Annotation.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. namespace Gedmo\Tree\Mapping\Driver;
  3. use Gedmo\Mapping\Driver,
  4. Doctrine\Common\Annotations\AnnotationReader,
  5. Doctrine\ORM\Mapping\ClassMetadataInfo,
  6. Gedmo\Tree\Mapping\MappingException;
  7. /**
  8. * This is an annotation mapping driver for Tree
  9. * behavioral extension. Used for extraction of extended
  10. * metadata from Annotations specificaly for Tree
  11. * extension.
  12. *
  13. * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
  14. * @package Gedmo.Tree.Mapping.Driver
  15. * @subpackage Annotation
  16. * @link http://www.gediminasm.org
  17. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  18. */
  19. class Annotation implements Driver
  20. {
  21. /**
  22. * Annotation to mark field as one which will store left value
  23. */
  24. const ANNOTATION_LEFT = 'Gedmo\Tree\Mapping\TreeLeft';
  25. /**
  26. * Annotation to mark field as one which will store right value
  27. */
  28. const ANNOTATION_RIGHT = 'Gedmo\Tree\Mapping\TreeRight';
  29. /**
  30. * Annotation to mark relative parent field
  31. */
  32. const ANNOTATION_PARENT = 'Gedmo\Tree\Mapping\TreeParent';
  33. /**
  34. * Annotation to mark node level
  35. */
  36. const ANNOTATION_LEVEL = 'Gedmo\Tree\Mapping\TreeLevel';
  37. /**
  38. * List of types which are valid for timestamp
  39. *
  40. * @var array
  41. */
  42. private $_validTypes = array(
  43. 'integer',
  44. 'smallint',
  45. 'bigint'
  46. );
  47. /**
  48. * (non-PHPdoc)
  49. * @see Gedmo\Mapping.Driver::validateFullMetadata()
  50. */
  51. public function validateFullMetadata(ClassMetadataInfo $meta, array $config)
  52. {
  53. if ($config) {
  54. $missingFields = array();
  55. if (!isset($config['parent'])) {
  56. $missingFields[] = 'ancestor';
  57. }
  58. if (!isset($config['left'])) {
  59. $missingFields[] = 'left';
  60. }
  61. if (!isset($config['right'])) {
  62. $missingFields[] = 'right';
  63. }
  64. if ($missingFields) {
  65. throw MappingException::missingMetaProperties($missingFields, $meta->name);
  66. }
  67. }
  68. }
  69. /**
  70. * (non-PHPdoc)
  71. * @see Gedmo\Mapping.Driver::readExtendedMetadata()
  72. */
  73. public function readExtendedMetadata(ClassMetadataInfo $meta, array &$config) {
  74. require_once __DIR__ . '/../Annotations.php';
  75. $reader = new AnnotationReader();
  76. $reader->setAnnotationNamespaceAlias('Gedmo\Tree\Mapping\\', 'gedmo');
  77. $class = $meta->getReflectionClass();
  78. // property annotations
  79. foreach ($class->getProperties() as $property) {
  80. if ($meta->isMappedSuperclass && !$property->isPrivate() ||
  81. $meta->isInheritedField($property->name) ||
  82. $meta->isInheritedAssociation($property->name)
  83. ) {
  84. continue;
  85. }
  86. // left
  87. if ($left = $reader->getPropertyAnnotation($property, self::ANNOTATION_LEFT)) {
  88. $field = $property->getName();
  89. if (!$meta->hasField($field)) {
  90. throw MappingException::fieldMustBeMapped($field, $meta->name);
  91. }
  92. if (!$this->_isValidField($meta, $field)) {
  93. throw MappingException::notValidFieldType($field, $meta->name);
  94. }
  95. $config['left'] = $field;
  96. }
  97. // right
  98. if ($right = $reader->getPropertyAnnotation($property, self::ANNOTATION_RIGHT)) {
  99. $field = $property->getName();
  100. if (!$meta->hasField($field)) {
  101. throw MappingException::fieldMustBeMapped($field, $meta->name);
  102. }
  103. if (!$this->_isValidField($meta, $field)) {
  104. throw MappingException::notValidFieldType($field, $meta->name);
  105. }
  106. $config['right'] = $field;
  107. }
  108. // ancestor/parent
  109. if ($parent = $reader->getPropertyAnnotation($property, self::ANNOTATION_PARENT)) {
  110. $field = $property->getName();
  111. if (!$meta->isSingleValuedAssociation($field)) {
  112. throw MappingException::parentFieldNotMappedOrRelated($field, $meta->name);
  113. }
  114. $config['parent'] = $field;
  115. }
  116. // level
  117. if ($parent = $reader->getPropertyAnnotation($property, self::ANNOTATION_LEVEL)) {
  118. $field = $property->getName();
  119. if (!$meta->hasField($field)) {
  120. throw MappingException::fieldMustBeMapped($field, $meta->name);
  121. }
  122. if (!$this->_isValidField($meta, $field)) {
  123. throw MappingException::notValidFieldType($field, $meta->name);
  124. }
  125. $config['level'] = $field;
  126. }
  127. }
  128. }
  129. /**
  130. * Checks if $field type is valid
  131. *
  132. * @param ClassMetadataInfo $meta
  133. * @param string $field
  134. * @return boolean
  135. */
  136. protected function _isValidField(ClassMetadataInfo $meta, $field)
  137. {
  138. return in_array($meta->getTypeOfField($field), $this->_validTypes);
  139. }
  140. }