|
@@ -1,184 +0,0 @@
|
|
|
-<?php
|
|
|
-
|
|
|
-namespace Gedmo\Sluggable\Handler;
|
|
|
-
|
|
|
-use Doctrine\Common\Persistence\ObjectManager;
|
|
|
-use Gedmo\Sluggable\SluggableListener;
|
|
|
-use Gedmo\Sluggable\Mapping\Event\SluggableAdapter;
|
|
|
-use Gedmo\Tool\Wrapper\AbstractWrapper;
|
|
|
-use Gedmo\Exception\InvalidMappingException;
|
|
|
-use Gedmo\Sluggable\Util\Urlizer;
|
|
|
-
|
|
|
-/**
|
|
|
-* Sluggable handler which slugs all parent nodes
|
|
|
-* recursively and synchronizes on updates. For instance
|
|
|
-* category tree slug could look like "food/fruits/apples"
|
|
|
-*
|
|
|
-* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
|
|
|
-* @package Gedmo.Sluggable.Handler
|
|
|
-* @subpackage TreeSlugHandler
|
|
|
-* @link http://www.gediminasm.org
|
|
|
-* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
|
|
-*/
|
|
|
-class TreeSlugHandler implements SlugHandlerInterface
|
|
|
-{
|
|
|
- const SEPARATOR = '/';
|
|
|
-
|
|
|
- /**
|
|
|
- * @var Doctrine\Common\Persistence\ObjectManager
|
|
|
- */
|
|
|
- protected $om;
|
|
|
-
|
|
|
- /**
|
|
|
- * @var Gedmo\Sluggable\SluggableListener
|
|
|
- */
|
|
|
- protected $sluggable;
|
|
|
-
|
|
|
- /**
|
|
|
- * Callable of original transliterator
|
|
|
- * which is used by sluggable
|
|
|
- *
|
|
|
- * @var callable
|
|
|
- */
|
|
|
- private $originalTransliterator;
|
|
|
-
|
|
|
- /**
|
|
|
- * True if node is being inserted
|
|
|
- *
|
|
|
- * @var boolean
|
|
|
- */
|
|
|
- private $isInsert = false;
|
|
|
-
|
|
|
- /**
|
|
|
- * Transliterated parent slug
|
|
|
- *
|
|
|
- * @var string
|
|
|
- */
|
|
|
- private $parentSlug;
|
|
|
-
|
|
|
- /**
|
|
|
- * Used path separator
|
|
|
- *
|
|
|
- * @var string
|
|
|
- */
|
|
|
- private $usedPathSeparator;
|
|
|
-
|
|
|
- /**
|
|
|
- * {@inheritDoc}
|
|
|
- */
|
|
|
- public function __construct(SluggableListener $sluggable)
|
|
|
- {
|
|
|
- $this->sluggable = $sluggable;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * {@inheritDoc}
|
|
|
- */
|
|
|
- public function onChangeDecision(SluggableAdapter $ea, $config, $object, &$slug, &$needToChangeSlug)
|
|
|
- {
|
|
|
- $this->om = $ea->getObjectManager();
|
|
|
- $this->isInsert = $this->om->getUnitOfWork()->isScheduledForInsert($object);
|
|
|
- $options = $config['handlers'][get_called_class()];
|
|
|
- $this->usedPathSeparator = isset($options['separator']) ? $options['separator'] : self::SEPARATOR;
|
|
|
- if (!$this->isInsert && !$needToChangeSlug) {
|
|
|
- $changeSet = $ea->getObjectChangeSet($this->om->getUnitOfWork(), $object);
|
|
|
- if (isset($changeSet[$options['parentRelationField']])) {
|
|
|
- $needToChangeSlug = true;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * {@inheritDoc}
|
|
|
- */
|
|
|
- public function postSlugBuild(SluggableAdapter $ea, array &$config, $object, &$slug)
|
|
|
- {
|
|
|
- $options = $config['handlers'][get_called_class()];
|
|
|
- $this->originalTransliterator = $this->sluggable->getTransliterator();
|
|
|
- $this->sluggable->setTransliterator(array($this, 'transliterate'));
|
|
|
- $this->parentSlug = '';
|
|
|
-
|
|
|
- $wrapped = AbstractWrapper::wrap($object, $this->om);
|
|
|
- if ($parent = $wrapped->getPropertyValue($options['parentRelationField'])) {
|
|
|
- $parent = AbstractWrapper::wrap($parent, $this->om);
|
|
|
- $this->parentSlug = $parent->getPropertyValue($config['slug']);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * {@inheritDoc}
|
|
|
- */
|
|
|
- public function handlesUrlization()
|
|
|
- {
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * {@inheritDoc}
|
|
|
- */
|
|
|
- public static function validate(array $options, $meta)
|
|
|
- {
|
|
|
- if (!$meta->isSingleValuedAssociation($options['parentRelationField'])) {
|
|
|
- throw new InvalidMappingException("Unable to find tree parent slug relation through field - [{$options['parentRelationField']}] in class - {$meta->name}");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * {@inheritDoc}
|
|
|
- */
|
|
|
- public function onSlugCompletion(SluggableAdapter $ea, array &$config, $object, &$slug)
|
|
|
- {
|
|
|
- if (!$this->isInsert) {
|
|
|
- $options = $config['handlers'][get_called_class()];
|
|
|
- $wrapped = AbstractWrapper::wrap($object, $this->om);
|
|
|
- $meta = $wrapped->getMetadata();
|
|
|
- $target = $wrapped->getPropertyValue($config['slug']);
|
|
|
- $config['pathSeparator'] = $this->usedPathSeparator;
|
|
|
- $ea->replaceRelative($object, $config, $target.$config['pathSeparator'], $slug);
|
|
|
- $uow = $this->om->getUnitOfWork();
|
|
|
- // update in memory objects
|
|
|
- foreach ($uow->getIdentityMap() as $className => $objects) {
|
|
|
- // for inheritance mapped classes, only root is always in the identity map
|
|
|
- if ($className !== $wrapped->getRootObjectName()) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- foreach ($objects as $object) {
|
|
|
- if (property_exists($object, '__isInitialized__') && !$object->__isInitialized__) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- $oid = spl_object_hash($object);
|
|
|
- $objectSlug = $meta->getReflectionProperty($config['slug'])->getValue($object);
|
|
|
- if (preg_match("@^{$target}{$config['pathSeparator']}@smi", $objectSlug)) {
|
|
|
- $objectSlug = str_replace($target, $slug, $objectSlug);
|
|
|
- $meta->getReflectionProperty($config['slug'])->setValue($object, $objectSlug);
|
|
|
- $ea->setOriginalObjectProperty($uow, $oid, $config['slug'], $objectSlug);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Transliterates the slug and prefixes the slug
|
|
|
- * by collection of parent slugs
|
|
|
- *
|
|
|
- * @param string $text
|
|
|
- * @param string $separator
|
|
|
- * @param object $object
|
|
|
- * @return string
|
|
|
- */
|
|
|
- public function transliterate($text, $separator, $object)
|
|
|
- {
|
|
|
- $slug = call_user_func_array(
|
|
|
- $this->originalTransliterator,
|
|
|
- array($text, $separator, $object)
|
|
|
- );
|
|
|
- // For tree slugs, we "urlize" each part of the slug before appending "/"
|
|
|
- $slug = Urlizer::urlize($slug, $separator);
|
|
|
- if (strlen($this->parentSlug)) {
|
|
|
- $slug = $this->parentSlug . $this->usedPathSeparator . $slug;
|
|
|
- }
|
|
|
- $this->sluggable->setTransliterator($this->originalTransliterator);
|
|
|
- return $slug;
|
|
|
- }
|
|
|
-}
|