diff --git a/src/Exception/IncrementException.php b/src/Exception/IncrementException.php index c101a84..fc74a8b 100644 --- a/src/Exception/IncrementException.php +++ b/src/Exception/IncrementException.php @@ -3,7 +3,7 @@ use Cake\Core\Exception\Exception; -class LengthException extends Exception +class IncrementException extends Exception { /** * {@inheritdoc} diff --git a/src/Model/Behavior/SlugBehavior.php b/src/Model/Behavior/SlugBehavior.php index 5c553cb..2f41d5c 100644 --- a/src/Model/Behavior/SlugBehavior.php +++ b/src/Model/Behavior/SlugBehavior.php @@ -50,39 +50,41 @@ public function beforeSave(Event $event, EntityInterface $entity) $slug = $config; } - if (!isset($this->_config[$slug]['present']) || $this->_config[$slug]['present'] !== true) { - if (!isset($this->_config[$slug]['field'])) { - $this->_config[$slug]['field'] = $this->_defaultField; - } + if (isset($this->_config[$slug]['present']) && $this->_config[$slug]['present'] === true) { + continue; + } - if ($this->_table->hasField($slug)) { - if ($this->_table->hasField($this->_config[$slug]['field'])) { - $schema = $this->_table->getSchema()->getColumn($slug); - - if ($schema['type'] == 'string') { - if (!isset($this->_config[$slug]['replacement'])) { - $this->_config[$slug]['replacement'] = $this->_defaultReplacement; - } - - if (!isset($this->_config[$slug]['length']) || $this->_config[$slug]['length'] > $schema['length']) { - $this->_config[$slug]['length'] = $schema['length']; - } - - if (!isset($this->_config[$slug]['finder'])) { - $this->_config[$slug]['finder'] = $this->_defaultFinder; - } - - $entity->{$slug} = $this->createSlug($entity->{$this->_config[$slug]['field']}, $slug); - } else { - throw new FieldTypeException(__d('slug', 'Field {s} should be string type.', $slug)); - } - } else { - throw new FieldException(__d('slug', 'Cannot find {0} field as source in schema.', $this->_config[$slug]['field'])); - } - } else { - throw new FieldException(__d('slug', 'Cannot find {0} field in schema.', $slug)); - } + if (!isset($this->_config[$slug]['field'])) { + $this->_config[$slug]['field'] = $this->_defaultField; + } + + if (!$this->_table->hasField($slug)) { + throw new FieldException(__d('slug', 'Cannot find {0} field in schema.', $slug)); + } + + if (!$this->_table->hasField($this->_config[$slug]['field'])) { + throw new FieldException(__d('slug', 'Cannot find {0} field as source in schema.', $this->_config[$slug]['field'])); + } + + $schema = $this->_table->getSchema()->getColumn($slug); + + if ($schema['type'] != 'string') { + throw new FieldTypeException(__d('slug', 'Field {0} should be string type.', $slug)); + } + + if (!isset($this->_config[$slug]['replacement'])) { + $this->_config[$slug]['replacement'] = $this->_defaultReplacement; } + + if (!isset($this->_config[$slug]['length']) || $this->_config[$slug]['length'] > $schema['length']) { + $this->_config[$slug]['length'] = $schema['length']; + } + + if (!isset($this->_config[$slug]['finder'])) { + $this->_config[$slug]['finder'] = $this->_defaultFinder; + } + + $entity->{$slug} = $this->createSlug($entity->{$this->_config[$slug]['field']}, $slug); } } @@ -95,85 +97,87 @@ public function beforeSave(Event $event, EntityInterface $entity) */ public function createSlug($slug, $field) { - if ((mb_strlen($this->_config[$field]['replacement']) + 1) < $this->_config[$field]['length']) { - if (isset($this->_config[$field]['method'])) { - if (method_exists($this->_table, $this->_config[$field]['method'])) { - $slug = $this->_table->{$this->_config[$field]['method']}($slug, $this->_config[$field]['replacement']); - } else { - throw new MethodException(__d('slug', 'Method {0} does not exist.', $this->_config[$field]['method'])); - } - } else { - $slug = Text::slug(mb_strtolower($slug), [ - 'replacement' => $this->_config[$field]['replacement'] - ]); + $config = $this->_config[$field]; + + if ((mb_strlen($config['replacement']) + 1) >= $config['length']) { + throw new LimitException(__d('slug', 'Limit of length in {0} field is too short.', $field)); + } + + if (isset($config['method'])) { + if (!method_exists($this->_table, $config['method'])) { + throw new MethodException(__d('slug', 'Method {0} does not exist.', $config['method'])); } - $slugs = $this->_sortSlugs($this->_getSlugs($slug, $field)); + $slug = $this->_table->{$config['method']}($slug, $config['replacement']); + } else { + $slug = Text::slug(mb_strtolower($slug), [ + 'replacement' => $config['replacement'] + ]); + } - // Slug is just numbers - if (preg_match('/^[0-9]+$/', $slug)) { - $numbers = preg_grep('/^[0-9]+$/', $slugs); + $slugs = $this->_sortSlugs($this->_getSlugs($slug, $field)); - if (!empty($numbers)) { - sort($numbers); + // Slug is just numbers + if (preg_match('/^[0-9]+$/', $slug)) { + $numbers = preg_grep('/^[0-9]+$/', $slugs); - $slug = end($numbers); + if (!empty($numbers)) { + sort($numbers); - $slug++; - } + $slug = end($numbers); + + $slug++; } + } - // Cut slug - if (mb_strlen($replace = preg_replace('/\s+/', $this->_config[$field]['replacement'], $slug)) > $this->_config[$field]['length']) { - $slug = mb_substr($replace, 0, $this->_config[$field]['length']); + // Cut slug + if (mb_strlen($replace = preg_replace('/\s+/', $config['replacement'], $slug)) > $config['length']) { + $slug = mb_substr($replace, 0, $config['length']); - // Update slug list based on cut slug - $slugs = $this->_sortSlugs($this->_getSlugs($slug, $field)); - } + // Update slug list based on cut slug + $slugs = $this->_sortSlugs($this->_getSlugs($slug, $field)); + } - $slug = preg_replace('/' . preg_quote($this->_config[$field]['replacement']) . '$/', '', trim(mb_substr($slug, 0, $this->_config[$field]['length']))); + $slug = preg_replace('/' . preg_quote($config['replacement']) . '$/', '', trim(mb_substr($slug, 0, $config['length']))); - if (in_array($slug, $slugs)) { - $list = preg_grep('/^' . preg_replace('/' . preg_quote($this->_config[$field]['replacement']) . '([1-9]{1}[0-9]*)$/', $this->_config[$field]['replacement'], $slug) . '/', $slugs); + if (in_array($slug, $slugs)) { + $list = preg_grep('/^' . preg_replace('/' . preg_quote($config['replacement']) . '([1-9]{1}[0-9]*)$/', $config['replacement'], $slug) . '/', $slugs); - preg_match('/^(.*)' . preg_quote($this->_config[$field]['replacement']) . '([1-9]{1}[0-9]*)$/', end($list), $matches); + preg_match('/^(.*)' . preg_quote($config['replacement']) . '([1-9]{1}[0-9]*)$/', end($list), $matches); - if (empty($matches)) { - $increment = 1; + if (empty($matches)) { + $increment = 1; + } else { + if (isset($matches[2])) { + $increment = $matches[2] += 1; } else { - if (isset($matches[2])) { - $increment = $matches[2] += 1; - } else { - throw new IncrementException(__d('slug', 'Cannot create next suffix because matches are empty.')); - } + throw new IncrementException(__d('slug', 'Cannot create next suffix because matches are empty.')); } + } - if (mb_strlen($slug . $this->_config[$field]['replacement'] . $increment) <= $this->_config[$field]['length']) { - $string = $slug; - } elseif (mb_strlen(mb_substr($slug, 0, -mb_strlen($increment))) + mb_strlen($this->_config[$field]['replacement'] . $increment) <= $this->_config[$field]['length']) { - $string = mb_substr($slug, 0, $this->_config[$field]['length'] - mb_strlen($this->_config[$field]['replacement'] . $increment)); - } else { - $string = mb_substr($slug, 0, -(mb_strlen($this->_config[$field]['replacement'] . $increment))); - } + if (mb_strlen($slug . $config['replacement'] . $increment) <= $config['length']) { + $string = $slug; + } elseif (mb_strlen(mb_substr($slug, 0, -mb_strlen($increment))) + mb_strlen($config['replacement'] . $increment) <= $config['length']) { + $string = mb_substr($slug, 0, $config['length'] - mb_strlen($config['replacement'] . $increment)); + } else { + $string = mb_substr($slug, 0, -(mb_strlen($config['replacement'] . $increment))); + } - if (mb_strlen($string) > 0) { - $slug = $string . $this->_config[$field]['replacement'] . $increment; + if (mb_strlen($string) <= 0) { + throw new LengthException(__d('slug', 'Cannot create slug because there are no available names.')); + } - // Refresh slugs list - $slugs = $this->_sortSlugs(array_merge($slugs, $this->_getSlugs($slug, $field))); + $slug = $string . $config['replacement'] . $increment; - if (in_array($slug, $slugs)) { - return $this->createSlug($slug, $field); - } - } else { - throw new LengthException(__d('slug', 'Cannot create slug because there are no available names.')); - } - } + // Refresh slugs list + $slugs = $this->_sortSlugs(array_merge($slugs, $this->_getSlugs($slug, $field))); - return $slug; - } else { - throw new LimitException(__d('slug', 'Limit of length in {0} field is too short.', $field)); + if (in_array($slug, $slugs)) { + return $this->createSlug($slug, $field); + } } + + return $slug; } /**