7

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

我做这个:

作曲家.json

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

应用内核.php

new Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle(),

应用程序/配置/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。你有想法吗?

谢谢

4

4 回答 4

7

要更改 slug,您必须更改相关属性。您可以在末尾添加一个空格$titre,将其保存,将其更改回来并再次保存。这将冲洗蛞蝓。

于 2014-10-17T14:04:29.883 回答
4
$uow = $em->getUnitOfWork();    
$uow->propertyChanged($entity, 'slug', NULL, NULL);    
$uow->scheduleForUpdate($entity);    
$em->flush();
于 2016-08-05T14:14:21.837 回答
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:忽略第二条语句的失败

如果您忽略该错误,然后尝试使用记录的方法手动生成 slug,$entity->setSlug(null)一切都会正常工作。它会起作用,因为通过使用$entity->setSlug(null)你会让 Doctrine 知道属性slug已更改(从''to 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 和扩展的内部工作原理。

于 2017-03-30T17:31:33.057 回答
2

sluggable文档说明如下:

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

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

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

它对我有用。

于 2016-10-18T13:41:41.167 回答