Skip to content

Commit

Permalink
Merge pull request #1650 from cmfcmf/unique-trees-2.4
Browse files Browse the repository at this point in the history
[2.4] Fix unique slugs with the TreeSlugHandler
  • Loading branch information
l3pp4rd authored Aug 30, 2016
2 parents dcaab46 + d7fac63 commit b818880
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Gedmo\Sluggable\Handler;

use Gedmo\Sluggable\Mapping\Event\SluggableAdapter;

/**
* This adds the ability to a SlugHandler to change the slug just before its
* uniqueness is ensured. It is also called if the unique options is _not_
* set.
*
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
interface SlugHandlerWithUniqueCallbackInterface extends SlugHandlerInterface
{
/**
* Callback for slug handlers before it is made unique
*
* @param SluggableAdapter $ea
* @param array $config
* @param object $object
* @param string $slug
*
* @return void
*/
public function beforeMakingUnique(SluggableAdapter $ea, array &$config, $object, &$slug);
}
10 changes: 8 additions & 2 deletions lib/Gedmo/Sluggable/Handler/TreeSlugHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class TreeSlugHandler implements SlugHandlerInterface
class TreeSlugHandler implements SlugHandlerWithUniqueCallbackInterface
{
const SEPARATOR = '/';

Expand Down Expand Up @@ -128,10 +128,16 @@ public static function validate(array $options, ClassMetadata $meta)
/**
* {@inheritDoc}
*/
public function onSlugCompletion(SluggableAdapter $ea, array &$config, $object, &$slug)
public function beforeMakingUnique(SluggableAdapter $ea, array &$config, $object, &$slug)
{
$slug = $this->transliterate($slug, $config['separator'], $object);
}

/**
* {@inheritDoc}
*/
public function onSlugCompletion(SluggableAdapter $ea, array &$config, $object, &$slug)
{
if (!$this->isInsert) {
$wrapped = AbstractWrapper::wrap($object, $this->om);
$meta = $wrapped->getMetadata();
Expand Down
11 changes: 11 additions & 0 deletions lib/Gedmo/Sluggable/SluggableListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Doctrine\Common\EventArgs;
use Gedmo\Mapping\MappedEventSubscriber;
use Gedmo\Sluggable\Handler\SlugHandlerWithUniqueCallbackInterface;
use Gedmo\Sluggable\Mapping\Event\SluggableAdapter;
use Doctrine\Common\Persistence\ObjectManager;
use Gedmo\Tool\Wrapper\AbstractWrapper;
Expand Down Expand Up @@ -384,6 +385,16 @@ private function generateSlug(SluggableAdapter $ea, $object)
$slug = null;
}

// notify slug handlers --> beforeMakingUnique
if ($hasHandlers) {
foreach ($options['handlers'] as $class => $handlerOptions) {
$handler = $this->getHandler($class);
if ($handler instanceof SlugHandlerWithUniqueCallbackInterface) {
$handler->beforeMakingUnique($ea, $options, $object, $slug);
}
}
}

// make unique slug if requested
if ($options['unique'] && null !== $slug) {
$this->exponent = 0;
Expand Down
71 changes: 71 additions & 0 deletions tests/Gedmo/Sluggable/Handlers/TreeSlugHandlerUniqueTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

namespace Gedmo\Sluggable;

use Doctrine\Common\EventManager;
use Gedmo\Tree\TreeListener;
use Sluggable\Fixture\Handler\TreeSlug;
use Tool\BaseTestCaseORM;

class TreeSlugHandlerUniqueTest extends BaseTestCaseORM
{
const TARGET = "Sluggable\\Fixture\\Handler\\TreeSlug";

protected function setUp()
{
parent::setUp();

$evm = new EventManager();
$evm->addEventSubscriber(new SluggableListener());
$evm->addEventSubscriber(new TreeListener());

$this->getMockSqliteEntityManager($evm);
}

public function testUniqueRoot()
{
$foo1 = new TreeSlug();
$foo1->setTitle('Foo');

$foo2 = new TreeSlug();
$foo2->setTitle('Foo');

$this->em->persist($foo1);
$this->em->persist($foo2);

$this->em->flush();

$this->assertEquals('foo', $foo1->getSlug());
$this->assertEquals('foo-1', $foo2->getSlug());
}

public function testUniqueLeaf()
{
$root = new TreeSlug();
$root->setTitle('root');

$foo1 = new TreeSlug();
$foo1->setTitle('Foo');
$foo1->setParent($root);

$foo2 = new TreeSlug();
$foo2->setTitle('Foo');
$foo2->setParent($root);

$this->em->persist($root);
$this->em->persist($foo1);
$this->em->persist($foo2);

$this->em->flush();

$this->assertEquals('root/foo', $foo1->getSlug());
$this->assertEquals('root/foo-1', $foo2->getSlug());
}

protected function getUsedEntityFixtures()
{
return array(
self::TARGET,
);
}
}

0 comments on commit b818880

Please sign in to comment.