PageRenderTime 51ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/htdocs/symfony/2.0.0pr3/src/vendor/doctrine-mongodb/lib/Doctrine/ODM/MongoDB/Mapping/Driver/AnnotationDriver.php

https://github.com/ad2joe/php-framework-benchmarks
PHP | 370 lines | 245 code | 42 blank | 83 comment | 49 complexity | a684cde75daaf532a1f2219a6fc6d08e MD5 | raw file
  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 LGPL. For more information, see
  17. * <http://www.doctrine-project.org>.
  18. */
  19. namespace Doctrine\ODM\MongoDB\Mapping\Driver;
  20. use Doctrine\ODM\MongoDB\Mapping\ClassMetadata,
  21. Doctrine\Common\Annotations\AnnotationReader,
  22. Doctrine\ODM\MongoDB\MongoDBException;
  23. require __DIR__ . '/DoctrineAnnotations.php';
  24. /**
  25. * The AnnotationDriver reads the mapping metadata from docblock annotations.
  26. *
  27. * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
  28. * @link www.doctrine-project.org
  29. * @since 1.0
  30. * @author Jonathan H. Wage <jonwage@gmail.com>
  31. * @author Roman Borschel <roman@code-factory.org>
  32. */
  33. class AnnotationDriver implements Driver
  34. {
  35. /**
  36. * The AnnotationReader.
  37. *
  38. * @var AnnotationReader
  39. */
  40. private $reader;
  41. /**
  42. * The paths where to look for mapping files.
  43. *
  44. * @var array
  45. */
  46. private $paths = array();
  47. /**
  48. * The file extension of mapping documents.
  49. *
  50. * @var string
  51. */
  52. private $fileExtension = '.php';
  53. /**
  54. * @param array
  55. */
  56. private $classNames;
  57. /**
  58. * Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
  59. * docblock annotations.
  60. *
  61. * @param $reader The AnnotationReader to use.
  62. * @param string|array $paths One or multiple paths where mapping classes can be found.
  63. */
  64. public function __construct(AnnotationReader $reader, $paths = null)
  65. {
  66. $this->reader = $reader;
  67. if ($paths) {
  68. $this->addPaths((array) $paths);
  69. }
  70. }
  71. /**
  72. * Append lookup paths to metadata driver.
  73. *
  74. * @param array $paths
  75. */
  76. public function addPaths(array $paths)
  77. {
  78. $this->paths = array_unique(array_merge($this->paths, $paths));
  79. }
  80. /**
  81. * Retrieve the defined metadata lookup paths.
  82. *
  83. * @return array
  84. */
  85. public function getPaths()
  86. {
  87. return $this->paths;
  88. }
  89. /**
  90. * {@inheritdoc}
  91. */
  92. public function loadMetadataForClass($className, ClassMetadata $class)
  93. {
  94. $reflClass = $class->getReflectionClass();
  95. $classAnnotations = $this->reader->getClassAnnotations($reflClass);
  96. if (isset($classAnnotations['Doctrine\ODM\MongoDB\Mapping\Document'])) {
  97. $documentAnnot = $classAnnotations['Doctrine\ODM\MongoDB\Mapping\Document'];
  98. } elseif (isset($classAnnotations['Doctrine\ODM\MongoDB\Mapping\MappedSuperclass'])) {
  99. $documentAnnot = $classAnnotations['Doctrine\ODM\MongoDB\Mapping\MappedSuperclass'];
  100. $class->isMappedSuperclass = true;
  101. } elseif (isset($classAnnotations['Doctrine\ODM\MongoDB\Mapping\EmbeddedDocument'])) {
  102. $documentAnnot = $classAnnotations['Doctrine\ODM\MongoDB\Mapping\EmbeddedDocument'];
  103. $class->isEmbeddedDocument = true;
  104. } else {
  105. throw MongoDBException::classIsNotAValidDocument($className);
  106. }
  107. if (isset($documentAnnot->db)) {
  108. $class->setDB($documentAnnot->db);
  109. }
  110. if (isset($documentAnnot->collection)) {
  111. $class->setCollection($documentAnnot->collection);
  112. }
  113. if (isset($documentAnnot->repositoryClass)) {
  114. $class->setCustomRepositoryClass($documentAnnot->repositoryClass);
  115. }
  116. if (isset($classAnnotations['Doctrine\ODM\MongoDB\Mapping\Indexes'])) {
  117. $indexes = $classAnnotations['Doctrine\ODM\MongoDB\Mapping\Indexes']->value;
  118. $indexes = is_array($indexes) ? $indexes : array($indexes);
  119. foreach ($indexes as $index) {
  120. $this->addIndex($class, $index);
  121. }
  122. }
  123. if (isset($classAnnotations['Doctrine\ODM\MongoDB\Mapping\Index'])) {
  124. $index = $classAnnotations['Doctrine\ODM\MongoDB\Mapping\Index'];
  125. $this->addIndex($class, $index);
  126. }
  127. if (isset($classAnnotations['Doctrine\ODM\MongoDB\Mapping\UniqueIndex'])) {
  128. $index = $classAnnotations['Doctrine\ODM\MongoDB\Mapping\UniqueIndex'];
  129. $this->addIndex($class, $index);
  130. }
  131. if (isset($documentAnnot->indexes)) {
  132. foreach($documentAnnot->indexes as $index) {
  133. $this->addIndex($class, $index);
  134. }
  135. }
  136. if (isset($classAnnotations['Doctrine\ODM\MongoDB\Mapping\InheritanceType'])) {
  137. $inheritanceTypeAnnot = $classAnnotations['Doctrine\ODM\MongoDB\Mapping\InheritanceType'];
  138. $class->setInheritanceType(constant('Doctrine\ODM\MongoDB\Mapping\ClassMetadata::INHERITANCE_TYPE_' . $inheritanceTypeAnnot->value));
  139. }
  140. if (isset($classAnnotations['Doctrine\ODM\MongoDB\Mapping\DiscriminatorField'])) {
  141. $discrFieldAnnot = $classAnnotations['Doctrine\ODM\MongoDB\Mapping\DiscriminatorField'];
  142. $class->setDiscriminatorField(array(
  143. 'fieldName' => $discrFieldAnnot->fieldName,
  144. ));
  145. }
  146. if (isset($classAnnotations['Doctrine\ODM\MongoDB\Mapping\DiscriminatorMap'])) {
  147. $discrMapAnnot = $classAnnotations['Doctrine\ODM\MongoDB\Mapping\DiscriminatorMap'];
  148. $class->setDiscriminatorMap($discrMapAnnot->value);
  149. }
  150. if (isset($classAnnotations['Doctrine\ODM\MongoDB\Mapping\DiscriminatorValue'])) {
  151. $discrValueAnnot = $classAnnotations['Doctrine\ODM\MongoDB\Mapping\DiscriminatorValue'];
  152. $class->setDiscriminatorValue($discrValueAnnot->value);
  153. }
  154. if (isset($classAnnotations['Doctrine\ODM\MongoDB\Mapping\ChangeTrackingPolicy'])) {
  155. $changeTrackingAnnot = $classAnnotations['Doctrine\ODM\MongoDB\Mapping\ChangeTrackingPolicy'];
  156. $class->setChangeTrackingPolicy(constant('Doctrine\ODM\MongoDB\Mapping\ClassMetadata::CHANGETRACKING_' . $changeTrackingAnnot->value));
  157. }
  158. $methods = $reflClass->getMethods();
  159. foreach ($reflClass->getProperties() as $property) {
  160. if ($class->isMappedSuperclass && ! $property->isPrivate()
  161. || $class->isInheritedField($property->name)) {
  162. continue;
  163. }
  164. $mapping = array();
  165. $mapping['fieldName'] = $property->getName();
  166. if ($alsoLoad = $this->reader->getPropertyAnnotation($property, 'Doctrine\ODM\MongoDB\Mapping\AlsoLoad')) {
  167. $mapping['alsoLoadFields'] = (array) $alsoLoad->value;
  168. }
  169. if ($notSaved = $this->reader->getPropertyAnnotation($property, 'Doctrine\ODM\MongoDB\Mapping\NotSaved')) {
  170. $mapping['notSaved'] = true;
  171. }
  172. $indexes = $this->reader->getPropertyAnnotation($property, 'Doctrine\ODM\MongoDB\Mapping\Indexes');
  173. $indexes = $indexes ? $indexes : array();
  174. if ($index = $this->reader->getPropertyAnnotation($property, 'Doctrine\ODM\MongoDB\Mapping\Index')) {
  175. $indexes[] = $index;
  176. }
  177. if ($index = $this->reader->getPropertyAnnotation($property, 'Doctrine\ODM\MongoDB\Mapping\UniqueIndex')) {
  178. $indexes[] = $index;
  179. }
  180. if ($indexes) {
  181. foreach ($indexes as $index) {
  182. $keys = array();
  183. $keys[$mapping['fieldName']] = 'asc';
  184. if (isset($index->order)) {
  185. $keys[$mapping['fieldName']] = $index->order;
  186. }
  187. $this->addIndex($class, $index, $keys);
  188. }
  189. }
  190. foreach ($this->reader->getPropertyAnnotations($property) as $fieldAnnot) {
  191. if ($fieldAnnot instanceof \Doctrine\ODM\MongoDB\Mapping\Field) {
  192. if ($fieldAnnot instanceof \Doctrine\ODM\MongoDB\Mapping\Id && $fieldAnnot->custom) {
  193. $fieldAnnot->type = 'custom_id';
  194. $class->setAllowCustomId(true);
  195. }
  196. $mapping = array_merge($mapping, (array) $fieldAnnot);
  197. $class->mapField($mapping);
  198. }
  199. }
  200. }
  201. foreach ($methods as $method) {
  202. if ($method->isPublic()) {
  203. if ($alsoLoad = $this->reader->getMethodAnnotation($method, 'Doctrine\ODM\MongoDB\Mapping\AlsoLoad')) {
  204. $fields = (array) $alsoLoad->value;
  205. foreach ($fields as $value) {
  206. $class->alsoLoadMethods[$value] = $method->getName();
  207. }
  208. }
  209. }
  210. }
  211. if (isset($classAnnotations['Doctrine\ODM\MongoDB\Mapping\HasLifecycleCallbacks'])) {
  212. foreach ($methods as $method) {
  213. if ($method->isPublic()) {
  214. $annotations = $this->reader->getMethodAnnotations($method);
  215. if (isset($annotations['Doctrine\ODM\MongoDB\Mapping\PrePersist'])) {
  216. $class->addLifecycleCallback($method->getName(), \Doctrine\ODM\MongoDB\ODMEvents::prePersist);
  217. }
  218. if (isset($annotations['Doctrine\ODM\MongoDB\Mapping\PostPersist'])) {
  219. $class->addLifecycleCallback($method->getName(), \Doctrine\ODM\MongoDB\ODMEvents::postPersist);
  220. }
  221. if (isset($annotations['Doctrine\ODM\MongoDB\Mapping\PreUpdate'])) {
  222. $class->addLifecycleCallback($method->getName(), \Doctrine\ODM\MongoDB\ODMEvents::preUpdate);
  223. }
  224. if (isset($annotations['Doctrine\ODM\MongoDB\Mapping\PostUpdate'])) {
  225. $class->addLifecycleCallback($method->getName(), \Doctrine\ODM\MongoDB\ODMEvents::postUpdate);
  226. }
  227. if (isset($annotations['Doctrine\ODM\MongoDB\Mapping\PreRemove'])) {
  228. $class->addLifecycleCallback($method->getName(), \Doctrine\ODM\MongoDB\ODMEvents::preRemove);
  229. }
  230. if (isset($annotations['Doctrine\ODM\MongoDB\Mapping\PostRemove'])) {
  231. $class->addLifecycleCallback($method->getName(), \Doctrine\ODM\MongoDB\ODMEvents::postRemove);
  232. }
  233. if (isset($annotations['Doctrine\ODM\MongoDB\Mapping\PreLoad'])) {
  234. $class->addLifecycleCallback($method->getName(), \Doctrine\ODM\MongoDB\ODMEvents::preLoad);
  235. }
  236. if (isset($annotations['Doctrine\ODM\MongoDB\Mapping\PostLoad'])) {
  237. $class->addLifecycleCallback($method->getName(), \Doctrine\ODM\MongoDB\ODMEvents::postLoad);
  238. }
  239. }
  240. }
  241. }
  242. }
  243. private function addIndex(ClassMetadata $class, $index, array $keys = array())
  244. {
  245. $keys = array_merge($keys, $index->keys);
  246. $options = array();
  247. $allowed = array('name', 'dropDups', 'background', 'safe', 'unique');
  248. foreach ($allowed as $name) {
  249. if (isset($index->$name)) {
  250. $options[$name] = $index->$name;
  251. }
  252. }
  253. $options = array_merge($options, $index->options);
  254. $class->addIndex($keys, $options);
  255. }
  256. /**
  257. * Whether the class with the specified name is transient. Only non-transient
  258. * classes, that is entities and mapped superclasses, should have their metadata loaded.
  259. * A class is non-transient if it is annotated with either @Entity or
  260. * @MappedSuperclass in the class doc block.
  261. *
  262. * @param string $className
  263. * @return boolean
  264. */
  265. public function isTransient($className)
  266. {
  267. $classAnnotations = $this->reader->getClassAnnotations(new \ReflectionClass($className));
  268. return ! isset($classAnnotations['Doctrine\ODM\MongoDB\Mapping\Document']) &&
  269. ! isset($classAnnotations['Doctrine\ODM\MongoDB\Mapping\MappedSuperclass']) &&
  270. ! isset($classAnnotations['Doctrine\ODM\MongoDB\Mapping\EmbeddedDocument']);
  271. }
  272. /**
  273. * {@inheritDoc}
  274. */
  275. public function getAllClassNames()
  276. {
  277. if ($this->classNames !== null) {
  278. return $this->classNames;
  279. }
  280. if ( ! $this->paths) {
  281. throw MongoDBException::pathRequired();
  282. }
  283. $classes = array();
  284. $includedFiles = array();
  285. foreach ($this->paths as $path) {
  286. if ( ! is_dir($path)) {
  287. throw MongoDBException::fileMappingDriversRequireConfiguredDirectoryPath();
  288. }
  289. $iterator = new \RecursiveIteratorIterator(
  290. new \RecursiveDirectoryIterator($path),
  291. \RecursiveIteratorIterator::LEAVES_ONLY
  292. );
  293. foreach ($iterator as $file) {
  294. if (($fileName = $file->getBasename($this->fileExtension)) == $file->getBasename()) {
  295. continue;
  296. }
  297. $sourceFile = realpath($file->getPathName());
  298. require_once $sourceFile;
  299. $includedFiles[] = $sourceFile;
  300. }
  301. }
  302. $declared = get_declared_classes();
  303. foreach ($declared as $className) {
  304. $rc = new \ReflectionClass($className);
  305. $sourceFile = $rc->getFileName();
  306. if (in_array($sourceFile, $includedFiles) && ! $this->isTransient($className)) {
  307. $classes[] = $className;
  308. }
  309. }
  310. $this->classNames = $classes;
  311. return $classes;
  312. }
  313. /**
  314. * Factory method for the Annotation Driver
  315. *
  316. * @param array|string $paths
  317. * @param AnnotationReader $reader
  318. * @return AnnotationDriver
  319. */
  320. static public function create($paths = array(), AnnotationReader $reader = null)
  321. {
  322. if ($reader == null) {
  323. $reader = new AnnotationReader();
  324. $reader->setDefaultAnnotationNamespace('Doctrine\ODM\MongoDB\Mapping\\');
  325. }
  326. return new self($reader, $paths);
  327. }
  328. }