1<?php 2/* 3 * $Id$ 4 * 5 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 6 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 7 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 8 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 9 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 10 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 11 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 12 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 13 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 14 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 15 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16 * 17 * This software consists of voluntary contributions made by many individuals 18 * and is licensed under the LGPL. For more information, see 19 * <http://www.doctrine-project.org>. 20 */ 21 22/** 23 * 24 * Doctrine_Manager is the base component of all doctrine based projects. 25 * It opens and keeps track of all connections (database connections). 26 * 27 * @package Doctrine 28 * @subpackage Manager 29 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL 30 * @link www.doctrine-project.org 31 * @since 1.0 32 * @version $Revision$ 33 * @author Konsta Vesterinen <kvesteri@cc.hut.fi> 34 */ 35class Doctrine_Manager extends Doctrine_Configurable implements Countable, IteratorAggregate 36{ 37 /** 38 * @var array $connections an array containing all the opened connections 39 */ 40 protected $_connections = array(); 41 42 /** 43 * @var array $bound an array containing all components that have a bound connection 44 */ 45 protected $_bound = array(); 46 47 /** 48 * @var integer $index the incremented index 49 */ 50 protected $_index = 0; 51 52 /** 53 * @var integer $currIndex the current connection index 54 */ 55 protected $_currIndex = 0; 56 57 /** 58 * @var Doctrine_Query_Registry the query registry 59 */ 60 protected $_queryRegistry; 61 62 /** 63 * @var array Array of registered validators 64 */ 65 protected $_validators = array(); 66 67 /** 68 * @var array Array of registered hydrators 69 */ 70 protected $_hydrators = array( 71 Doctrine_Core::HYDRATE_ARRAY => 'Doctrine_Hydrator_ArrayDriver', 72 Doctrine_Core::HYDRATE_RECORD => 'Doctrine_Hydrator_RecordDriver', 73 Doctrine_Core::HYDRATE_NONE => 'Doctrine_Hydrator_NoneDriver', 74 Doctrine_Core::HYDRATE_SCALAR => 'Doctrine_Hydrator_ScalarDriver', 75 Doctrine_Core::HYDRATE_SINGLE_SCALAR => 'Doctrine_Hydrator_SingleScalarDriver', 76 Doctrine_Core::HYDRATE_ON_DEMAND => 'Doctrine_Hydrator_RecordDriver', 77 Doctrine_Core::HYDRATE_ARRAY_HIERARCHY => 'Doctrine_Hydrator_ArrayHierarchyDriver', 78 Doctrine_Core::HYDRATE_RECORD_HIERARCHY => 'Doctrine_Hydrator_RecordHierarchyDriver', 79 Doctrine_Core::HYDRATE_ARRAY_SHALLOW => 'Doctrine_Hydrator_ArrayShallowDriver', 80 ); 81 82 protected $_connectionDrivers = array( 83 'db2' => 'Doctrine_Connection_Db2', 84 'mysql' => 'Doctrine_Connection_Mysql', 85 'mysqli' => 'Doctrine_Connection_Mysql', 86 'sqlite' => 'Doctrine_Connection_Sqlite', 87 'pgsql' => 'Doctrine_Connection_Pgsql', 88 'oci' => 'Doctrine_Connection_Oracle', 89 'oci8' => 'Doctrine_Connection_Oracle', 90 'oracle' => 'Doctrine_Connection_Oracle', 91 'mssql' => 'Doctrine_Connection_Mssql', 92 'dblib' => 'Doctrine_Connection_Mssql', 93 'odbc' => 'Doctrine_Connection_Mssql', 94 'mock' => 'Doctrine_Connection_Mock' 95 ); 96 97 protected $_extensions = array(); 98 99 /** 100 * @var boolean Whether or not the default validators have been loaded 101 */ 102 protected $_loadedDefaultValidators = false; 103 104 protected static $_instance; 105 106 private $_initialized = false; 107 108 /** 109 * constructor 110 * 111 * this is private constructor (use getInstance to get an instance of this class) 112 */ 113 private function __construct() 114 { 115 $null = new Doctrine_Null; 116 Doctrine_Locator_Injectable::initNullObject($null); 117 Doctrine_Record_Iterator::initNullObject($null); 118 } 119 120 /** 121 * Sets default attributes values. 122 * 123 * This method sets default values for all null attributes of this 124 * instance. It is idempotent and can only be called one time. Subsequent 125 * calls does not alter the attribute values. 126 * 127 * @return boolean true if inizialization was executed 128 */ 129 public function setDefaultAttributes() 130 { 131 if ( ! $this->_initialized) { 132 $this->_initialized = true; 133 $attributes = array( 134 Doctrine_Core::ATTR_CACHE => null, 135 Doctrine_Core::ATTR_RESULT_CACHE => null, 136 Doctrine_Core::ATTR_QUERY_CACHE => null, 137 Doctrine_Core::ATTR_TABLE_CACHE => null, 138 Doctrine_Core::ATTR_LOAD_REFERENCES => true, 139 Doctrine_Core::ATTR_LISTENER => new Doctrine_EventListener(), 140 Doctrine_Core::ATTR_RECORD_LISTENER => new Doctrine_Record_Listener(), 141 Doctrine_Core::ATTR_THROW_EXCEPTIONS => true, 142 Doctrine_Core::ATTR_VALIDATE => Doctrine_Core::VALIDATE_NONE, 143 Doctrine_Core::ATTR_QUERY_LIMIT => Doctrine_Core::LIMIT_RECORDS, 144 Doctrine_Core::ATTR_IDXNAME_FORMAT => "%s_idx", 145 Doctrine_Core::ATTR_SEQNAME_FORMAT => "%s_seq", 146 Doctrine_Core::ATTR_TBLNAME_FORMAT => "%s", 147 Doctrine_Core::ATTR_FKNAME_FORMAT => "%s", 148 Doctrine_Core::ATTR_QUOTE_IDENTIFIER => false, 149 Doctrine_Core::ATTR_SEQCOL_NAME => 'id', 150 Doctrine_Core::ATTR_PORTABILITY => Doctrine_Core::PORTABILITY_NONE, 151 Doctrine_Core::ATTR_EXPORT => Doctrine_Core::EXPORT_ALL, 152 Doctrine_Core::ATTR_DECIMAL_PLACES => 2, 153 Doctrine_Core::ATTR_DEFAULT_PARAM_NAMESPACE => 'doctrine', 154 Doctrine_Core::ATTR_AUTOLOAD_TABLE_CLASSES => false, 155 Doctrine_Core::ATTR_USE_DQL_CALLBACKS => false, 156 Doctrine_Core::ATTR_AUTO_ACCESSOR_OVERRIDE => false, 157 Doctrine_Core::ATTR_AUTO_FREE_QUERY_OBJECTS => false, 158 Doctrine_Core::ATTR_DEFAULT_IDENTIFIER_OPTIONS => array(), 159 Doctrine_Core::ATTR_DEFAULT_COLUMN_OPTIONS => array(), 160 Doctrine_Core::ATTR_HYDRATE_OVERWRITE => true, 161 Doctrine_Core::ATTR_QUERY_CLASS => 'Doctrine_Query', 162 Doctrine_Core::ATTR_COLLECTION_CLASS => 'Doctrine_Collection', 163 Doctrine_Core::ATTR_TABLE_CLASS => 'Doctrine_Table', 164 Doctrine_Core::ATTR_CASCADE_SAVES => true, 165 Doctrine_Core::ATTR_TABLE_CLASS_FORMAT => '%sTable', 166 Doctrine_Core::ATTR_USE_TABLE_REPOSITORY => true, 167 Doctrine_Core::ATTR_USE_TABLE_IDENTITY_MAP => true, 168 ); 169 foreach ($attributes as $attribute => $value) { 170 $old = $this->getAttribute($attribute); 171 if ($old === null) { 172 $this->setAttribute($attribute,$value); 173 } 174 } 175 return true; 176 } 177 return false; 178 } 179 180 /** 181 * Returns an instance of this class 182 * (this class uses the singleton pattern) 183 * 184 * @return Doctrine_Manager 185 */ 186 public static function getInstance() 187 { 188 if ( ! isset(self::$_instance)) { 189 self::$_instance = new self(); 190 } 191 return self::$_instance; 192 } 193 194 /** 195 * Reset the internal static instance 196 * 197 * @return void 198 */ 199 public static function resetInstance() 200 { 201 if (self::$_instance) { 202 self::$_instance->reset(); 203 self::$_instance = null; 204 } 205 } 206 207 /** 208 * Reset this instance of the manager 209 * 210 * @return void 211 */ 212 public function reset() 213 { 214 foreach ($this->_connections as $conn) { 215 $conn->close(); 216 } 217 $this->_connections = array(); 218 $this->_queryRegistry = null; 219 $this->_extensions = array(); 220 $this->_bound = array(); 221 $this->_validators = array(); 222 $this->_loadedDefaultValidators = false; 223 $this->_index = 0; 224 $this->_currIndex = 0; 225 $this->_initialized = false; 226 } 227 228 /** 229 * Lazy-initializes the query registry object and returns it 230 * 231 * @return Doctrine_Query_Registry 232 */ 233 public function getQueryRegistry() 234 { 235 if ( ! isset($this->_queryRegistry)) { 236 $this->_queryRegistry = new Doctrine_Query_Registry(); 237 } 238 return $this->_queryRegistry; 239 } 240 241 /** 242 * Sets the query registry 243 * 244 * @return Doctrine_Manager this object 245 */ 246 public function setQueryRegistry(Doctrine_Query_Registry $registry) 247 { 248 $this->_queryRegistry = $registry; 249 250 return $this; 251 } 252 253 /** 254 * Open a new connection. If the adapter parameter is set this method acts as 255 * a short cut for Doctrine_Manager::getInstance()->openConnection($adapter, $name); 256 * 257 * if the adapter paramater is not set this method acts as 258 * a short cut for Doctrine_Manager::getInstance()->getCurrentConnection() 259 * 260 * @param PDO|Doctrine_Adapter_Interface $adapter database driver 261 * @param string $name name of the connection, if empty numeric key is used 262 * @throws Doctrine_Manager_Exception if trying to bind a connection with an existing name 263 * @return Doctrine_Connection 264 */ 265 public static function connection($adapter = null, $name = null) 266 { 267 if ($adapter == null) { 268 return Doctrine_Manager::getInstance()->getCurrentConnection(); 269 } else { 270 return Doctrine_Manager::getInstance()->openConnection($adapter, $name); 271 } 272 } 273 274 /** 275 * Opens a new connection and saves it to Doctrine_Manager->connections 276 * 277 * @param PDO|Doctrine_Adapter_Interface $adapter database driver 278 * @param string $name name of the connection, if empty numeric key is used 279 * @throws Doctrine_Manager_Exception if trying to bind a connection with an existing name 280 * @throws Doctrine_Manager_Exception if trying to open connection for unknown driver 281 * @return Doctrine_Connection 282 */ 283 public function openConnection($adapter, $name = null, $setCurrent = true) 284 { 285 if (is_object($adapter)) { 286 if ( ! ($adapter instanceof PDO) && ! in_array('Doctrine_Adapter_Interface', class_implements($adapter))) { 287 throw new Doctrine_Manager_Exception("First argument should be an instance of PDO or implement Doctrine_Adapter_Interface"); 288 } 289 290 $driverName = $adapter->getAttribute(Doctrine_Core::ATTR_DRIVER_NAME); 291 } else if (is_array($adapter)) { 292 if ( ! isset($adapter[0])) { 293 throw new Doctrine_Manager_Exception('Empty data source name given.'); 294 } 295 $e = explode(':', $adapter[0]); 296 297 if ($e[0] == 'uri') { 298 $e[0] = 'odbc'; 299 } 300 301 $parts['dsn'] = $adapter[0]; 302 $parts['scheme'] = $e[0]; 303 $parts['user'] = (isset($adapter[1])) ? $adapter[1] : null; 304 $parts['pass'] = (isset($adapter[2])) ? $adapter[2] : null; 305 $driverName = $e[0]; 306 $adapter = $parts; 307 } else { 308 $parts = $this->parseDsn($adapter); 309 $driverName = $parts['scheme']; 310 $adapter = $parts; 311 } 312 313 // Decode adapter information 314 if (is_array($adapter)) { 315 foreach ($adapter as $key => $value) { 316 $adapter[$key] = $value ? urldecode($value):null; 317 } 318 } 319 320 // initialize the default attributes 321 $this->setDefaultAttributes(); 322 323 if ($name !== null) { 324 $name = (string) $name; 325 if (isset($this->_connections[$name])) { 326 if ($setCurrent) { 327 $this->_currIndex = $name; 328 } 329 return $this->_connections[$name]; 330 } 331 } else { 332 $name = $this->_index; 333 $this->_index++; 334 } 335 336 if ( ! isset($this->_connectionDrivers[$driverName])) { 337 throw new Doctrine_Manager_Exception('Unknown driver ' . $driverName); 338 } 339 340 $className = $this->_connectionDrivers[$driverName]; 341 $conn = new $className($this, $adapter); 342 $conn->setName($name); 343 344 $this->_connections[$name] = $conn; 345 346 if ($setCurrent) { 347 $this->_currIndex = $name; 348 } 349 return $this->_connections[$name]; 350 } 351 352 /** 353 * Parse a pdo style dsn in to an array of parts 354 * 355 * @param array $dsn An array of dsn information 356 * @return array The array parsed 357 * @todo package:dbal 358 */ 359 public function parsePdoDsn($dsn) 360 { 361 $parts = array(); 362 363 $names = array('dsn', 'scheme', 'host', 'port', 'user', 'pass', 'path', 'query', 'fragment', 'unix_socket'); 364 365 foreach ($names as $name) { 366 if ( ! isset($parts[$name])) { 367 $parts[$name] = null; 368 } 369 } 370 371 $e = explode(':', $dsn); 372 $parts['scheme'] = $e[0]; 373 $parts['dsn'] = $dsn; 374 375 $e = explode(';', $e[1]); 376 foreach ($e as $string) { 377 if ($string) { 378 $e2 = explode('=', $string); 379 380 if (isset($e2[0]) && isset($e2[1])) { 381 if (count($e2) > 2) 382 { 383 $key = $e2[0]; 384 unset($e2[0]); 385 $value = implode('=', $e2); 386 } else { 387 list($key, $value) = $e2; 388 } 389 $parts[$key] = $value; 390 } 391 } 392 } 393 394 return $parts; 395 } 396 397 /** 398 * Build the blank dsn parts array used with parseDsn() 399 * 400 * @see parseDsn() 401 * @param string $dsn 402 * @return array $parts 403 */ 404 protected function _buildDsnPartsArray($dsn) 405 { 406 // fix sqlite dsn so that it will parse correctly 407 $dsn = str_replace("////", "/", $dsn); 408 $dsn = str_replace("\\", "/", $dsn); 409 $dsn = preg_replace("/\/\/\/(.*):\//", "//$1:/", $dsn); 410 411 // silence any warnings 412 $parts = @parse_url($dsn); 413 414 $names = array('dsn', 'scheme', 'host', 'port', 'user', 'pass', 'path', 'query', 'fragment'); 415 416 foreach ($names as $name) { 417 if ( ! isset($parts[$name])) { 418 $parts[$name] = null; 419 } 420 } 421 422 if (count($parts) == 0 || ! isset($parts['scheme'])) { 423 throw new Doctrine_Manager_Exception('Could not parse dsn'); 424 } 425 426 return $parts; 427 } 428 429 /** 430 * Parse a Doctrine style dsn string in to an array of parts 431 * 432 * @param string $dsn 433 * @return array Parsed contents of DSN 434 * @todo package:dbal 435 */ 436 public function parseDsn($dsn) 437 { 438 $parts = $this->_buildDsnPartsArray($dsn); 439 440 switch ($parts['scheme']) { 441 case 'sqlite': 442 case 'sqlite2': 443 case 'sqlite3': 444 if (isset($parts['host']) && $parts['host'] == ':memory') { 445 $parts['database'] = ':memory:'; 446 $parts['dsn'] = 'sqlite::memory:'; 447 } else { 448 //fix windows dsn we have to add host: to path and set host to null 449 if (isset($parts['host'])) { 450 $parts['path'] = $parts['host'] . ":" . $parts["path"]; 451 $parts['host'] = null; 452 } 453 $parts['database'] = $parts['path']; 454 $parts['dsn'] = $parts['scheme'] . ':' . $parts['path']; 455 } 456 457 break; 458 459 case 'mssql': 460 case 'dblib': 461 if ( ! isset($parts['path']) || $parts['path'] == '/') { 462 throw new Doctrine_Manager_Exception('No database available in data source name'); 463 } 464 if (isset($parts['path'])) { 465 $parts['database'] = substr($parts['path'], 1); 466 } 467 if ( ! isset($parts['host'])) { 468 throw new Doctrine_Manager_Exception('No hostname set in data source name'); 469 } 470 471 $parts['dsn'] = $parts['scheme'] . ':host=' 472 . $parts['host'] . (isset($parts['port']) ? ':' . $parts['port']:null) . ';dbname=' 473 . $parts['database']; 474 475 break; 476 477 case 'mysql': 478 case 'oci8': 479 case 'oci': 480 case 'pgsql': 481 case 'odbc': 482 case 'mock': 483 case 'oracle': 484 if ( ! isset($parts['path']) || $parts['path'] == '/') { 485 throw new Doctrine_Manager_Exception('No database available in data source name'); 486 } 487 if (isset($parts['path'])) { 488 $parts['database'] = substr($parts['path'], 1); 489 } 490 if ( ! isset($parts['host'])) { 491 throw new Doctrine_Manager_Exception('No hostname set in data source name'); 492 } 493 494 $parts['dsn'] = $parts['scheme'] . ':host=' 495 . $parts['host'] . (isset($parts['port']) ? ';port=' . $parts['port']:null) . ';dbname=' 496 . $parts['database']; 497 498 break; 499 default: 500 $parts['dsn'] = $dsn; 501 } 502 503 return $parts; 504 } 505 506 /** 507 * Get the connection instance for the passed name 508 * 509 * @param string $name name of the connection, if empty numeric key is used 510 * @return Doctrine_Connection 511 * @throws Doctrine_Manager_Exception if trying to get a non-existent connection 512 */ 513 public function getConnection($name) 514 { 515 if ( ! isset($this->_connections[$name])) { 516 throw new Doctrine_Manager_Exception('Unknown connection: ' . $name); 517 } 518 519 return $this->_connections[$name]; 520 } 521 522 /** 523 * Get the name of the passed connection instance 524 * 525 * @param Doctrine_Connection $conn connection object to be searched for 526 * @return string the name of the connection 527 */ 528 public function getConnectionName(Doctrine_Connection $conn) 529 { 530 return array_search($conn, $this->_connections, true); 531 } 532 533 /** 534 * Binds given component to given connection 535 * this means that when ever the given component uses a connection 536 * it will be using the bound connection instead of the current connection 537 * 538 * @param string $componentName 539 * @param string $connectionName 540 * @return boolean 541 */ 542 public function bindComponent($componentName, $connectionName) 543 { 544 $this->_bound[$componentName] = $connectionName; 545 } 546 547 /** 548 * Get the connection instance for the specified component 549 * 550 * @param string $componentName 551 * @return Doctrine_Connection 552 */ 553 public function getConnectionForComponent($componentName) 554 { 555 Doctrine_Core::modelsAutoload($componentName); 556 557 if (isset($this->_bound[$componentName])) { 558 return $this->getConnection($this->_bound[$componentName]); 559 } 560 561 return $this->getCurrentConnection(); 562 } 563 564 /** 565 * Check if a component is bound to a connection 566 * 567 * @param string $componentName 568 * @return boolean 569 */ 570 public function hasConnectionForComponent($componentName = null) 571 { 572 return isset($this->_bound[$componentName]); 573 } 574 575 /** 576 * Closes the specified connection 577 * 578 * @param Doctrine_Connection $connection 579 * @return void 580 */ 581 public function closeConnection(Doctrine_Connection $connection) 582 { 583 $connection->close(); 584 585 $key = array_search($connection, $this->_connections, true); 586 587 if ($key !== false) { 588 unset($this->_connections[$key]); 589 590 if ($key === $this->_currIndex) { 591 $key = key($this->_connections); 592 $this->_currIndex = ($key !== null) ? $key : 0; 593 } 594 } 595 596 unset($connection); 597 } 598 599 /** 600 * Returns all opened connections 601 * 602 * @return array 603 */ 604 public function getConnections() 605 { 606 return $this->_connections; 607 } 608 609 /** 610 * Sets the current connection to $key 611 * 612 * @param mixed $key the connection key 613 * @throws Doctrine_Manager_Exception 614 * @return void 615 */ 616 public function setCurrentConnection($key) 617 { 618 $key = (string) $key; 619 if ( ! isset($this->_connections[$key])) { 620 throw new Doctrine_Manager_Exception("Connection key '$key' does not exist."); 621 } 622 $this->_currIndex = $key; 623 } 624 625 /** 626 * Whether or not the manager contains specified connection 627 * 628 * @param mixed $key the connection key 629 * @return boolean 630 */ 631 public function contains($key) 632 { 633 return isset($this->_connections[$key]); 634 } 635 636 /** 637 * Returns the number of opened connections 638 * 639 * @return integer 640 */ 641 public function count() 642 { 643 return count($this->_connections); 644 } 645 646 /** 647 * Returns an ArrayIterator that iterates through all connections 648 * 649 * @return ArrayIterator 650 */ 651 public function getIterator() 652 { 653 return new ArrayIterator($this->_connections); 654 } 655 656 /** 657 * Get the current connection instance 658 * 659 * @throws Doctrine_Connection_Exception if there are no open connections 660 * @return Doctrine_Connection 661 */ 662 public function getCurrentConnection() 663 { 664 $i = $this->_currIndex; 665 if ( ! isset($this->_connections[$i])) { 666 throw new Doctrine_Connection_Exception('There is no open connection'); 667 } 668 return $this->_connections[$i]; 669 } 670 671 /** 672 * Creates databases for all existing connections 673 * 674 * @param string $specifiedConnections Array of connections you wish to create the database for 675 * @return void 676 * @todo package:dbal 677 */ 678 public function createDatabases($specifiedConnections = array()) 679 { 680 if ( ! is_array($specifiedConnections)) { 681 $specifiedConnections = (array) $specifiedConnections; 682 } 683 684 foreach ($this as $name => $connection) { 685 if ( ! empty($specifiedConnections) && ! in_array($name, $specifiedConnections)) { 686 continue; 687 } 688 689 $connection->createDatabase(); 690 } 691 } 692 693 /** 694 * Drops databases for all existing connections 695 * 696 * @param string $specifiedConnections Array of connections you wish to drop the database for 697 * @return void 698 * @todo package:dbal 699 */ 700 public function dropDatabases($specifiedConnections = array()) 701 { 702 if ( ! is_array($specifiedConnections)) { 703 $specifiedConnections = (array) $specifiedConnections; 704 } 705 706 foreach ($this as $name => $connection) { 707 if ( ! empty($specifiedConnections) && ! in_array($name, $specifiedConnections)) { 708 continue; 709 } 710 711 $connection->dropDatabase(); 712 } 713 } 714 715 /** 716 * Returns a string representation of this object 717 * 718 * @return string 719 */ 720 public function __toString() 721 { 722 $r[] = "<pre>"; 723 $r[] = "Doctrine_Manager"; 724 $r[] = "Connections : ".count($this->_connections); 725 $r[] = "</pre>"; 726 return implode("\n",$r); 727 } 728 729 /** 730 * Get available doctrine validators 731 * 732 * @return array $validators 733 */ 734 public function getValidators() 735 { 736 if ( ! $this->_loadedDefaultValidators) { 737 $this->_loadedDefaultValidators = true; 738 739 $this->registerValidators(array( 740 'unique', 741 'past', 742 'range', 743 'ip', 744 'notblank', 745 'unsigned', 746 'errorstack', 747 'nospace', 748 'creditcard', 749 'regexp', 750 'exception', 751 'time', 752 'future', 753 'notnull', 754 'driver', 755 'readonly', 756 'htmlcolor', 757 'date', 758 'timestamp', 759 'minlength', 760 'usstate', 761 'email', 762 'country', 763 )); 764 } 765 766 return $this->_validators; 767 } 768 769 /** 770 * Register validators so that Doctrine is aware of them 771 * 772 * @param mixed $validators Name of validator or array of validators 773 * @return void 774 */ 775 public function registerValidators($validators) 776 { 777 $validators = (array) $validators; 778 foreach ($validators as $validator) { 779 if ( ! in_array($validator, $this->_validators)) { 780 $this->_validators[] = $validator; 781 } 782 } 783 } 784 785 /** 786 * Register a new driver for hydration 787 * 788 * @return void 789 */ 790 public function registerHydrator($name, $class) 791 { 792 $this->_hydrators[$name] = $class; 793 } 794 795 /** 796 * Get all registered hydrators 797 * 798 * @return array $hydrators 799 */ 800 public function getHydrators() 801 { 802 return $this->_hydrators; 803 } 804 805 /** 806 * Register a custom connection driver 807 * 808 * @return void 809 */ 810 public function registerConnectionDriver($name, $class) 811 { 812 $this->_connectionDrivers[$name] = $class; 813 } 814 815 /** 816 * Get all the available connection drivers 817 * 818 * @return array $connectionDrivers 819 */ 820 public function getConnectionDrivers() 821 { 822 return $this->_connectionDrivers; 823 } 824 825 /** 826 * Register a Doctrine extension for extensionsAutoload() method 827 * 828 * @param string $name 829 * @param string $path 830 * @return void 831 */ 832 public function registerExtension($name, $path = null) 833 { 834 if (is_null($path)) { 835 $path = Doctrine_Core::getExtensionsPath() . '/' . $name . '/lib'; 836 } 837 $this->_extensions[$name] = $path; 838 } 839 840 /** 841 * Get all registered Doctrine extensions 842 * 843 * @return $extensions 844 */ 845 public function getExtensions() 846 { 847 return $this->_extensions; 848 } 849} 850