Skip to content

Commit

Permalink
Add test for overwrite and no title present.
Browse files Browse the repository at this point in the history
  • Loading branch information
dereuromark committed Feb 28, 2024
1 parent 48bfcb9 commit 0da38f2
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 69 deletions.
148 changes: 81 additions & 67 deletions src/Model/Behavior/SluggedBehavior.php
Expand Up @@ -221,18 +221,32 @@ public function slug(EntityInterface $entity, array $options = []) {
if (!$overwrite && $entity->get($this->_config['overwriteField'])) {
$overwrite = true;
}
if ($overwrite || $entity->isNew() || !$entity->get($this->_config['field'])) {
$pieces = [];
foreach ((array)$this->_config['label'] as $v) {
$v = $entity->get($v);
if ($v !== null && $v !== '') {
$pieces[] = $v;
}
if (!$overwrite && !$entity->isNew() && $entity->get($this->_config['field'])) {
return;
}

$pieces = [];
$atLeastOneLabelFieldExists = false;
foreach ((array)$this->_config['label'] as $v) {
if ($entity->has($v)) {
$atLeastOneLabelFieldExists = true;
}
$v = $entity->get($v);
if ($v !== null && $v !== '') {
$pieces[] = $v;
}
$slug = implode($this->_config['separator'], $pieces);
$slug = $this->generateSlug($slug, $entity);
$entity->set($this->_config['field'], $slug);
}

if (!$atLeastOneLabelFieldExists) {
return;
}
if (!$pieces && !$this->needsSlugUpdate($entity)) {
return;
}

$slug = implode($this->_config['separator'], $pieces);
$slug = $this->generateSlug($slug, $entity);
$entity->set($this->_config['field'], $slug);
}

/**
Expand Down Expand Up @@ -262,6 +276,63 @@ public function needsSlugUpdate(EntityInterface $entity, $deep = false) {
return false;
}

/**
* ResetSlugs method.
*
* Regenerate all slugs. On large dbs this can take more than 30 seconds - a time
* limit is set to allow a minimum 100 updates per second as a preventative measure.
*
* Note that you should use the Reset behavior if you need additional functionality such
* as callbacks or timeouts.
*
* @param array<string, mixed> $params
* @throws \RuntimeException
* @return bool Success
*/
public function resetSlugs($params = []) {
if (!$this->_table->hasField($this->_config['field'])) {
throw new RuntimeException('Table does not have field ' . $this->_config['field']);
}
/** @var string $displayField */
$displayField = $this->_table->getDisplayField();
$defaults = [
'page' => 1,
'limit' => 100,
'fields' => array_merge([$this->_table->getPrimaryKey()], $this->_config['label']),
'order' => $displayField . ' ASC',
'conditions' => $this->_config['scope'],
'overwrite' => true,
];
$params += $defaults;

$conditions = $params['conditions'];
$count = $this->_table->find('all', compact('conditions'))->count();
$max = (int)ini_get('max_execution_time');
if ($max) {
set_time_limit(max($max, $count / 100));
}

$this->setConfig($params, null, false);
while (($records = $this->_table->find('all', $params)->toArray())) {
/** @var \Cake\ORM\Entity $record */
foreach ($records as $record) {
$record->setNew(true);

$fields = array_merge([$this->_table->getPrimaryKey(), $this->_config['field']], $this->_config['label']);
$options = [
'validate' => true,
'fields' => $fields,
];
if (!$this->_table->save($record, $options)) {
throw new RuntimeException(print_r($record->getErrors(), true));
}
}
$params['page']++;
}

return true;
}

/**
* Slug method
*
Expand Down Expand Up @@ -370,63 +441,6 @@ public function generateSlug($value, ?EntityInterface $entity = null) {
return $slug;
}

/**
* ResetSlugs method.
*
* Regenerate all slugs. On large dbs this can take more than 30 seconds - a time
* limit is set to allow a minimum 100 updates per second as a preventative measure.
*
* Note that you should use the Reset behavior if you need additional functionality such
* as callbacks or timeouts.
*
* @param array<string, mixed> $params
* @throws \RuntimeException
* @return bool Success
*/
public function resetSlugs($params = []) {
if (!$this->_table->hasField($this->_config['field'])) {
throw new RuntimeException('Table does not have field ' . $this->_config['field']);
}
/** @var string $displayField */
$displayField = $this->_table->getDisplayField();
$defaults = [
'page' => 1,
'limit' => 100,
'fields' => array_merge([$this->_table->getPrimaryKey()], $this->_config['label']),
'order' => $displayField . ' ASC',
'conditions' => $this->_config['scope'],
'overwrite' => true,
];
$params += $defaults;

$conditions = $params['conditions'];
$count = $this->_table->find('all', compact('conditions'))->count();
$max = (int)ini_get('max_execution_time');
if ($max) {
set_time_limit(max($max, $count / 100));
}

$this->setConfig($params, null, false);
while (($records = $this->_table->find('all', $params)->toArray())) {
/** @var \Cake\ORM\Entity $record */
foreach ($records as $record) {
$record->setNew(true);

$fields = array_merge([$this->_table->getPrimaryKey(), $this->_config['field']], $this->_config['label']);
$options = [
'validate' => true,
'fields' => $fields,
];
if (!$this->_table->save($record, $options)) {
throw new RuntimeException(print_r($record->getErrors(), true));
}
}
$params['page']++;
}

return true;
}

/**
* Multi slug method
*
Expand Down
23 changes: 21 additions & 2 deletions tests/TestCase/Model/Behavior/SluggedBehaviorTest.php
Expand Up @@ -178,8 +178,6 @@ public function testFields() {
}

/**
* Tests needSlugUpdate()
*
* @return void
*/
public function testNeedsSlugUpdate() {
Expand Down Expand Up @@ -228,6 +226,27 @@ public function testNeedsSlugUpdate() {
$this->assertEquals('Some-really-other-title', $result->get('slug'));
}

/**
* @return void
*/
public function testNeedsNoSlugUpdate() {
$entity = $this->articles->newEntity(['title' => 'Some title']);
$result = $this->articles->save($entity);
$this->assertEquals('Some-title', $result->get('slug'));

$entity = $this->articles->get($entity->id, ['fields' => ['id', 'slug']]);

$this->articles->behaviors()->Slugged->setConfig(['overwrite' => true]);
// Without title present it should not modify the slug
$entity = $this->articles->patchEntity($entity, ['foo' => 'bar']);
$result = $this->articles->needsSlugUpdate($entity);
$this->assertFalse($result);

$this->articles->saveOrFail($entity);
$entity = $this->articles->get($entity->id);
$this->assertEquals('Some-title', $entity->get('slug'));
}

/**
* Tests needSlugUpdate() with deep
*
Expand Down

0 comments on commit 0da38f2

Please sign in to comment.