Php 具有多重关系的Slug
我有三个实体,比如Php 具有多重关系的Slug,php,symfony,doctrine-orm,doctrine-extensions,stofdoctrineextensions,Php,Symfony,Doctrine Orm,Doctrine Extensions,Stofdoctrineextensions,我有三个实体,比如A,B和CA与B和C有两种多通关系。我想为a生成一个slug,由字段a.a、B.B和C.C组成。 目前,我可以使用a.a和B.B生成一个slug,使用以下代码: A类: <?php use Doctrine\ORM\Mapping as ORM; use Gedmo\Mapping\Annotation as Gedmo; /** * @ORM\Entity( * repositoryClass="AppBundle\Repository\AReposit
A
,B
和C
A
与B
和C
有两种多通关系。我想为a
生成一个slug,由字段a.a
、B.B
和C.C
组成。
目前,我可以使用a.a
和B.B
生成一个slug,使用以下代码:
A类:
<?php
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @ORM\Entity(
* repositoryClass="AppBundle\Repository\ARepository"
* )
*/
class A
{
/**
* @var integer
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*/
private $id;
/**
* @var string
* @ORM\Column(type="string")
*/
private $name;
/**
* @var B
* @ORM\ManyToOne(targetEntity="B")
*/
private $b;
/**
* @var C
* @ORM\ManyToOne(targetEntity="C")
*/
private $c;
/**
* @var string
* @ORM\Column(type="string", unique=true)
* @Gedmo\Slug(handlers={
* @Gedmo\SlugHandler(class="Gedmo\Sluggable\Handler\RelativeSlugHandler", options={
* @Gedmo\SlugHandlerOption(name="relationField", value="name"),
* @Gedmo\SlugHandlerOption(name="relationSlugField", value="alias"),
* @Gedmo\SlugHandlerOption(name="separator", value="-")
* })
* }, separator="-", updatable=true, fields={"name"})
*/
private $slug;
// ...
}
我已经用这个类解决了:
<?php
namespace App\Handler;
use Gedmo\Sluggable\Mapping\Event\SluggableAdapter;
use Gedmo\Tool\Wrapper\AbstractWrapper;
class SecondaryRelativeGedmoSlugHandler extends \Gedmo\Sluggable\Handler\RelativeSlugHandler
{
/**
* Used options
*
* @var array
*/
private $usedOptions;
/**
* Callable of original transliterator
* which is used by sluggable
*
* @var callable
*/
private $originalTransliterator;
/**
* {@inheritDoc}
*/
public function onChangeDecision(SluggableAdapter $ea, array &$config, $object, &$slug, &$needToChangeSlug)
{
$this->om = $ea->getObjectManager();
$isInsert = $this->om->getUnitOfWork()->isScheduledForInsert($object);
$this->usedOptions = $config['handlers'][get_called_class()];
if (!isset($this->usedOptions['separator'])) {
$this->usedOptions['separator'] = self::SEPARATOR;
}
if (!$isInsert && !$needToChangeSlug) {
$changeSet = $ea->getObjectChangeSet($this->om->getUnitOfWork(), $object);
if (isset($changeSet[$this->usedOptions['relationField']])) {
$needToChangeSlug = true;
}
}
}
/**
* {@inheritDoc}
*/
public function postSlugBuild(SluggableAdapter $ea, array &$config, $object, &$slug)
{
$this->originalTransliterator = $this->sluggable->getTransliterator();
$this->sluggable->setTransliterator(array($this, 'transliterate'));
}
/**
* Transliterates the slug and prefixes the slug
* by relative one
*
* @param string $text
* @param string $separator
* @param object $object
*
* @return string
*/
public function transliterate($text, $separator, $object)
{
// MIO
$result = call_user_func_array(
$this->originalTransliterator,
array($text, $separator, $object)
);
$tokens = explode('/', $result);
if(count($tokens) > 1) {
$result = $tokens[count($tokens) - 1];
}
$wrapped = AbstractWrapper::wrap($object, $this->om);
$relation = $wrapped->getPropertyValue($this->usedOptions['relationField']);
if ($relation) {
$wrappedRelation = AbstractWrapper::wrap($relation, $this->om);
$slug = $wrappedRelation->getPropertyValue($this->usedOptions['relationSlugField']);
if (isset($this->usedOptions['urilize']) && $this->usedOptions['urilize']) {
$slug = call_user_func_array(
$this->originalTransliterator,
array($slug, $separator, $object)
);
}
$result = $slug.$this->usedOptions['separator'].$result;
}
return $result;
}
}
<?php
namespace App\Handler;
use Gedmo\Sluggable\Mapping\Event\SluggableAdapter;
use Gedmo\Tool\Wrapper\AbstractWrapper;
class SecondaryRelativeGedmoSlugHandler extends \Gedmo\Sluggable\Handler\RelativeSlugHandler
{
/**
* Used options
*
* @var array
*/
private $usedOptions;
/**
* Callable of original transliterator
* which is used by sluggable
*
* @var callable
*/
private $originalTransliterator;
/**
* {@inheritDoc}
*/
public function onChangeDecision(SluggableAdapter $ea, array &$config, $object, &$slug, &$needToChangeSlug)
{
$this->om = $ea->getObjectManager();
$isInsert = $this->om->getUnitOfWork()->isScheduledForInsert($object);
$this->usedOptions = $config['handlers'][get_called_class()];
if (!isset($this->usedOptions['separator'])) {
$this->usedOptions['separator'] = self::SEPARATOR;
}
if (!$isInsert && !$needToChangeSlug) {
$changeSet = $ea->getObjectChangeSet($this->om->getUnitOfWork(), $object);
if (isset($changeSet[$this->usedOptions['relationField']])) {
$needToChangeSlug = true;
}
}
}
/**
* {@inheritDoc}
*/
public function postSlugBuild(SluggableAdapter $ea, array &$config, $object, &$slug)
{
$this->originalTransliterator = $this->sluggable->getTransliterator();
$this->sluggable->setTransliterator(array($this, 'transliterate'));
}
/**
* Transliterates the slug and prefixes the slug
* by relative one
*
* @param string $text
* @param string $separator
* @param object $object
*
* @return string
*/
public function transliterate($text, $separator, $object)
{
// MIO
$result = call_user_func_array(
$this->originalTransliterator,
array($text, $separator, $object)
);
$tokens = explode('/', $result);
if(count($tokens) > 1) {
$result = $tokens[count($tokens) - 1];
}
$wrapped = AbstractWrapper::wrap($object, $this->om);
$relation = $wrapped->getPropertyValue($this->usedOptions['relationField']);
if ($relation) {
$wrappedRelation = AbstractWrapper::wrap($relation, $this->om);
$slug = $wrappedRelation->getPropertyValue($this->usedOptions['relationSlugField']);
if (isset($this->usedOptions['urilize']) && $this->usedOptions['urilize']) {
$slug = call_user_func_array(
$this->originalTransliterator,
array($slug, $separator, $object)
);
}
$result = $slug.$this->usedOptions['separator'].$result;
}
return $result;
}
}
/**
* @Gedmo\Slug(handlers={
* @Gedmo\SlugHandler(class="Gedmo\Sluggable\Handler\RelativeSlugHandler", value="shop", options={
* @Gedmo\SlugHandlerOption(name="relationField", value="shop"),
* @Gedmo\SlugHandlerOption(name="relationSlugField", value="name"),
* @Gedmo\SlugHandlerOption(name="separator", value="/"),
* @Gedmo\SlugHandlerOption(name="urilize", value=true)
* }),
* @Gedmo\SlugHandler(class="App\Handler\SecondaryRelativeGedmoSlugHandler", value="category", options={
* @Gedmo\SlugHandlerOption(name="relationField", value="category"),
* @Gedmo\SlugHandlerOption(name="relationSlugField", value="name"),
* @Gedmo\SlugHandlerOption(name="separator", value="/"),
* @Gedmo\SlugHandlerOption(name="urilize", value=true)
* })
* },fields={"name"}, unique=true, updatable=true)
* @ORM\Column(type="string", length=255, unique=true)
*/
private $slug;