Configuration.php 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. <?php
  2. /*
  3. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14. *
  15. * This software consists of voluntary contributions made by many individuals
  16. * and is licensed under the MIT license. For more information, see
  17. * <http://www.doctrine-project.org>.
  18. */
  19. namespace Doctrine\ORM;
  20. use Doctrine\Common\Cache\Cache,
  21. Doctrine\Common\Cache\ArrayCache,
  22. Doctrine\Common\Annotations\AnnotationRegistry,
  23. Doctrine\Common\Annotations\AnnotationReader,
  24. Doctrine\Common\Persistence\Mapping\Driver\MappingDriver,
  25. Doctrine\ORM\Mapping\Driver\AnnotationDriver,
  26. Doctrine\ORM\Mapping\QuoteStrategy,
  27. Doctrine\ORM\Mapping\DefaultQuoteStrategy,
  28. Doctrine\ORM\Mapping\NamingStrategy,
  29. Doctrine\ORM\Mapping\DefaultNamingStrategy,
  30. Doctrine\Common\Annotations\SimpleAnnotationReader,
  31. Doctrine\Common\Annotations\CachedReader;
  32. /**
  33. * Configuration container for all configuration options of Doctrine.
  34. * It combines all configuration options from DBAL & ORM.
  35. *
  36. * @since 2.0
  37. * @internal When adding a new configuration option just write a getter/setter pair.
  38. * @author Benjamin Eberlei <kontakt@beberlei.de>
  39. * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
  40. * @author Jonathan Wage <jonwage@gmail.com>
  41. * @author Roman Borschel <roman@code-factory.org>
  42. */
  43. class Configuration extends \Doctrine\DBAL\Configuration
  44. {
  45. /**
  46. * Sets the directory where Doctrine generates any necessary proxy class files.
  47. *
  48. * @param string $dir
  49. */
  50. public function setProxyDir($dir)
  51. {
  52. $this->_attributes['proxyDir'] = $dir;
  53. }
  54. /**
  55. * Gets the directory where Doctrine generates any necessary proxy class files.
  56. *
  57. * @return string
  58. */
  59. public function getProxyDir()
  60. {
  61. return isset($this->_attributes['proxyDir'])
  62. ? $this->_attributes['proxyDir']
  63. : null;
  64. }
  65. /**
  66. * Gets a boolean flag that indicates whether proxy classes should always be regenerated
  67. * during each script execution.
  68. *
  69. * @return boolean
  70. */
  71. public function getAutoGenerateProxyClasses()
  72. {
  73. return isset($this->_attributes['autoGenerateProxyClasses'])
  74. ? $this->_attributes['autoGenerateProxyClasses']
  75. : true;
  76. }
  77. /**
  78. * Sets a boolean flag that indicates whether proxy classes should always be regenerated
  79. * during each script execution.
  80. *
  81. * @param boolean $bool
  82. */
  83. public function setAutoGenerateProxyClasses($bool)
  84. {
  85. $this->_attributes['autoGenerateProxyClasses'] = $bool;
  86. }
  87. /**
  88. * Gets the namespace where proxy classes reside.
  89. *
  90. * @return string
  91. */
  92. public function getProxyNamespace()
  93. {
  94. return isset($this->_attributes['proxyNamespace'])
  95. ? $this->_attributes['proxyNamespace']
  96. : null;
  97. }
  98. /**
  99. * Sets the namespace where proxy classes reside.
  100. *
  101. * @param string $ns
  102. */
  103. public function setProxyNamespace($ns)
  104. {
  105. $this->_attributes['proxyNamespace'] = $ns;
  106. }
  107. /**
  108. * Sets the cache driver implementation that is used for metadata caching.
  109. *
  110. * @param MappingDriver $driverImpl
  111. * @todo Force parameter to be a Closure to ensure lazy evaluation
  112. * (as soon as a metadata cache is in effect, the driver never needs to initialize).
  113. */
  114. public function setMetadataDriverImpl(MappingDriver $driverImpl)
  115. {
  116. $this->_attributes['metadataDriverImpl'] = $driverImpl;
  117. }
  118. /**
  119. * Add a new default annotation driver with a correctly configured annotation reader. If $useSimpleAnnotationReader
  120. * is true, the notation `@Entity` will work, otherwise, the notation `@ORM\Entity` will be supported.
  121. *
  122. * @param array $paths
  123. * @param bool $useSimpleAnnotationReader
  124. * @return AnnotationDriver
  125. */
  126. public function newDefaultAnnotationDriver($paths = array(), $useSimpleAnnotationReader = true)
  127. {
  128. AnnotationRegistry::registerFile(__DIR__ . '/Mapping/Driver/DoctrineAnnotations.php');
  129. if ($useSimpleAnnotationReader) {
  130. // Register the ORM Annotations in the AnnotationRegistry
  131. $reader = new SimpleAnnotationReader();
  132. $reader->addNamespace('Doctrine\ORM\Mapping');
  133. $cachedReader = new CachedReader($reader, new ArrayCache());
  134. return new AnnotationDriver($cachedReader, (array) $paths);
  135. }
  136. return new AnnotationDriver(
  137. new CachedReader(new AnnotationReader(), new ArrayCache()),
  138. (array) $paths
  139. );
  140. }
  141. /**
  142. * Adds a namespace under a certain alias.
  143. *
  144. * @param string $alias
  145. * @param string $namespace
  146. */
  147. public function addEntityNamespace($alias, $namespace)
  148. {
  149. $this->_attributes['entityNamespaces'][$alias] = $namespace;
  150. }
  151. /**
  152. * Resolves a registered namespace alias to the full namespace.
  153. *
  154. * @param string $entityNamespaceAlias
  155. * @throws ORMException
  156. * @return string
  157. */
  158. public function getEntityNamespace($entityNamespaceAlias)
  159. {
  160. if ( ! isset($this->_attributes['entityNamespaces'][$entityNamespaceAlias])) {
  161. throw ORMException::unknownEntityNamespace($entityNamespaceAlias);
  162. }
  163. return trim($this->_attributes['entityNamespaces'][$entityNamespaceAlias], '\\');
  164. }
  165. /**
  166. * Set the entity alias map
  167. *
  168. * @param array $entityNamespaces
  169. */
  170. public function setEntityNamespaces(array $entityNamespaces)
  171. {
  172. $this->_attributes['entityNamespaces'] = $entityNamespaces;
  173. }
  174. /**
  175. * Retrieves the list of registered entity namespace aliases.
  176. *
  177. * @return array
  178. */
  179. public function getEntityNamespaces()
  180. {
  181. return $this->_attributes['entityNamespaces'];
  182. }
  183. /**
  184. * Gets the cache driver implementation that is used for the mapping metadata.
  185. *
  186. * @throws ORMException
  187. * @return MappingDriver
  188. */
  189. public function getMetadataDriverImpl()
  190. {
  191. return isset($this->_attributes['metadataDriverImpl'])
  192. ? $this->_attributes['metadataDriverImpl']
  193. : null;
  194. }
  195. /**
  196. * Gets the cache driver implementation that is used for the query cache (SQL cache).
  197. *
  198. * @return \Doctrine\Common\Cache\Cache
  199. */
  200. public function getQueryCacheImpl()
  201. {
  202. return isset($this->_attributes['queryCacheImpl'])
  203. ? $this->_attributes['queryCacheImpl']
  204. : null;
  205. }
  206. /**
  207. * Sets the cache driver implementation that is used for the query cache (SQL cache).
  208. *
  209. * @param \Doctrine\Common\Cache\Cache $cacheImpl
  210. */
  211. public function setQueryCacheImpl(Cache $cacheImpl)
  212. {
  213. $this->_attributes['queryCacheImpl'] = $cacheImpl;
  214. }
  215. /**
  216. * Gets the cache driver implementation that is used for the hydration cache (SQL cache).
  217. *
  218. * @return \Doctrine\Common\Cache\Cache
  219. */
  220. public function getHydrationCacheImpl()
  221. {
  222. return isset($this->_attributes['hydrationCacheImpl'])
  223. ? $this->_attributes['hydrationCacheImpl']
  224. : null;
  225. }
  226. /**
  227. * Sets the cache driver implementation that is used for the hydration cache (SQL cache).
  228. *
  229. * @param \Doctrine\Common\Cache\Cache $cacheImpl
  230. */
  231. public function setHydrationCacheImpl(Cache $cacheImpl)
  232. {
  233. $this->_attributes['hydrationCacheImpl'] = $cacheImpl;
  234. }
  235. /**
  236. * Gets the cache driver implementation that is used for metadata caching.
  237. *
  238. * @return \Doctrine\Common\Cache\Cache
  239. */
  240. public function getMetadataCacheImpl()
  241. {
  242. return isset($this->_attributes['metadataCacheImpl'])
  243. ? $this->_attributes['metadataCacheImpl']
  244. : null;
  245. }
  246. /**
  247. * Sets the cache driver implementation that is used for metadata caching.
  248. *
  249. * @param \Doctrine\Common\Cache\Cache $cacheImpl
  250. */
  251. public function setMetadataCacheImpl(Cache $cacheImpl)
  252. {
  253. $this->_attributes['metadataCacheImpl'] = $cacheImpl;
  254. }
  255. /**
  256. * Adds a named DQL query to the configuration.
  257. *
  258. * @param string $name The name of the query.
  259. * @param string $dql The DQL query string.
  260. */
  261. public function addNamedQuery($name, $dql)
  262. {
  263. $this->_attributes['namedQueries'][$name] = $dql;
  264. }
  265. /**
  266. * Gets a previously registered named DQL query.
  267. *
  268. * @param string $name The name of the query.
  269. * @throws ORMException
  270. * @return string The DQL query.
  271. */
  272. public function getNamedQuery($name)
  273. {
  274. if ( ! isset($this->_attributes['namedQueries'][$name])) {
  275. throw ORMException::namedQueryNotFound($name);
  276. }
  277. return $this->_attributes['namedQueries'][$name];
  278. }
  279. /**
  280. * Adds a named native query to the configuration.
  281. *
  282. * @param string $name The name of the query.
  283. * @param string $sql The native SQL query string.
  284. * @param Query\ResultSetMapping $rsm The ResultSetMapping used for the results of the SQL query.
  285. */
  286. public function addNamedNativeQuery($name, $sql, Query\ResultSetMapping $rsm)
  287. {
  288. $this->_attributes['namedNativeQueries'][$name] = array($sql, $rsm);
  289. }
  290. /**
  291. * Gets the components of a previously registered named native query.
  292. *
  293. * @param string $name The name of the query.
  294. * @throws ORMException
  295. * @return array A tuple with the first element being the SQL string and the second
  296. * element being the ResultSetMapping.
  297. */
  298. public function getNamedNativeQuery($name)
  299. {
  300. if ( ! isset($this->_attributes['namedNativeQueries'][$name])) {
  301. throw ORMException::namedNativeQueryNotFound($name);
  302. }
  303. return $this->_attributes['namedNativeQueries'][$name];
  304. }
  305. /**
  306. * Ensures that this Configuration instance contains settings that are
  307. * suitable for a production environment.
  308. *
  309. * @throws ORMException If a configuration setting has a value that is not
  310. * suitable for a production environment.
  311. */
  312. public function ensureProductionSettings()
  313. {
  314. if ( ! $this->getQueryCacheImpl()) {
  315. throw ORMException::queryCacheNotConfigured();
  316. }
  317. if ( ! $this->getMetadataCacheImpl()) {
  318. throw ORMException::metadataCacheNotConfigured();
  319. }
  320. if ($this->getAutoGenerateProxyClasses()) {
  321. throw ORMException::proxyClassesAlwaysRegenerating();
  322. }
  323. }
  324. /**
  325. * Registers a custom DQL function that produces a string value.
  326. * Such a function can then be used in any DQL statement in any place where string
  327. * functions are allowed.
  328. *
  329. * DQL function names are case-insensitive.
  330. *
  331. * @param string $name
  332. * @param string $className
  333. * @throws ORMException
  334. */
  335. public function addCustomStringFunction($name, $className)
  336. {
  337. if (Query\Parser::isInternalFunction($name)) {
  338. throw ORMException::overwriteInternalDQLFunctionNotAllowed($name);
  339. }
  340. $this->_attributes['customStringFunctions'][strtolower($name)] = $className;
  341. }
  342. /**
  343. * Gets the implementation class name of a registered custom string DQL function.
  344. *
  345. * @param string $name
  346. * @return string
  347. */
  348. public function getCustomStringFunction($name)
  349. {
  350. $name = strtolower($name);
  351. return isset($this->_attributes['customStringFunctions'][$name])
  352. ? $this->_attributes['customStringFunctions'][$name]
  353. : null;
  354. }
  355. /**
  356. * Sets a map of custom DQL string functions.
  357. *
  358. * Keys must be function names and values the FQCN of the implementing class.
  359. * The function names will be case-insensitive in DQL.
  360. *
  361. * Any previously added string functions are discarded.
  362. *
  363. * @param array $functions The map of custom DQL string functions.
  364. */
  365. public function setCustomStringFunctions(array $functions)
  366. {
  367. foreach ($functions as $name => $className) {
  368. $this->addCustomStringFunction($name, $className);
  369. }
  370. }
  371. /**
  372. * Registers a custom DQL function that produces a numeric value.
  373. * Such a function can then be used in any DQL statement in any place where numeric
  374. * functions are allowed.
  375. *
  376. * DQL function names are case-insensitive.
  377. *
  378. * @param string $name
  379. * @param string $className
  380. * @throws ORMException
  381. */
  382. public function addCustomNumericFunction($name, $className)
  383. {
  384. if (Query\Parser::isInternalFunction($name)) {
  385. throw ORMException::overwriteInternalDQLFunctionNotAllowed($name);
  386. }
  387. $this->_attributes['customNumericFunctions'][strtolower($name)] = $className;
  388. }
  389. /**
  390. * Gets the implementation class name of a registered custom numeric DQL function.
  391. *
  392. * @param string $name
  393. * @return string
  394. */
  395. public function getCustomNumericFunction($name)
  396. {
  397. $name = strtolower($name);
  398. return isset($this->_attributes['customNumericFunctions'][$name])
  399. ? $this->_attributes['customNumericFunctions'][$name]
  400. : null;
  401. }
  402. /**
  403. * Sets a map of custom DQL numeric functions.
  404. *
  405. * Keys must be function names and values the FQCN of the implementing class.
  406. * The function names will be case-insensitive in DQL.
  407. *
  408. * Any previously added numeric functions are discarded.
  409. *
  410. * @param array $functions The map of custom DQL numeric functions.
  411. */
  412. public function setCustomNumericFunctions(array $functions)
  413. {
  414. foreach ($functions as $name => $className) {
  415. $this->addCustomNumericFunction($name, $className);
  416. }
  417. }
  418. /**
  419. * Registers a custom DQL function that produces a date/time value.
  420. * Such a function can then be used in any DQL statement in any place where date/time
  421. * functions are allowed.
  422. *
  423. * DQL function names are case-insensitive.
  424. *
  425. * @param string $name
  426. * @param string $className
  427. * @throws ORMException
  428. */
  429. public function addCustomDatetimeFunction($name, $className)
  430. {
  431. if (Query\Parser::isInternalFunction($name)) {
  432. throw ORMException::overwriteInternalDQLFunctionNotAllowed($name);
  433. }
  434. $this->_attributes['customDatetimeFunctions'][strtolower($name)] = $className;
  435. }
  436. /**
  437. * Gets the implementation class name of a registered custom date/time DQL function.
  438. *
  439. * @param string $name
  440. * @return string
  441. */
  442. public function getCustomDatetimeFunction($name)
  443. {
  444. $name = strtolower($name);
  445. return isset($this->_attributes['customDatetimeFunctions'][$name])
  446. ? $this->_attributes['customDatetimeFunctions'][$name]
  447. : null;
  448. }
  449. /**
  450. * Sets a map of custom DQL date/time functions.
  451. *
  452. * Keys must be function names and values the FQCN of the implementing class.
  453. * The function names will be case-insensitive in DQL.
  454. *
  455. * Any previously added date/time functions are discarded.
  456. *
  457. * @param array $functions The map of custom DQL date/time functions.
  458. */
  459. public function setCustomDatetimeFunctions(array $functions)
  460. {
  461. foreach ($functions as $name => $className) {
  462. $this->addCustomDatetimeFunction($name, $className);
  463. }
  464. }
  465. /**
  466. * Set the custom hydrator modes in one pass.
  467. *
  468. * @param array An array of ($modeName => $hydrator)
  469. */
  470. public function setCustomHydrationModes($modes)
  471. {
  472. $this->_attributes['customHydrationModes'] = array();
  473. foreach ($modes as $modeName => $hydrator) {
  474. $this->addCustomHydrationMode($modeName, $hydrator);
  475. }
  476. }
  477. /**
  478. * Get the hydrator class for the given hydration mode name.
  479. *
  480. * @param string $modeName The hydration mode name.
  481. * @return string $hydrator The hydrator class name.
  482. */
  483. public function getCustomHydrationMode($modeName)
  484. {
  485. return isset($this->_attributes['customHydrationModes'][$modeName])
  486. ? $this->_attributes['customHydrationModes'][$modeName]
  487. : null;
  488. }
  489. /**
  490. * Add a custom hydration mode.
  491. *
  492. * @param string $modeName The hydration mode name.
  493. * @param string $hydrator The hydrator class name.
  494. */
  495. public function addCustomHydrationMode($modeName, $hydrator)
  496. {
  497. $this->_attributes['customHydrationModes'][$modeName] = $hydrator;
  498. }
  499. /**
  500. * Set a class metadata factory.
  501. *
  502. * @param string $cmfName
  503. */
  504. public function setClassMetadataFactoryName($cmfName)
  505. {
  506. $this->_attributes['classMetadataFactoryName'] = $cmfName;
  507. }
  508. /**
  509. * @return string
  510. */
  511. public function getClassMetadataFactoryName()
  512. {
  513. if ( ! isset($this->_attributes['classMetadataFactoryName'])) {
  514. $this->_attributes['classMetadataFactoryName'] = 'Doctrine\ORM\Mapping\ClassMetadataFactory';
  515. }
  516. return $this->_attributes['classMetadataFactoryName'];
  517. }
  518. /**
  519. * Add a filter to the list of possible filters.
  520. *
  521. * @param string $name The name of the filter.
  522. * @param string $className The class name of the filter.
  523. */
  524. public function addFilter($name, $className)
  525. {
  526. $this->_attributes['filters'][$name] = $className;
  527. }
  528. /**
  529. * Gets the class name for a given filter name.
  530. *
  531. * @param string $name The name of the filter.
  532. *
  533. * @return string The class name of the filter, or null of it is not
  534. * defined.
  535. */
  536. public function getFilterClassName($name)
  537. {
  538. return isset($this->_attributes['filters'][$name])
  539. ? $this->_attributes['filters'][$name]
  540. : null;
  541. }
  542. /**
  543. * Set default repository class.
  544. *
  545. * @since 2.2
  546. * @param string $className
  547. * @throws ORMException If not is a \Doctrine\Common\Persistence\ObjectRepository
  548. */
  549. public function setDefaultRepositoryClassName($className)
  550. {
  551. $reflectionClass = new \ReflectionClass($className);
  552. if ( ! $reflectionClass->implementsInterface('Doctrine\Common\Persistence\ObjectRepository')) {
  553. throw ORMException::invalidEntityRepository($className);
  554. }
  555. $this->_attributes['defaultRepositoryClassName'] = $className;
  556. }
  557. /**
  558. * Get default repository class.
  559. *
  560. * @since 2.2
  561. * @return string
  562. */
  563. public function getDefaultRepositoryClassName()
  564. {
  565. return isset($this->_attributes['defaultRepositoryClassName'])
  566. ? $this->_attributes['defaultRepositoryClassName']
  567. : 'Doctrine\ORM\EntityRepository';
  568. }
  569. /**
  570. * Set naming strategy.
  571. *
  572. * @since 2.3
  573. * @param NamingStrategy $namingStrategy
  574. */
  575. public function setNamingStrategy(NamingStrategy $namingStrategy)
  576. {
  577. $this->_attributes['namingStrategy'] = $namingStrategy;
  578. }
  579. /**
  580. * Get naming strategy..
  581. *
  582. * @since 2.3
  583. * @return NamingStrategy
  584. */
  585. public function getNamingStrategy()
  586. {
  587. if ( ! isset($this->_attributes['namingStrategy'])) {
  588. $this->_attributes['namingStrategy'] = new DefaultNamingStrategy();
  589. }
  590. return $this->_attributes['namingStrategy'];
  591. }
  592. /**
  593. * Set quote strategy.
  594. *
  595. * @since 2.3
  596. * @param Doctrine\ORM\Mapping\QuoteStrategy $quoteStrategy
  597. */
  598. public function setQuoteStrategy(QuoteStrategy $quoteStrategy)
  599. {
  600. $this->_attributes['quoteStrategy'] = $quoteStrategy;
  601. }
  602. /**
  603. * Get quote strategy.
  604. *
  605. * @since 2.3
  606. * @return Doctrine\ORM\Mapping\QuoteStrategy
  607. */
  608. public function getQuoteStrategy()
  609. {
  610. if ( ! isset($this->_attributes['quoteStrategy'])) {
  611. $this->_attributes['quoteStrategy'] = new DefaultQuoteStrategy();
  612. }
  613. return $this->_attributes['quoteStrategy'];
  614. }
  615. }