DRY:如何在Symfony2项目的多个实体中使用此代码?特质? [英] DRY: how to use this code in several entities accross Symfony2 project? Traits?

查看:72
本文介绍了DRY:如何在Symfony2项目的多个实体中使用此代码?特质?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这段重复的代码,将在我的Symfony2项目中的多个实体中使用,所以当然可以应用某种DRY,如果可以的话,我在 PHP特性.

I have this repetitive piece of code that will be used in more than one entity in my Symfony2 project so will be fine to apply some kind of DRY, if it's possible of course, and I'm thinking in PHP Traits.

private static $preDeletedEntities;// static array that will contain entities due to deletion.
private static $deletedEntities;// static array that will contain entities that were deleted (well, at least the SQL was thrown).

/**
 * This callback will be called on the preRemove event
 * @ORM\PreRemove
 */
public function entityDueToDeletion()
{
    // This entity is due to be deleted though not deleted yet.
    self::$preDeletedEntities[] = $this->getId();
}

/**
 * This callback will be called in the postRemove event
 * @ORM\PostRemove
 */
public function entityDeleted()
{
    // The SQL to delete the entity has been issued. Could fail and trigger the rollback in which case the id doesn't get stored in the array.
    self::$deletedEntities[] = $this->getId();
}

public static function getDeletedEntities()
{
    return array_slice(self::$preDeletedEntities, 0, count(self::$deletedEntities));
}

public static function getNotDeletedEntities()
{
    return array_slice(self::$preDeletedEntities, count(self::$deletedEntities)+1, count(self::$preDeletedEntities));
}

public static function getFailedToDeleteEntity()
{
    if(count(self::$preDeletedEntities) == count(self::$deletedEntities)) {
        return NULL; // Everything went ok
    }

    return self::$preDeletedEntities[count(self::$deletedEntities)]; // We return the id of the entity that failed.
}

public static function prepareArrays()
{
    self::$preDeletedEntities = array();
    self::$deletedEntities = array();
}

这是我想到的代码:

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\HasLifecycleCallbacks()
 */
trait DeleteLifeCycleCallbacksTrait
{
    // write things here
}

但是注释会应用于实体吗?这样好吗为了避免不重复代码,您会怎么做?

But will be the Annotation applied to the entity? Is that fine? What would you do it to avoid not repeat the code?

试图找到最佳方法

具有 @Cerad 用户的一些想法,并且正如文档所述,生命周期事件监听器比简单的生命周期回调函数更强大,所以我将开始研究它们.

Having some ideas from @Cerad user and because as docs says Lifecycle event listeners are much more powerful than the simple lifecycle callbacks then I'll start playing with them.

因此,首先,此Lifecycle Callbacks|Listener|Suscribers的目的是存储每个持久对象的ID,以便我可以某种方式获取它并从控制器发送回视图.作为一个简单的可视示例,可以说我从视图将值(1, 2, 3, 4, 5)的数组发送到控制器,由于某种X的原因,只有1,4和5被保留(意味着从DB中完全删除),对吧?

So, first, the purpose of this Lifecycle Callbacks|Listener|Suscribers will be store the ID of each persisted object so I can get it in somehow and send back to the view from the controller. As a simple visual example, lets said I send from the view to the controller this array of values (1, 2, 3, 4, 5) and for some X reason just 1 ,4 and 5 was persisted (mean was complete delete from DB) to DB, right?

让我们也说,我将在Producto实体中使用事件侦听器.因此,在没有进行测试的情况下,仅从示例中获取代码,对于Listener:

Lets said also that I'll use the event listener in Producto entity. So, whithout test and just getting code from examples, the code should be something like this for the Listener:

use Doctrine\ORM\Event\LifecycleEventArgs;
use Entity\Producto;

class StoreDeletedIds
{
    private $deletedItems = []; 

    public function postDelete(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        $entityManager = $args->getEntityManager();

        if ($entity instanceof Producto) {
            array_push($deletedItems, $entity->getId());
        }
    }
}

我的问题|对此有疑问

  • 上面的代码是否正确?
  • 每次由教义调用侦听器时,都会清除$deletedItems吗?
  • 如何返回$deletedItems以便在控制器上将其捕获并发送回视图?
  • 我也需要定义一个订户吗?为什么?
  • Is the code above fine or doesn't?
  • Is $deletedItems cleaned every time the listener is invoked by Doctrine?
  • How do I return $deletedItems in order to catch it on the controller and send back to the view?
  • Do I need to define a Suscriber too? Why?

这是我的新话题,所以我需要一些建议

This are topics new to me so I need some kind of advise

推荐答案

@PeterPopelyshko 之后,这是我附带的解决方案,只需定义一个抽象类Model\DeleteLifeCycleCallbacks.php并将代码放入其中:

Following @PeterPopelyshko comment this is the solution I come with, just define a abstract class Model\DeleteLifeCycleCallbacks.php and put the code inside:

use Doctrine\ORM\Mapping as ORM; // not so sure if this is need here

abstract class DeleteLifeCycleCallbacks
{
    private static $preDeletedEntities;// static array that will contain entities due to deletion.
    private static $deletedEntities;// static array that will contain entities that were deleted (well, at least the SQL was thrown).

    /**
     * This callback will be called on the preRemove event
     * @ORM\PreRemove
     */
    public function entityDueToDeletion()
    {
        // This entity is due to be deleted though not deleted yet.
        self::$preDeletedEntities[] = $this->getId();
    }

    /**
     * This callback will be called in the postRemove event
     * @ORM\PostRemove
     */
    public function entityDeleted()
    {
        // The SQL to delete the entity has been issued. Could fail and trigger the rollback in which case the id doesn't get stored in the array.
        self::$deletedEntities[] = $this->getId();
    }

    public static function getDeletedEntities()
    {
        return array_slice(self::$preDeletedEntities, 0, count(self::$deletedEntities));
    }

    public static function getNotDeletedEntities()
    {
        return array_slice(self::$preDeletedEntities, count(self::$deletedEntities)+1, count(self::$preDeletedEntities));
    }

    public static function getFailedToDeleteEntity()
    {
        if(count(self::$preDeletedEntities) == count(self::$deletedEntities)) {
            return NULL; // Everything went ok
        }

        return self::$preDeletedEntities[count(self::$deletedEntities)]; // We return the id of the entity that failed.
    }

    public static function prepareArrays()
    {
        self::$preDeletedEntities = array();
        self::$deletedEntities = array();
    }
}

然后按以下方式使用它:

Then use it as follow:

/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks()
 */
class Producto extends Model\DeleteLifeCycleCallbacks
{
    // entity methods and properties here
}

这篇关于DRY:如何在Symfony2项目的多个实体中使用此代码?特质?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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