Annotation.php 4.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. <?php
  2. namespace Gedmo\Sluggable\Mapping\Driver;
  3. use Gedmo\Mapping\Annotation\SlugHandler;
  4. use Gedmo\Mapping\Annotation\SlugHandlerOption;
  5. use Gedmo\Mapping\Driver\AbstractAnnotationDriver,
  6. Doctrine\Common\Annotations\AnnotationReader,
  7. Gedmo\Exception\InvalidMappingException;
  8. /**
  9. * This is an annotation mapping driver for Sluggable
  10. * behavioral extension. Used for extraction of extended
  11. * metadata from Annotations specificaly for Sluggable
  12. * extension.
  13. *
  14. * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
  15. * @package Gedmo.Sluggable.Mapping.Driver
  16. * @subpackage Annotation
  17. * @link http://www.gediminasm.org
  18. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  19. */
  20. class Annotation extends AbstractAnnotationDriver
  21. {
  22. /**
  23. * Annotation to identify field as one which holds the slug
  24. * together with slug options
  25. */
  26. const SLUG = 'Gedmo\\Mapping\\Annotation\\Slug';
  27. /**
  28. * List of types which are valid for slug and sluggable fields
  29. *
  30. * @var array
  31. */
  32. protected $validTypes = array(
  33. 'string',
  34. 'text',
  35. 'integer',
  36. 'int',
  37. );
  38. /**
  39. * {@inheritDoc}
  40. */
  41. public function readExtendedMetadata($meta, array &$config) {
  42. $class = $this->getMetaReflectionClass($meta);
  43. // property annotations
  44. foreach ($class->getProperties() as $property) {
  45. if ($meta->isMappedSuperclass && !$property->isPrivate() ||
  46. $meta->isInheritedField($property->name) ||
  47. isset($meta->associationMappings[$property->name]['inherited'])
  48. ) {
  49. continue;
  50. }
  51. // slug property
  52. if ($slug = $this->reader->getPropertyAnnotation($property, self::SLUG)) {
  53. $field = $property->getName();
  54. if (!$meta->hasField($field)) {
  55. throw new InvalidMappingException("Unable to find slug [{$field}] as mapped property in entity - {$meta->name}");
  56. }
  57. if (!$this->isValidField($meta, $field)) {
  58. throw new InvalidMappingException("Cannot use field - [{$field}] for slug storage, type is not valid and must be 'string' or 'text' in class - {$meta->name}");
  59. }
  60. // process slug fields
  61. if (empty($slug->fields) || !is_array($slug->fields)) {
  62. throw new InvalidMappingException("Slug must contain at least one field for slug generation in class - {$meta->name}");
  63. }
  64. foreach ($slug->fields as $slugField) {
  65. if (!$meta->hasField($slugField)) {
  66. throw new InvalidMappingException("Unable to find slug [{$slugField}] as mapped property in entity - {$meta->name}");
  67. }
  68. if (!$this->isValidField($meta, $slugField)) {
  69. throw new InvalidMappingException("Cannot use field - [{$slugField}] for slug storage, type is not valid and must be 'string' or 'text' in class - {$meta->name}");
  70. }
  71. }
  72. if (!is_bool($slug->updatable)) {
  73. throw new InvalidMappingException("Slug annotation [updatable], type is not valid and must be 'boolean' in class - {$meta->name}");
  74. }
  75. if (!is_bool($slug->unique)) {
  76. throw new InvalidMappingException("Slug annotation [unique], type is not valid and must be 'boolean' in class - {$meta->name}");
  77. }
  78. if (!empty($meta->identifier) && $meta->isIdentifier($field) && !(bool)$slug->unique) {
  79. throw new InvalidMappingException("Identifier field - [{$field}] slug must be unique in order to maintain primary key in class - {$meta->name}");
  80. }
  81. // set all options
  82. $config['slugs'][$field] = array(
  83. 'fields' => $slug->fields,
  84. 'slug' => $field,
  85. 'style' => $slug->style,
  86. 'updatable' => $slug->updatable,
  87. 'unique' => $slug->unique,
  88. 'separator' => $slug->separator,
  89. );
  90. }
  91. }
  92. }
  93. }