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

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

问题描述

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



我的config.yml:

 

$ b dbal:
驱动程序:%database_server%
主机:%database_host%
端口: %database_port%
dbname:%database_name%
user:%database_user%
password:%database_password%
charset:UTF8
#if使用pdo_sqlite作为您的数据库驱动程序:
#1.在parameters.yml中添加路径
#eg database_path:%kernel.root_dir%/ data / data.db3
#2.取消注释parameter.yml.dist中的database_path
#3.取消注释下一行:
#path:%
orm:
auto_generate_proxy_classes:%kernel.debug%
naming_strategy:doctrine.orm.naming_strategy.underscore
auto_mapping:true
#Gedmo程序包扩展名对于Symfony和Doctrine
映射:
gedmo_tree:
类型:注释
前缀:Gedmo\Tree\Entity
dir:%kernel.root_dir%/。 ./vendor/gedmo/doctrine-extensions/lib/Gedmo/Tree/Entity
别名:GedmoTree
is_bundle:false
gedmo_sortable:
类型:注释
前缀:Gedmo\Sortable\Entity
dir:%kernel.root_dir%/ .. / vendor / gedmo / doctrine-extensions / lib / Gedmo / Sortable /实体
别名:GedmoTree
is_bundle:false
[...]
stof_doctrine_extensions:
default_locale:%locale%
translation_fallback:true
orm:
默认值:
timestampable:true
blameable:true

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

 服务:

extension.listener:
class:Omega\HomeBundle\Library\Listener\DoctrineExtensionListener
调用:
- [setContainer,[@service_container]]
标签:
#loggable hooks用户名,如果一个在安全上下文
- {name:kernel.event_listener,event:kernel.request,方法:onKernelRequest}
#Doctrine扩展侦听器来处理行为
gedmo.listener.tree:
class:Gedmo\Tree\TreeListener
标签:
- {name:doctrine.event_sub scriber,connection:default}
调用:
- [setAnnotationReader,[@annotation_reader]]
gedmo.listener.sortable:
class:Gedmo\Sortable\SortableListener
标签:
- {name:doctrine.event_subscriber,connection:default}
调用:
- [setAnnotationReader,[@annotation_reader]]
gedmo.listener.timestampable:
class:Gedmo\Timestampable\TimestampableListener
标签:
- {name:doctrine.event_subscriber,connection:default}
调用:
- [setAnnotationReader,[@ annotation_reader]]
gedmo.listener.loggable:
class:Gedmo\Loggable\LoggableListener
标签:
- {name:doctrine.event_subscriber,connection:default}
调用:
- [setAnnotationReader,[@annotation_reader]]
gedmo.listener.blameable:
class:Gedmo\Blameable\BlameableListener
标签:
- {name:doctrine.event_subscriber,connection:default}
调用:
- [setAnnotationReader,[@annotation_reader]]
- [setUserValue,[@ security.token_storage]]

我创造了一个特点来处理创建,更新,更新和创建的字段:





 命名空间HomeBundle\Traits; 
使用Doctrine\ORM\Mapping作为ORM;
使用Omega\UserBundle\Entity\Users;
使用Gedmo\Mapping\Annotation作为Gedmo;

trait LogableTrait
{

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

/ **
* @var用户
* @ 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用户
* /
public function getCreatedBy()
{
return $ this-> CreatedBy ;
}

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

/ **
* @return用户
* /
public function getUpdatedBy()
{
return $这 - > UpdatedBy;
}

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


}

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

 类'Symfony\Component\Security\Core\Authentication\Token在链配置的命名空间中找不到\Storage\TokenStorage'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 

我希望一些身体可以帮助我。

解决方案

像我一样,这个可耻的功能是无法工作的:



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





 命名空间HomeBundle\\ \\图书馆; 

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

/ **
*可扩展侦听器在创建和更新时处理
*日期的更新。
*
* @author Gediminas Morkevicius< gediminas.morkevicius@gmail.com&
* @license MIT许可证(http://www.opensource.org/licenses/mit-license.php)
* /
class BlameableListener extends TimestampableListener
{
保护$ user;

/ **
*获取用户可设置字段的值
*
* @param对象$ meta
* @param string $字段
*
* @return mixed
* /
public function getUserValue($ meta,$ field)
{
if($ meta-> hasAssociation($ field)){
if(null!== $ this-> user&&!is_object($ this-> user)){
throw new InvalidArgumentException(参考,用户必须是对象);
}
$ user = $ this-> user-> getToken() - > getUser();
if(!is_object($ user))
{
return null;
}
return $ user;
}

//确定它不是一个关联,那么它是一个字符串
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 expecting string,user must be a string,or object should have method getUsername or __toString);
}

return $ this-> user;
}

/ **
*设置用户值返回
*
* @param mixed $ user
* /
public function setUserValue($ user)
{
$ this-> user = $ user;
}

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

/ **
*更新字段
*
* @param对象$ 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($ meta-> hasAssociation($ field)&& $ newValue){
$ ea-> getObjectManager() - >坚持($ 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}
调用:
- [setAnnotationReader,[@annotation_reader]]
- [setUserValue,[@ security.token_storage]]

您需要将映射库复制到与侦听器本身相同的位置。调整命名空间,它的工作原理。似乎有些结构改变了symfony 2.7,所以这个插件不再开箱即用。


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

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: 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

My doctrine_extension.yml is included in the config file:

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 ] ]

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

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


        }

But everytime that I use this Bundle I get:

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 

I hope some body can help me.

解决方案

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

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

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

adjust the service for the blamable:

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

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无法工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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