Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

configure blameable doctrine extension with symfony2

can anyone provide a complete example of the Blameable Gedmo extension, and especially the configuration of the Blameable Listener ?

I am using the code provided by the documentation:

 * @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;

BUT the createdBy and updatedBy database columns are always NULL.

The documentation provides example to configure the other listeners (e.g. timestampable which I got working) but I find no example or documentation for the blameable listener.

Thanks for any help!!

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

EDIT to answer Jean:

yes I added the use which is:

use Gedmo\Mapping\Annotation as Gedmo;

I also use the Timestampable with the provided trait:

use Gedmo\Timestampable\Traits\TimestampableEntity;

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

and the timestampable configuration is:

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

Timespambable works just fine. I tried a similar configuration for the blameable listener since it has a setUserValue method:

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

but it doesn't work, I get this error (the 4 bundles are the ones used in my project):

The class 'Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage' was not found in the chain configured namespaces Cf\UserBundle\Entity, Cf\DocumentBundle\Entity, Cf\SouffleBundle\Entity, FOS\UserBundle\Model

I understand it is missing the user id or security token as an argument in one way or another but I just can't find an example anywhere. That's where I'm stuck. Any idea ?

like image 255
JML Avatar asked May 05 '15 14:05

JML


1 Answers

I also found it hard to enable Blameable behavior with StofDoctrineExtensionsBundle (let's assume you are using it).

There is one piece of configuration that is not mentioned in that bundle:

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

Apart from that, I created a BlameableEntity trait:

<?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;
    }

}

And in your entity, just add a use statement like this:

<?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;

    // ...

I hope this helps!

like image 131
ChMat Avatar answered Sep 19 '22 07:09

ChMat