Browse Source

[sluggable] merged @dator sluggable position into master, pr #37

Gediminas Morkevicius 14 years ago
parent
commit
2a13d90ad3

+ 2 - 1
README.markdown

@@ -63,7 +63,8 @@ To setup and run tests follow these steps:
 
 ### Contributors:
 
-- [xanf](http://github.com/xanf)
+- Clément JOBEILI [dator](http://github.com/dator)
+- Illya Klymov [xanf](http://github.com/xanf)
 - Gustavo Adrian [comfortablynumb](http://github.com/comfortablynumb)
 - Boussekeyt Jules [gordonslondon](http://github.com/gordonslondon)
 - Christophe Coevoet [stof](http://github.com/stof)

+ 1 - 1
lib/Gedmo/Mapping/Annotation/Sluggable.php

@@ -15,6 +15,6 @@ use Doctrine\Common\Annotations\Annotation;
  */
 final class Sluggable extends Annotation
 {
-
+    public $position = 0;
 }
 

+ 1 - 1
lib/Gedmo/Sluggable/Mapping/Driver/Annotation.php

@@ -77,7 +77,7 @@ class Annotation implements Driver
                 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::SLUG)) {

+ 3 - 1
lib/Gedmo/Sluggable/Mapping/Driver/Yaml.php

@@ -56,11 +56,13 @@ class Yaml extends File implements Driver
         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;
+                        $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)) {

+ 12 - 3
lib/Gedmo/Sluggable/SluggableListener.php

@@ -149,14 +149,23 @@ class SluggableListener extends MappedEventSubscriber
         $uow = $om->getUnitOfWork();
         $config = $this->getConfiguration($om, $meta->name);
 
+        // sort sluggable fields by position
+        $fields = $config['fields'];
+        usort($fields, function($a, $b) {
+            if ($a['position'] == $b['position']) {
+                return 1;
+            }
+            return ($a['position'] < $b['position']) ? -1 : 1;
+        });
+
         // collect the slug from fields
         $slug = '';
         $needToChangeSlug = false;
-        foreach ($config['fields'] as $sluggableField) {
-            if ($changeSet === false || isset($changeSet[$sluggableField])) {
+        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) {

+ 7 - 7
tests/Gedmo/Mapping/SluggableMappingTest.php

@@ -10,7 +10,7 @@ use Doctrine\Common\Util\Debug,
 
 /**
  * These are mapping tests for sluggable extension
- * 
+ *
  * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
  * @package Gedmo.Mapping
  * @link http://www.gediminasm.org
@@ -22,7 +22,7 @@ class SluggableMappingTest extends \PHPUnit_Framework_TestCase
     private $em;
 
     public function setUp()
-    {        
+    {
         $config = new \Doctrine\ORM\Configuration();
         $config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
         $config->setQueryCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
@@ -30,7 +30,7 @@ class SluggableMappingTest extends \PHPUnit_Framework_TestCase
         $config->setProxyNamespace('Gedmo\Mapping\Proxy');
         $chainDriverImpl = new DriverChain;
         $chainDriverImpl->addDriver(
-            new YamlDriver(array(__DIR__ . '/Driver/Yaml')), 
+            new YamlDriver(array(__DIR__ . '/Driver/Yaml')),
             'Mapping\Fixture\Yaml'
         );
         $config->setMetadataDriverImpl($chainDriverImpl);
@@ -41,7 +41,7 @@ class SluggableMappingTest extends \PHPUnit_Framework_TestCase
         );
 
         //$config->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger());
-        
+
         $evm = new \Doctrine\Common\EventManager();
         $evm->addEventSubscriber(new SluggableListener());
         $this->em = \Doctrine\ORM\EntityManager::create($conn, $config, $evm);
@@ -52,12 +52,12 @@ class SluggableMappingTest extends \PHPUnit_Framework_TestCase
             $this->em->getClassMetadata(self::TEST_YAML_ENTITY_CLASS)
         ));
     }
-    
+
     public function testYamlMapping()
     {
         $meta = $this->em->getClassMetadata(self::TEST_YAML_ENTITY_CLASS);
         $cacheId = ExtensionMetadataFactory::getCacheId(
-            self::TEST_YAML_ENTITY_CLASS, 
+            self::TEST_YAML_ENTITY_CLASS,
             'Gedmo\Sluggable'
         );
         $config = $this->em->getMetadataFactory()->getCacheDriver()->fetch($cacheId);
@@ -65,7 +65,7 @@ class SluggableMappingTest extends \PHPUnit_Framework_TestCase
         $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);

+ 46 - 0
tests/Gedmo/Sluggable/Fixture/Position.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace Sluggable\Fixture;
+
+/**
+ * @Entity
+ */
+class Position
+{
+    /**
+     * @Id
+     * @GeneratedValue
+     * @Column(type="integer")
+     */
+    private $id;
+
+    /**
+     * @gedmo:Sluggable(position=2)
+     * @Column(length=16)
+     */
+    private $prop;
+
+    /**
+     * @gedmo:Sluggable(position=1)
+     * @Column(length=64)
+     */
+    private $title;
+
+    /**
+     * @gedmo:Sluggable
+     * @Column(length=16)
+     */
+    private $code;
+
+    /**
+     * @gedmo:Sluggable(position=0)
+     * @Column(length=16)
+     */
+    private $other;
+
+    /**
+     * @gedmo:Slug
+     * @Column(length=64, unique=true)
+     */
+    private $slug;
+}

+ 61 - 0
tests/Gedmo/Sluggable/SluggablePositionTest.php

@@ -0,0 +1,61 @@
+<?php
+
+namespace Gedmo\Sluggable;
+
+use Doctrine\Common\EventManager;
+use Tool\BaseTestCaseORM;
+use Sluggable\Fixture\Position;
+
+/**
+ * These are tests for Sluggable behavior
+ *
+ * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
+ * @package Gedmo.Sluggable
+ * @link http://www.gediminasm.org
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class SluggablePositionTest extends BaseTestCaseORM
+{
+    const POSITION = 'Sluggable\\Fixture\\Position';
+
+    protected function setUp()
+    {
+        parent::setUp();
+
+        $evm = new EventManager;
+        $evm->addEventSubscriber(new SluggableListener);
+
+        $this->getMockSqliteEntityManager($evm);
+        $this->populate();
+    }
+
+    public function testPositionedSlugOrder()
+    {
+        $meta = $this->em->getClassMetadata(self::POSITION);
+        $repo = $this->em->getRepository(self::POSITION);
+
+        $object = $repo->find(1);
+        $slug = $meta->getReflectionProperty('slug')->getValue($object);
+        $this->assertEquals('code-other-title-prop', $slug);
+    }
+
+    protected function getUsedEntityFixtures()
+    {
+        return array(
+            self::POSITION,
+        );
+    }
+
+    private function populate()
+    {
+        $meta = $this->em->getClassMetadata(self::POSITION);
+        $object = new Position;
+        $meta->getReflectionProperty('title')->setValue($object, 'title');
+        $meta->getReflectionProperty('prop')->setValue($object, 'prop');
+        $meta->getReflectionProperty('code')->setValue($object, 'code');
+        $meta->getReflectionProperty('other')->setValue($object, 'other');
+
+        $this->em->persist($object);
+        $this->em->flush();
+    }
+}