Permalink
Browse files

Add the Position option to Sluggable

  • Loading branch information...
1 parent 9dedea9 commit c608bb6c9d0ab99ab2d8d513f00fb82274f55f80 Clément Jobeili committed Apr 13, 2011
@@ -14,7 +14,9 @@
* @link http://www.gediminasm.org
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
-final class Sluggable extends Annotation {}
+final class Sluggable extends Annotation {
+ public $position = 0;
+}
final class Slug extends Annotation {
public $updatable = true;
public $style = 'default'; // or "camel"
@@ -76,7 +76,7 @@ public function readExtendedMetadata($meta, array &$config) {
if (!$this->isValidField($meta, $field)) {
throw new InvalidMappingException("Cannot slug field - [{$field}] type is not valid and must be 'string' in class - {$meta->name}");
}
- $config['fields'][] = $field;
+ $config['fields'][] = array('field' => $field, 'position' => $sluggable->position);
}
// slug property
if ($slug = $reader->getPropertyAnnotation($property, self::ANNOTATION_SLUG)) {
@@ -55,11 +55,13 @@ public function readExtendedMetadata($meta, array &$config) {
if (isset($mapping['fields'])) {
foreach ($mapping['fields'] as $field => $fieldMapping) {
if (isset($fieldMapping['gedmo'])) {
+
if (in_array('sluggable', $fieldMapping['gedmo'])) {
if (!$this->isValidField($meta, $field)) {
throw new InvalidMappingException("Cannot slug field - [{$field}] type is not valid and must be 'string' in class - {$meta->name}");
- }
- $config['fields'][] = $field;
+ }//var_dump($fieldMapping['gedmo']);
+ $sluggable = $fieldMapping['gedmo'][array_search('sluggable', $fieldMapping['gedmo'])];
+ $config['fields'][] = array('field' => $field, 'position' => $sluggable['position']);
} elseif (isset($fieldMapping['gedmo']['slug']) || in_array('slug', $fieldMapping['gedmo'])) {
$slug = $fieldMapping['gedmo']['slug'];
if (!$this->isValidField($meta, $field)) {
@@ -19,8 +19,21 @@
/**
* @gedmo:Sluggable
+ * available options:
+ * position(optional, default=0) - the position of the property in the slug
* to mark the field as sluggable use property annotation @gedmo:Sluggable
* this field value will be included in built slug
+ *
+ * example:
+ *
+ * @gedmo:Sluggable(position=1)
+ * @Column(type="string", length=64)
+ * $property
+ *
+ * @gedmo:Sluggable(position=0)
+ * @Column(type="string", length=64)
+ * $property2
+ *
*/
/**
@@ -150,11 +150,20 @@ protected function generateSlug(SluggableAdapter $ea, $object, $changeSet)
// collect the slug from fields
$slug = '';
$needToChangeSlug = false;
- foreach ($config['fields'] as $sluggableField) {
- if ($changeSet === false || isset($changeSet[$sluggableField])) {
+ $fields = $config['fields'];
+
+ usort($fields, function($a, $b){
+ if ($a['position'] == $b['position']) {
+ return 1;
+ }
+ return ($a['position'] < $b['position']) ? -1 : 1;
+ });
+
+ foreach ($fields as $sluggableField) {
+ if ($changeSet === false || isset($changeSet[$sluggableField['field']])) {
$needToChangeSlug = true;
}
- $slug .= $meta->getReflectionProperty($sluggableField)->getValue($object) . ' ';
+ $slug .= $meta->getReflectionProperty($sluggableField['field'])->getValue($object) . ' ';
}
// if slug is not changed, no need further processing
if (!$needToChangeSlug) {
@@ -65,7 +65,7 @@ public function testYamlMapping()
$this->assertEquals('slug', $config['slug']);
$this->assertArrayHasKey('fields', $config);
$this->assertEquals(1, count($config['fields']));
- $this->assertEquals('title', $config['fields'][0]);
+ $this->assertEquals('title', $config['fields'][0]['field']);
$this->assertArrayHasKey('style', $config);
$this->assertEquals('camel', $config['style']);
$this->assertArrayHasKey('separator', $config);
@@ -0,0 +1,62 @@
+<?php
+
+namespace Sluggable\Fixture;
+
+use Gedmo\Sluggable\Sluggable;
+
+/**
+ * @Entity
+ */
+class Post implements Sluggable
+{
+ /** @Id @GeneratedValue @Column(type="integer") */
+ private $id;
+
+ /**
+ * @gedmo:Sluggable(position=1)
+ * @Column(name="title", type="string", length=64)
+ */
+ private $title;
+
+ /**
+ * @gedmo:Sluggable(position=0)
+ * @Column(name="code", type="string", length=16)
+ */
+ private $code;
+
+ /**
+ * @gedmo:Slug
+ * @Column(name="slug", type="string", length=64, unique=true)
+ */
+ private $slug;
+
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ public function setTitle($title)
+ {
+ $this->title = $title;
+ }
+
+ public function getTitle()
+ {
+ return $this->title;
+ }
+
+ public function setCode($code)
+ {
+ $this->code = $code;
+ }
+
+ public function getCode()
+ {
+ return $this->code;
+ }
+
+ public function getSlug()
+ {
+ return $this->slug;
+ }
+}
@@ -5,6 +5,7 @@
use Doctrine\Common\EventManager;
use Tool\BaseTestCaseORM;
use Doctrine\Common\Util\Debug,
+ Sluggable\Fixture\Post,
Sluggable\Fixture\Article;
/**
@@ -18,6 +19,8 @@
class SluggableTest extends BaseTestCaseORM
{
const ARTICLE = 'Sluggable\\Fixture\\Article';
+ const POST = 'Sluggable\\Fixture\\Post';
+
private $articleId;
protected function setUp()
@@ -52,6 +55,18 @@ public function testUniqueSlugGeneration()
$this->assertEquals($article->getSlug(), 'the-title-my-code-' . ($i + 1));
}
}
+
+ public function testPositionedSlugGeneration()
+ {
+ $post = new Post();
+ $post->setTitle('the title');
+ $post->setCode('my code');
+
+ $this->em->persist($post);
+ $this->em->flush();
+ $this->em->clear();
+ $this->assertEquals($post->getSlug(), 'my-code-the-title');
+ }
public function testUniqueSlugLimit()
{
@@ -115,6 +130,7 @@ protected function getUsedEntityFixtures()
{
return array(
self::ARTICLE,
+ self::POST
);
}

0 comments on commit c608bb6

Please sign in to comment.