Symfony Gedmo无法工作 [英] Symfony Gedmo Blameable not working
问题描述
我有同样的问题。
我的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屋!