【问题标题】:Symfony 2 - Generate Slugs with Gedmo\SlugSymfony 2 - 使用 Gedmo\Slug 生成 Slug
【发布时间】:2014-10-17 13:39:16
【问题描述】:

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

我做这个:

composer.json

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

AppKernel.php

new Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle(),

app/config/config.yml

stof_doctrine_extensions:
    orm:
        default:
            sluggable: true

Djoo\AppliBundle\Entity\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();
 }

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

谢谢

【问题讨论】:

  • 我认为 slug 只会为新持久化的对象生成。

标签: symfony stofdoctrineextensions


【解决方案1】:

要更改 slug,您必须更改相关属性。你可以在$titre末尾加个空格,保存,改回来再保存。这将冲洗鼻涕虫。

【讨论】:

  • 是的,谢谢 $entity = $em->getRepository($entityName)->find($id); $titre = $entity->getTitre(); $entity -> setSlug(null); $entity -> setTitre($titre." "); $em->flush();
  • 它对我不起作用。我不得不根据stackoverflow.com/a/18672588/1179841 手动重新生成 slug
【解决方案2】:
$uow = $em->getUnitOfWork();    
$uow->propertyChanged($entity, 'slug', NULL, NULL);    
$uow->scheduleForUpdate($entity);    
$em->flush();

【讨论】:

  • 这对我有用,我想知道为什么它有 -1 ????。我刚刚添加了+1。另请记住,您可能需要将ObjectManager 输入到EntityManager 以便您可以获得getUnitOfWork() 的代码完成:/** @var ObjectManager|EntityManager $em */
【解决方案3】:

为什么它不适用于 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) 手动生成 slug,一切都会正常工作。它会起作用,因为通过使用 $entity->setSlug(null),您会让 Doctrine 知道 propertyslug 已更改(从 ''null),这反过来会在内部触发 $uow->propertyChanged()$uow->scheduleForUpdate()(感谢 @Sebastian Radu 为他的例子)。 Sluggable 扩展也会注意到这一变化,并将重新生成 slug。现在所有 slug 都是唯一的,下次您运行 app/console doc:schema:update 时,它将成功在 slug 上创建索引,并且您的架构将完全同步。

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

 ..    

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

这将导致slug 列将NULL 作为默认值。现在,当您尝试使用记录在案的 $entity->setSlug(null) 方法时,它不会起作用(就像 OP 发布的那样)。这是因为当$entity->slug 属性已经是NULL 时。因此,当您使用 $entity->setSlug(null) 时,Doctrine 不会检测到任何更改,因此永远不会触发 Sluggable 再生行为。为了触发更改,有两个答案:

  • 在 slug 源属性 $entity -> setTitre($titre." "); 中添加空间(但这会导致您必须在之后修剪额外的空间)

  • @Sebastian Radu 的方法,他展示了如何直接告诉 Doctrine 该字段已更改(我个人更喜欢这个并想知道为什么它被不公平地否决了)

希望这可以帮助您更好地了解 Doctrine 和扩展的内部工作原理。

【讨论】:

    【解决方案4】:

    sluggable documentation 声明如下:

    如果您希望 slug 基于 sluggable 重新生成自身 字段,将 slug 设置为 null。

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

    它确实对我有用。

    【讨论】:

    • 对我不起作用。字段注解是这样的@ORM\Column(name="slug", unique=true, nullable=true)@Gedmo\Slug(fields={"name","city"}, updatable=true)
    猜你喜欢
    • 2019-03-10
    • 1970-01-01
    • 2020-01-19
    • 2018-04-17
    • 2014-12-09
    • 2015-08-21
    • 2013-09-11
    • 2011-04-21
    • 2011-06-20
    相关资源
    最近更新 更多