在Symfony2 / Doctrine项目中,我有一个名为Developer
的实体,特别包括那些字段:
1. firstName
2. lastName
3. machineName
创建Developer项的表单仅显示firstName和lastName字段。我希望当用户根据另外两个字段创建一个Developer项时自动生成machineName。
例如,John Doe
会提供john_doe
而Jérémy Arçouille
会提供jeremy_arcouille
。
所以我的问题是:
注意:因为它是相当一部分代码,我希望它可以重用,我不想进入prePersist生命周期回调
我曾经为这个问题开发了一个完整的解决方案并且运行良好,但实际上是非常蹩脚和意大利式的,所以我宁愿现在以适当的Symfony2方式做更多的事情。
感谢您的帮助。
答案 0 :(得分:1)
在这种情况下,您可以尝试至少两种方法。
创建prePresists
event listener。该解决方案非常易于实现,从应用程序的角度透明地工作,并且可以与现有代码一起使用。
定义您的侦听器服务:
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Events;
use Doctrine\ORM\Event\LifecycleEventArgs;
class MyEventListener implements EventSubscriber
{
public function __construct(/* ... */)
{
/* you can use other services here */
}
public function prePersist(LifecycleEventArgs $event)
{
$developer = $event->getEntity();
if (!($developer instanceof Developer) || $developer->hasMachineName()) {
return;
}
...
$developer->setMachineName(...);
}
public function getSubscribedEvents()
{
return array(Events::prePersist);
}
}
在Symofny的服务容器中声明它
<service id="..." class="...">
<!-- <argument ... /> -->
<tag name="doctrine.event_subscriber" />
</service>
你已经完成了。
为您的应用程序创建适当的域/ bussines层。这需要更多工作,迫使您遵循一些通用准则,但使您的代码更灵活,更易于维护。简而言之,不是直接在控制器中使用Doctrine的ObjectManager,而是创建一个专门用于处理域对象的全新服务器层。此层sholud包含一个服务,该服务负责使用save(Developer $dev)
方法保持开发人员。从第一种方法开始,此方法应与MyEventListener
完全相同。
PS。您不应该执行任何复杂操作或从实体中引用外部类。
答案 1 :(得分:0)
我在MyBundle \ Utils \ MachinesNames.php中创建了一个类文件,其中包含一个由Developer实体的类调用的方法:
// MyBundle\Utils\MachineNames.php
class MachinesNames
{
public static function createDeveloperName(array $nameArray)
{
// code goes here
return $machineName;
}
public static function createActivityName(array $nameArray)
{
// other stuff...
return $machineName;
}
}
// MyBundle\Entity\Developer.php
class Developer
{
public function setMachineName()
{
$nameArray = array(
'firstName' => $this->getFirstName(),
'lastName' => $this->getLastName(),
);
$machineName = MachineNames::createDeveloperName($nameArray);
$this->setName($machineName);
}
}
在具有生命周期回调的prePersist上调用此函数。
有何评论?有没有更好的办法?你会怎么做?