Skip to content

Commit 58038d5

Browse files
authored
Merge pull request #1781 from dgafka/v2.4.x
Possibility to use sluggable with embedded entites
2 parents 1a5f953 + f2b09fb commit 58038d5

File tree

1 file changed

+98
-67
lines changed

1 file changed

+98
-67
lines changed

lib/Gedmo/Sluggable/Mapping/Driver/Annotation.php

Lines changed: 98 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -62,81 +62,112 @@ public function readExtendedMetadata($meta, array &$config)
6262
) {
6363
continue;
6464
}
65-
// slug property
66-
if ($slug = $this->reader->getPropertyAnnotation($property, self::SLUG)) {
67-
$field = $property->getName();
68-
if (!$meta->hasField($field)) {
69-
throw new InvalidMappingException("Unable to find slug [{$field}] as mapped property in entity - {$meta->name}");
70-
}
71-
if (!$this->isValidField($meta, $field)) {
72-
throw new InvalidMappingException("Cannot use field - [{$field}] for slug storage, type is not valid and must be 'string' or 'text' in class - {$meta->name}");
65+
$config = $this->retrieveSlug($meta, $config, $property, '');
66+
}
67+
68+
// Embedded entity
69+
if (property_exists($meta, 'embeddedClasses') && $meta->embeddedClasses) {
70+
foreach ($meta->embeddedClasses as $propertyName => $embeddedClassInfo) {
71+
$embeddedClass = new \ReflectionClass($embeddedClassInfo['class']);
72+
foreach ($embeddedClass->getProperties() as $embeddedProperty) {
73+
$config = $this->retrieveSlug($meta, $config, $embeddedProperty, $propertyName);
7374
}
74-
// process slug handlers
75-
$handlers = array();
76-
if (is_array($slug->handlers) && $slug->handlers) {
77-
foreach ($slug->handlers as $handler) {
78-
if (!$handler instanceof SlugHandler) {
79-
throw new InvalidMappingException("SlugHandler: {$handler} should be instance of SlugHandler annotation in entity - {$meta->name}");
80-
}
81-
if (!strlen($handler->class)) {
82-
throw new InvalidMappingException("SlugHandler class: {$handler->class} should be a valid class name in entity - {$meta->name}");
83-
}
84-
$class = $handler->class;
85-
$handlers[$class] = array();
86-
foreach ((array) $handler->options as $option) {
87-
if (!$option instanceof SlugHandlerOption) {
88-
throw new InvalidMappingException("SlugHandlerOption: {$option} should be instance of SlugHandlerOption annotation in entity - {$meta->name}");
89-
}
90-
if (!strlen($option->name)) {
91-
throw new InvalidMappingException("SlugHandlerOption name: {$option->name} should be valid name in entity - {$meta->name}");
92-
}
93-
$handlers[$class][$option->name] = $option->value;
94-
}
95-
$class::validate($handlers[$class], $meta);
75+
}
76+
}
77+
78+
return $config;
79+
}
80+
81+
/**
82+
* @param $meta
83+
* @param array $config
84+
* @param $property
85+
* @param $fieldNamePrefix
86+
* @return array
87+
*/
88+
private function retrieveSlug($meta, array &$config, $property, $fieldNamePrefix)
89+
{
90+
$fieldName = $fieldNamePrefix ? ($fieldNamePrefix . '.' . $property->getName()) : $property->getName();
91+
// slug property
92+
if ($slug = $this->reader->getPropertyAnnotation($property, self::SLUG)) {
93+
if (!$meta->hasField($fieldName)) {
94+
throw new InvalidMappingException("Unable to find slug [{$fieldName}] as mapped property in entity - {$meta->name}");
95+
}
96+
if (!$this->isValidField($meta, $fieldName)) {
97+
throw new InvalidMappingException("Cannot use field - [{$fieldName}] for slug storage, type is not valid and must be 'string' or 'text' in class - {$meta->name}");
98+
}
99+
// process slug handlers
100+
$handlers = array();
101+
if (is_array($slug->handlers) && $slug->handlers) {
102+
foreach ($slug->handlers as $handler) {
103+
if (!$handler instanceof SlugHandler) {
104+
throw new InvalidMappingException("SlugHandler: {$handler} should be instance of SlugHandler annotation in entity - {$meta->name}");
96105
}
97-
}
98-
// process slug fields
99-
if (empty($slug->fields) || !is_array($slug->fields)) {
100-
throw new InvalidMappingException("Slug must contain at least one field for slug generation in class - {$meta->name}");
101-
}
102-
foreach ($slug->fields as $slugField) {
103-
if (!$meta->hasField($slugField)) {
104-
throw new InvalidMappingException("Unable to find slug [{$slugField}] as mapped property in entity - {$meta->name}");
106+
if (!strlen($handler->class)) {
107+
throw new InvalidMappingException("SlugHandler class: {$handler->class} should be a valid class name in entity - {$meta->name}");
105108
}
106-
if (!$this->isValidField($meta, $slugField)) {
107-
throw new InvalidMappingException("Cannot use field - [{$slugField}] for slug storage, type is not valid and must be 'string' or 'text' in class - {$meta->name}");
109+
$class = $handler->class;
110+
$handlers[$class] = array();
111+
foreach ((array)$handler->options as $option) {
112+
if (!$option instanceof SlugHandlerOption) {
113+
throw new InvalidMappingException("SlugHandlerOption: {$option} should be instance of SlugHandlerOption annotation in entity - {$meta->name}");
114+
}
115+
if (!strlen($option->name)) {
116+
throw new InvalidMappingException("SlugHandlerOption name: {$option->name} should be valid name in entity - {$meta->name}");
117+
}
118+
$handlers[$class][$option->name] = $option->value;
108119
}
120+
$class::validate($handlers[$class], $meta);
109121
}
110-
if (!is_bool($slug->updatable)) {
111-
throw new InvalidMappingException("Slug annotation [updatable], type is not valid and must be 'boolean' in class - {$meta->name}");
112-
}
113-
if (!is_bool($slug->unique)) {
114-
throw new InvalidMappingException("Slug annotation [unique], type is not valid and must be 'boolean' in class - {$meta->name}");
115-
}
116-
if (!empty($meta->identifier) && $meta->isIdentifier($field) && !(bool) $slug->unique) {
117-
throw new InvalidMappingException("Identifier field - [{$field}] slug must be unique in order to maintain primary key in class - {$meta->name}");
118-
}
119-
if ($slug->unique === false && $slug->unique_base) {
120-
throw new InvalidMappingException("Slug annotation [unique_base] can not be set if unique is unset or 'false'");
122+
}
123+
// process slug fields
124+
if (empty($slug->fields) || !is_array($slug->fields)) {
125+
throw new InvalidMappingException("Slug must contain at least one field for slug generation in class - {$meta->name}");
126+
}
127+
foreach ($slug->fields as $slugField) {
128+
$slugFieldWithPrefix = $fieldNamePrefix ? ($fieldNamePrefix . '.' . $slugField) : $slugField;
129+
if (!$meta->hasField($slugFieldWithPrefix)) {
130+
throw new InvalidMappingException("Unable to find slug [{$slugFieldWithPrefix}] as mapped property in entity - {$meta->name}");
121131
}
122-
if ($slug->unique_base && !$meta->hasField($slug->unique_base) && !$meta->hasAssociation($slug->unique_base)) {
123-
throw new InvalidMappingException("Unable to find [{$slug->unique_base}] as mapped property in entity - {$meta->name}");
132+
if (!$this->isValidField($meta, $slugFieldWithPrefix)) {
133+
throw new InvalidMappingException("Cannot use field - [{$slugFieldWithPrefix}] for slug storage, type is not valid and must be 'string' or 'text' in class - {$meta->name}");
124134
}
125-
// set all options
126-
$config['slugs'][$field] = array(
127-
'fields' => $slug->fields,
128-
'slug' => $field,
129-
'style' => $slug->style,
130-
'dateFormat' => $slug->dateFormat,
131-
'updatable' => $slug->updatable,
132-
'unique' => $slug->unique,
133-
'unique_base' => $slug->unique_base,
134-
'separator' => $slug->separator,
135-
'prefix' => $slug->prefix,
136-
'suffix' => $slug->suffix,
137-
'handlers' => $handlers,
138-
);
139135
}
136+
if (!is_bool($slug->updatable)) {
137+
throw new InvalidMappingException("Slug annotation [updatable], type is not valid and must be 'boolean' in class - {$meta->name}");
138+
}
139+
if (!is_bool($slug->unique)) {
140+
throw new InvalidMappingException("Slug annotation [unique], type is not valid and must be 'boolean' in class - {$meta->name}");
141+
}
142+
if (!empty($meta->identifier) && $meta->isIdentifier($fieldName) && !(bool)$slug->unique) {
143+
throw new InvalidMappingException("Identifier field - [{$fieldName}] slug must be unique in order to maintain primary key in class - {$meta->name}");
144+
}
145+
if ($slug->unique === false && $slug->unique_base) {
146+
throw new InvalidMappingException("Slug annotation [unique_base] can not be set if unique is unset or 'false'");
147+
}
148+
if ($slug->unique_base && !$meta->hasField($slug->unique_base) && !$meta->hasAssociation($slug->unique_base)) {
149+
throw new InvalidMappingException("Unable to find [{$slug->unique_base}] as mapped property in entity - {$meta->name}");
150+
}
151+
$sluggableFields = [];
152+
foreach ($slug->fields as $field) {
153+
$sluggableFields[] = $fieldNamePrefix ? ($fieldNamePrefix . '.' . $field) : $field;
154+
}
155+
156+
// set all options
157+
$config['slugs'][$fieldName] = array(
158+
'fields' => $sluggableFields,
159+
'slug' => $fieldName,
160+
'style' => $slug->style,
161+
'dateFormat' => $slug->dateFormat,
162+
'updatable' => $slug->updatable,
163+
'unique' => $slug->unique,
164+
'unique_base' => $slug->unique_base,
165+
'separator' => $slug->separator,
166+
'prefix' => $slug->prefix,
167+
'suffix' => $slug->suffix,
168+
'handlers' => $handlers,
169+
);
140170
}
171+
return $config;
141172
}
142173
}

0 commit comments

Comments
 (0)