我试图在symfony2中运行一个控制台命令,其中某个类的某些属性正在更新。其中一个属性有一个相应的reviewBy-property,它由可责行行为设置,如下所示:
/**
* @var bool
* @ORM\Column(name="public_cmt", type="boolean", nullable=true)
*/
private $publicCmt;
/**
* @var User $publicCmtReviewedBy
*
* @Gedmo\Blameable(on="change", field="public_cmt")
* @ORM\ManyToOne(targetEntity="My\Bundle\EntityBundle\Entity\User")
* @ORM\JoinColumn(name="public_cmt_reviewed_by", referencedColumnName="id", nullable=true)
*/
private $publicCmtReviewedBy;
当我执行任务时,没有任何用户可以被指责为'所以我得到以下例外:
[Doctrine\ORM\ORMInvalidArgumentException]
EntityManager#persist() expects parameter 1 to be an entity object, NULL given.
但是我也无法禁用责备,因为在我开始执行任务并以编程方式尝试设置用户时,它没有注册为过滤器:
// create the authentication token
$token = new UsernamePasswordToken(
$user,
null,
'main',
$user->getRoles());
// give it to the security context
$this->getService('security.context')->setToken($token);
不起作用。有人有想法吗?
答案 0 :(得分:4)
如果您使用StofDoctrineExtensionsBundle,您只需执行以下操作:
$this->container->get('stof_doctrine_extensions.listener.blameable')
->setUserValue('task-user');
请参阅:https://github.com/stof/StofDoctrineExtensionsBundle/issues/197
答案 1 :(得分:2)
首先,我不确定' field'如果您使用数据库列或属性,则会很小心,但您可能需要将其更改为field="publicCmt"
。
您应该做的是覆盖Blameable Listener。我假设你正在使用StofDoctrineExtensionsBundle。在配置中首先覆盖:
# app/config/config.yml
stof_doctrine_extensions:
class:
blameable: MyBundle\BlameableListener
现在只需扩展现有的侦听器。你有几个选项 - 你想要允许NULL值(没有责备),或者你想拥有一个默认用户。比如说你想跳过persist并允许null,你可以覆盖:
namespace MyBundle\EventListener;
use Gedmo\Blameable\BlameableListener;
class MyBlameableListener extends BlameableListener
{
public function getUserValue($meta, $field)
{
try {
$user = parent::getUserValue($meta, $field);
}
catch (\Exception $e) {
$user = null;
return $user;
}
protected function updateField($object, $ea, $meta, $field)
{
if (!$user) {
return;
}
parent::updateField($object, $ea, $meta, $field);
}
}
因此,它首先尝试使用父getUserValue()
函数来获取用户,如果不是,则返回null
。我们必须输入try / catch,因为如果没有当前用户,它会抛出Exception
。现在,在updateField()
功能中,如果没有用户,我们就不会做任何事情。
免责声明 - 您可能仍然需要updateField()
功能的一部分......我还没有对此进行过测试。
这只是一个例子。另一个想法是拥有一个默认的数据库用户。您可以使用特定用户名将其放在配置文件中。然后,如果安全令牌中没有用户,则不是返回null,而是可以从数据库中获取默认用户并使用它(当然,您也必须在服务中注入实体管理器)。
答案 2 :(得分:2)
使用相同的config.yml-entry轻微修改上述答案:我们可以检查用户是否已设置,如果没有:因为我们可以访问updateField-method中的对象管理器,获取默认用户,设置它然后执行父方法。
namespace MyBundle\EventListener;
use Gedmo\Blameable\BlameableListener;
class MyBlameableListener extends BlameableListener
{
protected function updateField($object, $ea, $meta, $field)
{
// If we don't have a user, we are in a task and set a default-user
if (null === $this->getUserValue($meta, $field)) {
/* @var $ur UserRepository */
$ur = $ea->getObjectManager()->getRepository('MyBundle:User');
$taskUser = $ur->findOneBy(array('name' => 'task-user'));
$this->setUserValue($taskUser);
}
parent::updateField($object, $ea, $meta, $field);
}
}