Symfony 2 - 用Gedmo \ Slug生成S ..

时间:2014-10-17 13:39:16

标签: symfony stofdoctrineextensions

我刚刚安装了学说扩展以使用Sluggable。

我做到了:

composer.json

"stof/doctrine-extensions-bundle": "1.2.*@dev"

AppKernel.php

new Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle(),

应用程序/配置/ config.yml

stof_doctrine_extensions:
    orm:
        default:
            sluggable: true

Djoo \ AppliBundle \实体\ Nomenclature.php

namespace Djoo\AppliBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\DBAL\Types\SmallIntType;
use Gedmo\Mapping\Annotation as Gedmo;

/**
 * Nomenclature
 *
 * 
 * @ORM\Table(name="app_nomenclature")
 * @ORM\Entity
 */
class Nomenclature
{
    .....
    /**
     * @var string
     *
     * @ORM\Column(name="titre", type="string", length=200, nullable=false)
     */
    private $titre;

    /**
     * @var string
     *
     * @ORM\Column(name="finess", type="string", length=10, nullable=true)
     */
    private $finess;

    /**
     * @Gedmo\Slug(fields={"titre","finess"},suffix=".html")
     * @ORM\Column(length=128, unique=true,nullable=true)
     */
    private $slug;

    public function getSlug() {
        return $this->slug;
    }

    public function setSlug($slug){
        $this->slug = $slug;
        return $this;
    }

}

在我的控制器中,我使用它来为我的数据表中的旧值生成slug:

$filterBuilder = $this->get('doctrine.orm.entity_manager')>getRepository('DjooAppliBundle:Nomenclature')->createQueryBuilder('e')->orderBy('e.titre', 'asc');
$query = $filterBuilder->getQuery();
$nomenclatures = $query->getResult();

foreach($nomenclatures as $nomenclaturee){
    $nomenclature->setSlug(null);
    $this->get('doctrine.orm.entity_manager')->persist($nomenclature);
    $this->get('doctrine.orm.entity_manager')->flush();
 }

我没有错误,但我的旧值是一个空的slu ..我尝试创建一个新元素,我有一个很好的slug。你有想法吗?

由于

4 个答案:

答案 0 :(得分:7)

要更改slug,您必须更改相关属性。您可以在$titre的末尾添加空格,保存,更改并再次保存。这将冲洗slu ..

答案 1 :(得分:2)

$uow = $em->getUnitOfWork();    
$uow->propertyChanged($entity, 'slug', NULL, NULL);    
$uow->scheduleForUpdate($entity);    
$em->flush();

答案 2 :(得分:2)

sluggable documentation声明如下:

  

如果你想让slug基于sluggable重新生成自己的话   字段,将slug设置为null。

<?php
$entity = $em->find('Entity\Something', $id);
$entity->setSlug(null);

$em->persist($entity);
$em->flush();

它对我有用。

答案 3 :(得分:2)

为什么它不适用于OP,但适用于其他人(例如@gregor):

创建slug时,您的第一直觉是使用此列配置创建slug属性:

 ..    

 @ORM\Column(unique=true, nullable=false)
 private $slug;
 ..

运行app/console doctrine:schema:update时会产生2个sql语句:

ALTER TABLE ... ADD slug ... NOT NULL
CREATE UNIQUE INDEX...`. 

默认情况下,列slug将填充值''(空字符串),这将使第二个语句失败并显示(Duplicate entry '')错误。现在你有两个选择:

选择A:忽略第二个陈述的失败

如果忽略错误,稍后尝试使用记录的方法$entity->setSlug(null)手动生成slugs,一切都会正常工作。它会起作用,因为通过使用$entity->setSlug(null),您可以让Doctrine知道属性slug已更改(从''更改为null),这反过来会在内部触发{{1} }和$uow->propertyChanged()(感谢@Sebastian Radu的榜样)。 $uow->scheduleForUpdate()扩展名也会注意到此更改,并会重新生成slug。现在所有的slug都是唯一的,下次运行Sluggable时,它会成功在app/console doc:schema:update上创建索引,并且您的架构将完全同步。

选择B:将slug字段修改为slug 在注意到错误后,您的直觉是将nullable字段标记为slug,以便创建索引成功:

nullable

这会导致 .. @ORM\Column(unique=true, nullable=true) private $slug; .. 列的slug作为默认值。现在,当您尝试使用记录的NULL方法时,它将无法正常工作(就像OP发布的那样)。这是因为当$entity->setSlug(null)属性已经$entity->slug时。因此,当您使用NULL时,Doctrine不会检测到任何更改,因此永远不会触发$entity->setSlug(null)重生行为。为了触发更改,有两个答案:

  • 黑客为slug源属性添加空间Sluggable(但这会导致额外的空间,你必须修剪)

  • 接近@Sebastian Radu,在那里他展示了如何直接告诉Doctrine该领域已被改变(我个人更喜欢这个并且想知道为什么它被不公平地投票)

希望这有助于您更好地理解Doctrine和扩展的内部运作。