@@ -34,7 +34,8 @@ class SlugBehavior extends Behavior
3434 * to `Muffin\Slug\Slugger\CakeSlugger`.
3535 * - unique: Tells if slugs should be unique. Set this to a callable if you
3636 * want to customize how unique slugs are generated. Defaults to `true`.
37- * - scope: Extra conditions used when checking a slug for uniqueness.
37+ * - scope: Extra conditions or a callable `$callable($entity)` used when
38+ * checking a slug for uniqueness.
3839 * - implementedEvents: Events this behavior listens to. Defaults to
3940 * `['Model.buildValidator' => 'buildValidator', 'Model.beforeSave' => 'beforeSave']`.
4041 * By default the behavior adds validation for the `displayField` fields
@@ -218,25 +219,37 @@ public function beforeSave(Event $event, Entity $entity, ArrayObject $options)
218219 return ;
219220 }
220221
222+ $ parts = $ this ->_getPartsFromEntity ($ entity );
223+ if (empty ($ parts )) {
224+ return ;
225+ }
226+
227+ $ slug = $ this ->slug ($ entity , implode ($ separator , $ parts ), $ separator );
228+ $ entity ->set ($ field , $ slug );
229+ }
230+
231+ /**
232+ * Gets the parts from an entity
233+ *
234+ * @param \Cake\Datasource\EntityInterface $entity Entity
235+ * @return array
236+ */
237+ protected function _getPartsFromEntity ($ entity )
238+ {
221239 $ parts = [];
222240 foreach ((array )$ this ->getConfig ('displayField ' ) as $ displayField ) {
223241 $ value = Hash::get ($ entity , $ displayField );
224242
225243 if ($ value === null && !$ entity ->isNew ()) {
226- return ;
244+ return [] ;
227245 }
228246
229247 if (!empty ($ value ) || is_numeric ($ value )) {
230248 $ parts [] = $ value ;
231249 }
232250 }
233251
234- if (!count ($ parts )) {
235- return ;
236- }
237-
238- $ slug = $ this ->slug ($ entity , implode ($ separator , $ parts ), $ separator );
239- $ entity ->set ($ field , $ slug );
252+ return $ parts ;
240253 }
241254
242255 /**
@@ -278,14 +291,7 @@ public function slug($entity, $string = null, $separator = null)
278291 $ string = $ entity ;
279292 unset($ entity );
280293 } elseif (($ entity instanceof Entity) && $ string === null ) {
281- $ string = [];
282- foreach ((array )$ this ->getConfig ('displayField ' ) as $ field ) {
283- if ($ entity ->getError ($ field )) {
284- throw new InvalidArgumentException ();
285- }
286- $ string [] = $ value = Hash::get ($ entity , $ field );
287- }
288- $ string = implode ($ separator , $ string );
294+ $ string = $ this ->_getSlugStringFromEntity ($ entity , $ separator );
289295 }
290296
291297 $ slug = $ this ->_slug ($ string , $ separator );
@@ -298,6 +304,55 @@ public function slug($entity, $string = null, $separator = null)
298304 return $ slug ;
299305 }
300306
307+ /**
308+ * Gets the slug string based on an entity
309+ *
310+ * @param \Cake\Datasource\EntityInterface $entity Entity
311+ * @param string $separator Separator
312+ * @return string
313+ */
314+ protected function _getSlugStringFromEntity ($ entity , $ separator )
315+ {
316+ $ string = [];
317+ foreach ((array )$ this ->getConfig ('displayField ' ) as $ field ) {
318+ if ($ entity ->getError ($ field )) {
319+ throw new InvalidArgumentException (sprintf ('Error while generating the slug, the field `%s` contains an invalid value. ' , $ field ));
320+ }
321+ $ string [] = $ value = Hash::get ($ entity , $ field );
322+ }
323+
324+ return implode ($ separator , $ string );
325+ }
326+
327+ /**
328+ * Builds the conditions
329+ *
330+ * @param \Cake\ORM\Entity $entity Entity.
331+ * @param string $slug Slug
332+ * @return array
333+ */
334+ protected function _conditions ($ entity , $ slug )
335+ {
336+ /** @var string $primaryKey */
337+ $ primaryKey = $ this ->_table ->getPrimaryKey ();
338+ $ field = $ this ->_table ->aliasField ($ this ->getConfig ('field ' ));
339+
340+ $ conditions = [$ field => $ slug ];
341+
342+ if (is_callable ($ this ->getConfig ('scope ' ))) {
343+ $ scope = $ this ->getConfig ('scope ' );
344+ $ conditions += $ scope ($ entity );
345+ } else {
346+ $ conditions += $ this ->getConfig ('scope ' );
347+ }
348+
349+ if ($ id = $ entity ->{$ primaryKey }) {
350+ $ conditions ['NOT ' ][$ this ->_table ->aliasField ($ primaryKey )] = $ id ;
351+ }
352+
353+ return $ conditions ;
354+ }
355+
301356 /**
302357 * Returns a unique slug.
303358 *
@@ -312,11 +367,7 @@ protected function _uniqueSlug(Entity $entity, $slug, $separator)
312367 $ primaryKey = $ this ->_table ->getPrimaryKey ();
313368 $ field = $ this ->_table ->aliasField ($ this ->getConfig ('field ' ));
314369
315- $ conditions = [$ field => $ slug ];
316- $ conditions += $ this ->getConfig ('scope ' );
317- if ($ id = $ entity ->{$ primaryKey }) {
318- $ conditions ['NOT ' ][$ this ->_table ->aliasField ($ primaryKey )] = $ id ;
319- }
370+ $ conditions = $ this ->_conditions ($ entity , $ slug );
320371
321372 $ i = 0 ;
322373 $ suffix = '' ;
0 commit comments