【问题标题】:configure blameable doctrine extension with symfony2使用 symfony2 配置可责备的学说扩展
【发布时间】:2015-05-05 14:53:31
【问题描述】:

谁能提供 Blameable Gedmo 扩展的完整示例,尤其是 Blameable Listener 的配置?

我正在使用文档提供的代码:

 * @var User $createdBy
 *
 * @Gedmo\Blameable(on="create")
 * @ORM\ManyToOne(targetEntity="Cf\UserBundle\Entity\User")
 * @ORM\JoinColumn(name="createdBy", referencedColumnName="id")
 */
private $createdBy;

/**
 * @var User $updatedBy
 *
 * @Gedmo\Blameable(on="update")
 * @ORM\ManyToOne(targetEntity="Cf\UserBundle\Entity\User")
 * @ORM\JoinColumn(name="updatedBy", referencedColumnName="id")
 */
private $updatedBy;

但 createdBy 和 updatedBy 数据库列始终为 NULL。

文档提供了配置其他侦听器的示例(例如,我开始工作的可时间戳记),但我找不到可指责的侦听器的示例或文档。

感谢您的帮助!!

================================================ ================

编辑回答让:

是的,我添加了以下用途:

use Gedmo\Mapping\Annotation as Gedmo;

我还将 Timestampable 与提供的特征一起使用:

use Gedmo\Timestampable\Traits\TimestampableEntity;

// doctrine comments removed
class Document
{
    use TimestampableEntity;
...
}

时间戳配置为:

services:
    gedmo.listener.timestampable:
        class: Gedmo\Timestampable\TimestampableListener
        tags:
            - { name: doctrine.event_subscriber, connection: default }
        calls:
            - [ setAnnotationReader, [ @annotation_reader ] ]

Timespmbable 工作得很好。 我为可指责的侦听器尝试了类似的配置,因为它有一个setUserValue 方法:

gedmo.listener.blameable:
    class: Gedmo\Blameable\BlameableListener
    tags:
        - { name: doctrine.event_subscriber, connection: default }
    calls:
        - [ setAnnotationReader, [ @annotation_reader ] ]
        - [ setUserValue, [ @security.token_storage ] ]

但它不起作用,我收到此错误(我的项目中使用了 4 个捆绑包):

在链配置的命名空间 Cf\UserBundle\Entity、Cf\DocumentBundle\Entity、Cf\SouffleBundle\Entity、FOS\ 中找不到类“Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage”用户包\模型

我知道它以某种方式缺少用户 ID 或安全令牌作为参数,但我无法在任何地方找到示例。 这就是我卡住的地方。有什么想法吗?

【问题讨论】:

  • 您是否将use 放在了班级的首位?你能给我们看看吗?
  • 此外,Blameable 仅在使用安全上下文创建\更新实体并包含用户令牌时才有效,该用户令牌已被考虑并保留在您的字段中。
  • 你使用https://github.com/stof/StofDoctrineExtensionsBundle吗?我有它和可责备的作品。
  • 你有没有得到这个工作?我也有类似的问题?
  • 你使用的是 Symfony >= 2.6 还是 Symfony github.com/Atlantic18/DoctrineExtensions/blob/master/doc/… 的说明添加 DoctrineExtensionsListener? (注意:此代码仅适用于 Symfony = 2.6,您必须更改 onKernelRequest 方法)

标签: php symfony doctrine-orm


【解决方案1】:

我还发现很难使用 StofDoctrineExtensionsBundle 启用 Blameable 行为(假设您正在使用它)。

该捆绑包中没有提到一项配置:

# Add in your app/config/config.yml
stof_doctrine_extensions:
    orm:
        default:
            blameable: true

除此之外,我还创建了一个 BlameableEntity 特征:

<?php

namespace AppBundle\Entity\Traits;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use AppBundle\Entity\User;

/**
 * Add Blameable behavior to an entity.
 */
trait BlameableEntity {

    /**
     * @var User
     *
     * @Gedmo\Blameable(on="create")
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
     * @ORM\JoinColumn(name="created_by", referencedColumnName="id")
     */
    protected $createdBy;

    /**
     * @var User
     *
     * @Gedmo\Blameable(on="update")
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
     * @ORM\JoinColumn(name="updated_by", referencedColumnName="id")
     */
    protected $updatedBy;

    /**
     * Set createdBy
     *
     * @param User $createdBy
     * @return Object
     */
    public function setCreatedBy(User $createdBy)
    {
        $this->createdBy = $createdBy;

        return $this;
    }

    /**
     * Get createdBy
     *
     * @return User
     */
    public function getCreatedBy()
    {
        return $this->createdBy;
    }

    /**
     * Set updatedBy
     *
     * @param User $updatedBy
     * @return Object
     */
    public function setUpdatedBy(User $updatedBy)
    {
        $this->updatedBy = $updatedBy;

        return $this;
    }

    /**
     * Get updatedBy
     *
     * @return User
     */
    public function getUpdatedBy()
    {
        return $this->updatedBy;
    }

}

在您的实体中,只需像这样添加use 语句:

<?php

namespace AppBundle\Entity;

use AppBundle\Entity\Traits\BlameableEntity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
 * Your precious Foo entity
 *
 * @ORM\Table(name="foo")
 * @ORM\Entity(repositoryClass="AppBundle\Entity\FooRepository")
 */
class Foo
{
    use BlameableEntity;

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    // ...

我希望这会有所帮助!

【讨论】:

  • 我让它工作了,谢谢!我确实必须更改一件事:我必须将 $createdBy 和 $updatedBy 字段设为可选以防止出现错误:Typed property App\Entity\Note::$createdBy must not be accessed before initialization。以下代码是我的最终解决方案:/** * @var ?User $updatedBy * * @Gedmo\Blameable(on="update") * @ORM\ManyToOne(targetEntity=User::class) * @ORM\JoinColumn(name="updated_by", referencedColumnName="id", nullable=true) */ private ?User $updatedBy;
【解决方案2】:

对开启 symfony 3.0 + 的人的额外贡献:

在“doctrine_extensions.yml”中添加/修改:

gedmo.listener.blameable:
    class: Gedmo\Blameable\BlameableListener
    tags:
        - { name: doctrine.event_subscriber, connection: default }
    calls:
        - [ setAnnotationReader, [ "@annotation_reader" ] ]

【讨论】:

    【解决方案3】:

    如果要更新 updated_by 字段,则必须指定该字段,以便在更新时在 updated_by 中执行此操作。 例如:

    /**
     * @var \DateTime $updated
     *
     * @Gedmo\Timestampable(on="update")
     * @ORM\Column(type="datetime", nullable=true)
     */
    protected $updated;
    
    /**
     * @var string $updatedBy
     *
     * @Gedmo\Blameable(on="update", field="updated")
     * @ORM\Column(type="string", nullable=true)
     */
    protected $updatedBy;
    

    注意field="updated"

    【讨论】:

      【解决方案4】:

      如果有人仍然有这个问题,我终于可以按照以下步骤让 Gedmo Blameable 正常工作:

      1. 遵循本指南 https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/symfony2.md
      2. 将此添加到教义扩展名.yml

        gedmo.listener.blameable:
          class: Gedmo\Blameable\BlameableListener
          tags:
            - { name: doctrine.event_subscriber, connection: default }
          calls:
            - [ setAnnotationReader, [ "@annotation_reader" ] ]
        
      3. 修改onKernelRequest方法如下:

        public function onKernelRequest(GetResponseEvent $event) {
            if (Kernel::MAJOR_VERSION == 2 && Kernel::MINOR_VERSION < 6) {
                $securityContext = $this->container->get('security.context', ContainerInterface::NULL_ON_INVALID_REFERENCE);
                if (null !== $securityContext && null !== $securityContext->getToken() && $securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
                    $loggable = $this->container->get('gedmo.listener.loggable');
                    $loggable->setUsername($securityContext->getToken()->getUsername());
                }
            }
            else {
                $tokenStorage = $this->container->get('security.token_storage')->getToken();
                $authorizationChecker = $this->container->get('security.authorization_checker');
                if (null !== $tokenStorage && $authorizationChecker->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
                    $loggable = $this->container->get('gedmo.listener.loggable');
                    $loggable->setUsername($tokenStorage->getUser());
                    $blameable = $this->container->get('gedmo.listener.blameable');
                    $blameable->setUserValue($tokenStorage->getUser());
                }
            }
        }
        

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-24
        • 1970-01-01
        • 2012-02-15
        • 1970-01-01
        • 2015-04-01
        • 1970-01-01
        • 2014-12-20
        相关资源
        最近更新 更多