在Symfony2/Doctrine项目中,我有一个称为Developer
的实体,包括:
1. firstName
2. lastName
3. machineName
创建开发人员项目的表单仅显示firstName和lastname字段。我希望在用户创建开发人员项目时自动生成MachineName,该项目基于其他两个字段。
例如,John Doe
将给出john_doe
,Jérémy Arçouille
将提供jeremy_arcouille
。
所以我的问题是:
- 对于此(很常见)的情况有一般的最佳实践吗?
- 我必须从自己的文章中编码某些内容还是标准的东西?
- 如果(2 == true)将那个代码的后备箱放在哪个最好的地方(服务?utils?)?
- 我应该从控制器或实体中调用此部分代码吗?
注意:因为这将是代码的一部分,我希望它可以重复使用,所以我不想放入前主义的生命周期回调
我曾经为这个问题开发了一个完整的解决方案,并且效果很好,但确实是la脚和意大利面,所以我宁愿现在以适当的symfony2方式做一些东西。
感谢您的任何帮助。
在这种情况下,至少可以尝试两种方法。
-
创建
。prePresists
事件侦听器。该解决方案非常易于实现,从应用程序的角度透明地工作,可以与现有代码一起使用。定义您的侦听器服务:
use DoctrineCommonEventSubscriber; use DoctrineORMEvents; use DoctrineORMEventLifecycleEventArgs; 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); } }
在Symerofny的服务容器中声明它
<service id="..." class="..."> <!-- <argument ... /> --> <tag name="doctrine.event_subscriber" /> </service>
你完成了。
-
为您的应用程序创建适当的域/公共汽车层。这需要更多的工作,迫使您遵循一些一般指南,但使您的代码更加灵活和易于维护。简而言之,在您的控制器内部,而不是直接使用Doctrine的ObjectManager创建一个全新的服务器层,该服务器专门用于与您的域对象一起使用。该层Sholud包含了一项服务,该服务负责使用
save(Developer $dev)
方法坚持开发人员。此方法应与第一种方法中的MyEventListener
完全相同。
ps。您不应该进行任何复杂的操作或参考实体内的外部类。
好吧,这是我目前想到的。
我在mybundle utils machinesnames.php中创建了一个类文件,其中包含开发人员实体类调用的方法:
// MyBundleUtilsMachineNames.php
class MachinesNames
{
public static function createDeveloperName(array $nameArray)
{
// code goes here
return $machineName;
}
public static function createActivityName(array $nameArray)
{
// other stuff...
return $machineName;
}
}
// MyBundleEntityDeveloper.php
class Developer
{
public function setMachineName()
{
$nameArray = array(
'firstName' => $this->getFirstName(),
'lastName' => $this->getLastName(),
);
$machineName = MachineNames::createDeveloperName($nameArray);
$this->setName($machineName);
}
}
使用生命周期回调的预科师调用此功能。
有话吗?有没有更好的办法?您将如何做?