Browse Source

Enhance Slugged.

euromark 11 years ago
parent
commit
59b2918632

+ 16 - 5
src/Model/Behavior/SluggedBehavior.php

@@ -175,8 +175,8 @@ class SluggedBehavior extends Behavior {
 	 * @param Entity $entity
 	 * @return void
 	 */
-	public function slug(Entity $entity) {
-		$overwrite = $this->_config['overwrite'];
+	public function slug(Entity $entity, array $options = array()) {
+		$overwrite = isset($options['overwrite']) ? $options['overwrite'] : $this->_config['overwrite'];
 		if (!$overwrite && $entity->get($this->_config['overwriteField'])) {
 			$overwrite = true;
 		}
@@ -194,17 +194,27 @@ class SluggedBehavior extends Behavior {
 	}
 
 	/**
-	 * SluggedBehavior::_needsUpdating()
+	 * Method to find out if the current slug needs updating.
+	 *
+	 * The deep option is useful if you cannot rely on dirty() because
+	 * of maybe some not in sync slugs anymore (saving the same title again,
+	 * but the slug is completely different, for example).
 	 *
 	 * @param Entity $entity
+	 * @param bool $deep If true it will generate a new slug and compare it to the currently stored one.
 	 * @return bool
 	 */
-	protected function _needsUpdating($entity) {
+	public function needsSlugUpdate($entity, $deep = false) {
 		foreach ((array)$this->_config['label'] as $label) {
 			if ($entity->dirty($label)) {
 				return true;
 			}
 		}
+		if ($deep) {
+			$copy = clone $entity;
+			$this->slug($copy, ['overwrite' => true]);
+			return $copy->get($this->_config['field']) !== $entity->get($this->_config['field']);
+		}
 		return false;
 	}
 
@@ -214,6 +224,7 @@ class SluggedBehavior extends Behavior {
 	 * If a new row, or overwrite is set to true, check for a change to a label field and add the slug to the data
 	 * to be saved
 	 *
+	 * @deprecated Not in use anymore!
 	 * @return void
 	 */
 	public function _slug(Entity $entity) {
@@ -256,7 +267,6 @@ class SluggedBehavior extends Behavior {
 				$slug = $this->display($Model);
 			}
 			$slug = $Model->slug($slug);
-			$this->_addToWhitelist($Model, array($slugField));
 			$Model->data[$this->_table->alias()][$slugField] = $slug;
 		}
 	}
@@ -361,6 +371,7 @@ class SluggedBehavior extends Behavior {
 	 * to get the display name
 	 * Otherwise, read from the database
 	 *
+	 * @deprecated Not in use anymore!
 	 * @param mixed $id
 	 * @return mixed string (the display name) or false
 	 */

+ 92 - 3
tests/TestCase/Model/Behavior/SluggedBehaviorTest.php

@@ -112,6 +112,95 @@ class SluggedBehaviorTest extends TestCase {
 	}
 
 /**
+ * Test that fieldList doesnt mess with slug storing.
+ *
+ * @return void
+ */
+	public function testFieldList() {
+		// field list is only relevant for newEntity(), not for what the behavior does
+		$entity = $this->articles->newEntity(['title' => 'Some title'], ['fieldList' => ['title']]);
+
+		$result = $this->articles->save($entity);
+		$this->assertEquals('Some-title', $result->get('slug'));
+	}
+
+/**
+ * Tests needSlugUpdate()
+ *
+ * @return void
+ */
+	public function testNeedsSlugUpdate() {
+		// No title change
+		$entity = $this->articles->newEntity(['title' => 'Some title'], ['fieldList' => []]);
+		$result = $this->articles->needsSlugUpdate($entity);
+		$this->assertFalse($result);
+
+		// Title change
+		$entity = $this->articles->newEntity(['title' => 'Some title']);
+		$result = $this->articles->needsSlugUpdate($entity);
+		$this->assertTrue($result);
+
+		$result = $this->articles->save($entity);
+		$this->assertEquals('Some-title', $result->get('slug'));
+
+		// No title change
+		$entity = $this->articles->patchEntity($entity, ['description' => 'Foo bar']);
+		$result = $this->articles->needsSlugUpdate($entity);
+		$this->assertFalse($result);
+
+		// Needs an update, but overwrite is still false: will not modify the slug
+		$entity = $this->articles->patchEntity($entity, ['title' => 'Some other title']);
+		$result = $this->articles->needsSlugUpdate($entity);
+		$this->assertTrue($result);
+
+		$result = $this->articles->save($entity);
+		$this->assertEquals('Some-title', $result->get('slug'));
+
+		$this->articles->behaviors()->Slugged->config(['overwrite' => true]);
+		// Now it can modify the slug
+		$entity = $this->articles->patchEntity($entity, ['title' => 'Some really other title']);
+		$result = $this->articles->needsSlugUpdate($entity);
+		$this->assertTrue($result);
+
+		$result = $this->articles->save($entity);
+		$this->assertEquals('Some-really-other-title', $result->get('slug'));
+	}
+
+/**
+ * Tests needSlugUpdate() with deep
+ *
+ * @return void
+ */
+	public function testNeedsSlugUpdateDeep() {
+		// No title change
+		$entity = $this->articles->newEntity(['title' => 'Some title']);
+		$result = $this->articles->needsSlugUpdate($entity);
+		$this->assertTrue($result);
+		$result = $this->articles->needsSlugUpdate($entity, true);
+		$this->assertTrue($result);
+
+		$result = $this->articles->save($entity);
+		$this->assertEquals('Some-title', $result->get('slug'));
+
+		// Needs an update, but overwrite is still false: will not modify the slug
+		$entity = $this->articles->patchEntity($entity, ['title' => 'Some other title']);
+		$result = $this->articles->needsSlugUpdate($entity);
+		$this->assertTrue($result);
+		$result = $this->articles->needsSlugUpdate($entity, true);
+		$this->assertTrue($result);
+
+		$result = $this->articles->save($entity);
+		$this->assertEquals('Some-title', $result->get('slug'));
+
+		// Here deep would tell the truth
+		$entity = $this->articles->patchEntity($entity, ['title' => 'Some other title']);
+		$result = $this->articles->needsSlugUpdate($entity);
+		$this->assertFalse($result);
+		$result = $this->articles->needsSlugUpdate($entity, true);
+		$this->assertTrue($result);
+	}
+
+/**
  * Length based on auto-detect of schema.
  *
  * @return void
@@ -427,7 +516,7 @@ class SluggedBehaviorTest extends TestCase {
 		$result = $this->articles->save($article);
 		$this->assertEquals('Some-Cool-String', $result['slug']);
 
-		$this->articles->patchEntity($article, ['title' => 'Some Cool Other String']);
+		$this->articles->patchEntity($article, ['title' => 'Some Cool Other String', 'overwrite_my_slug' => false]);
 		$result = $this->articles->save($article);
 		$this->assertEquals('Some-Cool-String', $result['slug']);
 
@@ -473,10 +562,10 @@ class SluggedBehaviorTest extends TestCase {
  *
  * @return Entity
  */
-	protected function _getEntity($title = 'test 123', $field = 'title') {
+	protected function _getEntity($title = 'test 123', $field = 'title', array $options = array()) {
 		return new Entity([
 			$field => $title
-		]);
+		], $options);
 	}
 
 }