Symfony Gedmo Blameable无法正常工作

时间:2015-08-31 17:50:43

标签: php symfony doctrine php-5.6

有没有人找到解决这个问题的方法? 我遇到了同样的问题。

我的config.yml:

# Doctrine Configuration
doctrine:
    dbal:
        driver:   "%database_server%"
        host:     "%database_host%"
        port:     "%database_port%"
        dbname:   "%database_name%"
        user:     "%database_user%"
        password: "%database_password%"
        charset:  UTF8
        # if using pdo_sqlite as your database driver:
        #   1. add the path in parameters.yml
        #     e.g. database_path: "%kernel.root_dir%/data/data.db3"
        #   2. Uncomment database_path in parameters.yml.dist
        #   3. Uncomment next line:
        #     path:     "%database_path%"
    orm:
        auto_generate_proxy_classes: "%kernel.debug%"
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true
        #Gedmo Package extension for Symfony and Doctrine
        mappings:
            gedmo_tree:
                type: annotation
                prefix: Gedmo\Tree\Entity
                dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Tree/Entity"
                alias: GedmoTree
                is_bundle: false
            gedmo_sortable:
                type: annotation
                prefix: Gedmo\Sortable\Entity
                dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Sortable/Entity"
                alias: GedmoTree
                is_bundle: false
[...]
stof_doctrine_extensions:
    default_locale: "%locale%"
    translation_fallback: true
    orm:
        default:
            timestampable: true
            blameable: true

我的doctrine_extension.yml包含在配置文件中:

services:

  extension.listener:
    class: Omega\HomeBundle\Library\Listener\DoctrineExtensionListener
    calls:
      - [ setContainer, [@service_container]]
    tags:
      # loggable hooks user username if one is in security context
      - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
  # Doctrine Extension listeners to handle behaviors
  gedmo.listener.tree:
    class: Gedmo\Tree\TreeListener
    tags:
      - { name: doctrine.event_subscriber, connection: default }
    calls:
      - [ setAnnotationReader, [ @annotation_reader ] ]
  gedmo.listener.sortable:
    class: Gedmo\Sortable\SortableListener
    tags:
      - { name: doctrine.event_subscriber, connection: default }
    calls:
      - [ setAnnotationReader, [ @annotation_reader ] ]
  gedmo.listener.timestampable:
    class: Gedmo\Timestampable\TimestampableListener
    tags:
      - { name: doctrine.event_subscriber, connection: default }
    calls:
      - [ setAnnotationReader, [ @annotation_reader ] ]
  gedmo.listener.loggable:
    class: Gedmo\Loggable\LoggableListener
    tags:
      - { name: doctrine.event_subscriber, connection: default }
    calls:
      - [ setAnnotationReader, [ @annotation_reader ] ]
  gedmo.listener.blameable:
    class: Gedmo\Blameable\BlameableListener
    tags:
      - { name: doctrine.event_subscriber, connection: default }
    calls:
      - [ setAnnotationReader, [ @annotation_reader ] ]
      - [ setUserValue, [ @security.token_storage ] ]

我创建了一个特性来处理创建,更新,updated_by和createdby字段:

        namespace HomeBundle\Traits;
        use Doctrine\ORM\Mapping as ORM;
        use Omega\UserBundle\Entity\Users;
        use Gedmo\Mapping\Annotation as Gedmo;

        trait LogableTrait
        {

            /**
             * @var Users
             * @Gedmo\Blameable(on="create")
             * @ORM\ManyToOne(targetEntity="UserBundle\Entity\Users")
             * @ORM\JoinColumn(name="log_created_by", referencedColumnName="id")
             */
            protected $CreatedBy;

            /**
             * @var Users
             * @Gedmo\Blameable(on="update")
             * @ORM\ManyToOne(targetEntity="UserBundle\Entity\Users")
             * @ORM\JoinColumn(name="log_updated_by", referencedColumnName="id")
             */
            protected $UpdatedBy;
            /**
             * @Gedmo\Timestampable(on="create")
             * @ORM\Column(name="created", type="datetime")
             * @var \DateTime
             */
            protected $created;

            /**
             * @Gedmo\Timestampable(on="create")
             * @ORM\Column(name="updated", type="datetime")
             * @var \DateTime
             */
            protected $updated;

            /**
             * @return Users
             */
            public function getCreatedBy ()
            {
                return $this->CreatedBy;
            }

            /**
             * @param Users $CreatedBy
             *
             * @return $this
             */
            public function setCreatedBy (Users $CreatedBy )
            {
                $this->CreatedBy = $CreatedBy;
                return $this;
            }

            /**
             * @return Users
             */
            public function getUpdatedBy ()
            {
                return $this->UpdatedBy;
            }

            /**
             * @param Users $UpdatedBy
             *
             * @return $this
             */
            public function setUpdatedBy (Users $UpdatedBy )
            {
                $this->UpdatedBy = $UpdatedBy;
                return $this;
            }


        }

但每次我使用这个Bundle我都会得到:

The class 'Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage' was not found in the chain configured namespaces Gedmo\Tree\Entity, Gedmo\Sortable\Entity, JMS\JobQueueBundle\Entity, AccountingBundle\Entity, DocumentsBundle\Entity, EavBundle\Entity, HomeBundle\Entity, UserBundle\Entity, CustomerBundle\Entity, Jns\Bundle\XhprofBundle\Entity 

我希望有些人可以帮助我。

2 个答案:

答案 0 :(得分:2)

对于任何一个像我一样有问题的人,可燃功能不起作用:

我的解决方案是使用不同的方法实现BlamableListener:

  namespace HomeBundle\Library;

  use Doctrine\Common\NotifyPropertyChanged;
  use Gedmo\Exception\InvalidArgumentException;
  use Gedmo\Timestampable\TimestampableListener;
  use Gedmo\Blameable\Mapping\Event\BlameableAdapter;
  use Gedmo\Blameable\Mapping\Driver\Annotation;

  /**
   * The Blameable listener handles the update of
   * dates on creation and update.
   *
   * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
   * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
   */
  class BlameableListener extends TimestampableListener
  {
      protected $user;

      /**
       * Get the user value to set on a blameable field
       *
       * @param object $meta
       * @param string $field
       *
       * @return mixed
       */
      public function getUserValue($meta, $field)
      {
          if ($meta->hasAssociation($field)) {
              if (null !== $this->user && ! is_object($this->user)) {
                  throw new InvalidArgumentException("Blame is reference, user must be an object");
              }
              $user = $this->user->getToken()->getUser();
              if(!is_object($user))
              {
                  return null;
              }
              return $user;
          }

          // ok so its not an association, then it is a string
          if (is_object($this->user)) {
              if (method_exists($this->user, 'getUsername')) {
                  return (string) $this->user->getUsername();
              }
              if (method_exists($this->user, '__toString')) {
                  return $this->user->__toString();
              }
              throw new InvalidArgumentException("Field expects string, user must be a string, or object should have method getUsername or __toString");
          }

          return $this->user;
      }

      /**
       * Set a user value to return
       *
       * @param mixed $user
       */
      public function setUserValue($user)
      {
          $this->user = $user;
      }

      /**
       * {@inheritDoc}
       */
      protected function getNamespace()
      {
          return __NAMESPACE__;
      }

      /**
       * Updates a field
       *
       * @param object           $object
       * @param BlameableAdapter $ea
       * @param $meta
       * @param $field
       */
      protected function updateField($object, $ea, $meta, $field)
      {
          $property = $meta->getReflectionProperty($field);
          $oldValue = $property->getValue($object);
          $newValue = $this->getUserValue($meta, $field);

          //if blame is reference, persist object
          if ($meta->hasAssociation($field) && $newValue) {
              $ea->getObjectManager()->persist($newValue);
          }
          $property->setValue($object, $newValue);
          if ($object instanceof NotifyPropertyChanged) {
              $uow = $ea->getObjectManager()->getUnitOfWork();
              $uow->propertyChanged($object, $field, $oldValue, $newValue);
          }
      }
  }

调整可燃物品的服务:

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

您需要将映射库复制到与侦听器本身相同的位置。调整名称空间,它的工作原理。似乎某些结构在symfony 2.7中发生了变化,因此该插件不再能够开箱即用。

答案 1 :(得分:0)

如果要更新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”