Symfony Gedmo Blameable 无法正常工作 [英] Symfony Gedmo Blameable not working

查看:23
本文介绍了Symfony Gedmo Blameable 无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Did any one ever find an solution for this issue? I'm having the same issue.

我的 config.yml:

My 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: GedmoTreeEntity
                dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Tree/Entity"
                alias: GedmoTree
                is_bundle: false
            gedmo_sortable:
                type: annotation
                prefix: GedmoSortableEntity
                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 包含在配置文件中:

My doctrine_extension.yml is included in the config file:

services:

  extension.listener:
    class: OmegaHomeBundleLibraryListenerDoctrineExtensionListener
    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: GedmoTreeTreeListener
    tags:
      - { name: doctrine.event_subscriber, connection: default }
    calls:
      - [ setAnnotationReader, [ @annotation_reader ] ]
  gedmo.listener.sortable:
    class: GedmoSortableSortableListener
    tags:
      - { name: doctrine.event_subscriber, connection: default }
    calls:
      - [ setAnnotationReader, [ @annotation_reader ] ]
  gedmo.listener.timestampable:
    class: GedmoTimestampableTimestampableListener
    tags:
      - { name: doctrine.event_subscriber, connection: default }
    calls:
      - [ setAnnotationReader, [ @annotation_reader ] ]
  gedmo.listener.loggable:
    class: GedmoLoggableLoggableListener
    tags:
      - { name: doctrine.event_subscriber, connection: default }
    calls:
      - [ setAnnotationReader, [ @annotation_reader ] ]
  gedmo.listener.blameable:
    class: GedmoBlameableBlameableListener
    tags:
      - { name: doctrine.event_subscriber, connection: default }
    calls:
      - [ setAnnotationReader, [ @annotation_reader ] ]
      - [ setUserValue, [ @security.token_storage ] ]

我为自己创建了一个 trait 来处理 created、updated、updated_by 和 createdby 字段:

I created myself an trait to handle the created, updated, updated_by and createdby fields:

        namespace HomeBundleTraits;
        use DoctrineORMMapping as ORM;
        use OmegaUserBundleEntityUsers;
        use GedmoMappingAnnotation as Gedmo;

        trait LogableTrait
        {

            /**
             * @var Users
             * @GedmoBlameable(on="create")
             * @ORMManyToOne(targetEntity="UserBundleEntityUsers")
             * @ORMJoinColumn(name="log_created_by", referencedColumnName="id")
             */
            protected $CreatedBy;

            /**
             * @var Users
             * @GedmoBlameable(on="update")
             * @ORMManyToOne(targetEntity="UserBundleEntityUsers")
             * @ORMJoinColumn(name="log_updated_by", referencedColumnName="id")
             */
            protected $UpdatedBy;
            /**
             * @GedmoTimestampable(on="create")
             * @ORMColumn(name="created", type="datetime")
             * @var DateTime
             */
            protected $created;

            /**
             * @GedmoTimestampable(on="create")
             * @ORMColumn(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;
            }


        }

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

But everytime that I use this Bundle I get:

The class 'SymfonyComponentSecurityCoreAuthenticationTokenStorageTokenStorage' was not found in the chain configured namespaces GedmoTreeEntity, GedmoSortableEntity, JMSJobQueueBundleEntity, AccountingBundleEntity, DocumentsBundleEntity, EavBundleEntity, HomeBundleEntity, UserBundleEntity, CustomerBundleEntity, JnsBundleXhprofBundleEntity 

我希望有人能帮助我.

推荐答案

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

for any one that Is having th same issue like me that the blamable feature is not working:

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

My solution was to implement the BlamableListener with an different approach:

  namespace HomeBundleLibrary;

  use DoctrineCommonNotifyPropertyChanged;
  use GedmoExceptionInvalidArgumentException;
  use GedmoTimestampableTimestampableListener;
  use GedmoBlameableMappingEventBlameableAdapter;
  use GedmoBlameableMappingDriverAnnotation;

  /**
   * 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: HomeBundleLibraryBlameableListener
  tags:
    - { name: doctrine.event_subscriber, connection: default }
  calls:
    - [ setAnnotationReader, [ @annotation_reader ] ]
    - [ setUserValue, [ @security.token_storage ] ]

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

you need to copy the mapping library to the same location as the listener itself. Adjust the namespaces and it works. It seems that some structures changed in symfony 2.7 so the plugin no longer works out of the box.

这篇关于Symfony Gedmo Blameable 无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆