【问题标题】:Symfony Gedmo Blameable not workingSymfony Gedmo Blameable 无法正常工作
【发布时间】:2015-11-25 19:54:36
【问题描述】:

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

我的 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

我的学说扩展.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 ] ]

我为自己创建了一个 trait 来处理 created、updated、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;
            }


        }

但是每次我使用这个捆绑包时,我都会得到:

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 

我希望有人能帮助我。

【问题讨论】:

    标签: php symfony doctrine php-5.6


    【解决方案1】:

    对于任何像我一样有同样问题的人来说,可指责的功能不起作用:

    我的解决方案是用不同的方法实现 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 中的某些结构发生了变化,因此该插件不再开箱即用。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-21
        • 1970-01-01
        • 2020-02-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-16
        • 1970-01-01
        相关资源
        最近更新 更多