2015-07-02 11 views
1

Я не пишу «что я пробовал» или «что не работает», так как я могу придумать множество способов реализовать что-то подобное. Но я не могу поверить, что никто раньше не делал что-то подобное, и поэтому я хотел бы задать вопрос, чтобы увидеть, какие из лучших методов Doctrine2 появляются.Doctrine2 - Событие триггера при изменении свойства (PropertyChangeListener)


То, что я хочу, чтобы вызвать событие на изменение свойства. Итак, допустим, у меня есть объект с собственностью $active, и я хочу, чтобы событие EntityBecameActive запускалось для каждого объекта, когда свойство изменяется с false на true.

Другие библиотеки часто имеют событие PropertyChanged, но в Doctrine2 такой вещи нет.

Так что у меня какой-то объект, как это:

<?php 

namespace Application\Entity; 

class Entity 
{ 
    /** 
    * @var int 
    * @ORM\Id 
    * @ORM\Column(type="integer"); 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @var boolean 
    * @ORM\Column(type="boolean", nullable=false) 
    */ 
    protected $active = false; 

    /** 
    * Get active. 
    * 
    * @return string 
    */ 
    public function getActive() 
    { 
     return $this->active; 
    } 

    /** 
    * Is active. 
    * 
    * @return string 
    */ 
    public function isActive() 
    { 
     return $this->active; 
    } 

    /** 
    * Set active. 
    * 
    * @param bool $active 
    * @return self 
    */ 
    public function setActive($active) 
    { 
     $this->active = $active; 
     return $this; 
    } 
} 

ответ

3

Может ChangeTracking политики является то, что вы хотите, может быть, это не так!

Политика NOTIFY основана на предположении, что организации уведомляют заинтересованных слушателей об изменениях их свойств. Для этой цели класс, который хочет использовать эту политику, должен реализовать интерфейс NotificationPropertyChanged из пространства имен Doctrine \ Common.

Посмотрите полный пример в ссылке выше.

class MyEntity extends DomainObject 
{ 
    private $data; 
    // ... other fields as usual 

    public function setData($data) { 
     if ($data != $this->data) { // check: is it actually modified? 
      $this->onPropertyChanged('data', $this->data, $data); 
      $this->data = $data; 
     } 
    } 
} 

UPDATE


Это полный пример, но глупый, так что вы можете работать на нем, как вы хотите. Он просто демонстрирует, как вы это делаете, поэтому не считайте это слишком серьезным!

объект

namespace Football\TeamBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 

/** 
* @ORM\Entity 
* @ORM\Table(name="country") 
*/ 
class Country extends DomainObject 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Id 
    * @ORM\Column(type="smallint") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(type="string", length=2, unique=true) 
    */ 
    protected $code; 

    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set code 
    * 
    * @param string $code 
    * @return Country 
    */ 
    public function setCode($code) 
    { 
     if ($code != $this->code) { 
      $this->onPropertyChanged('code', $this->code, $code); 
      $this->code = $code; 
     } 

     return $this; 
    } 

    /** 
    * Get code 
    * 
    * @return string 
    */ 
    public function getCode() 
    { 
     return $this->code; 
    } 
} 

domainobject

namespace Football\TeamBundle\Entity; 

use Doctrine\Common\NotifyPropertyChanged; 
use Doctrine\Common\PropertyChangedListener; 

abstract class DomainObject implements NotifyPropertyChanged 
{ 
    private $listeners = array(); 

    public function addPropertyChangedListener(PropertyChangedListener $listener) 
    { 
     $this->listeners[] = $listener; 
    } 

    protected function onPropertyChanged($propName, $oldValue, $newValue) 
    { 
     $filename = '../src/Football/TeamBundle/Entity/log.txt'; 
     $content = file_get_contents($filename); 

     if ($this->listeners) { 
      foreach ($this->listeners as $listener) { 
       $listener->propertyChanged($this, $propName, $oldValue, $newValue); 

       file_put_contents($filename, $content . "\n" . time()); 
      } 
     } 
    } 
} 

контроллер

namespace Football\TeamBundle\Controller; 

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Football\TeamBundle\Entity\Country; 

class DefaultController extends Controller 
{ 
    public function indexAction() 
    { 
     // First run this to create or just manually punt in DB 
     $this->createAction('AB'); 
     // Run this to update it 
     $this->updateAction('AB'); 

     return $this->render('FootballTeamBundle:Default:index.html.twig', array('name' => 'inanzzz')); 
    } 

    public function createAction($code) 
    { 
     $em = $this->getDoctrine()->getManager(); 
     $country = new Country(); 
     $country->setCode($code); 
     $em->persist($country); 
     $em->flush(); 
    } 

    public function updateAction($code) 
    { 
     $repo = $this->getDoctrine()->getRepository('FootballTeamBundle:Country'); 
     $country = $repo->findOneBy(array('code' => $code)); 
     $country->setCode('BB'); 

     $em = $this->getDoctrine()->getManager(); 
     $em->flush(); 
    } 
} 

И есть этот файл остроумие h 777 (опять же, это тест): src/Football/TeamBundle/Entity/log.txt

При запуске кода в файле журнала будет храниться отметка времени, предназначенная только для демонстрации.

+0

Это выглядит действительно очень интересно, я буду погружаться в документы :) – Wilt

+0

Я использовал его по той же причине, что и ваш, так что посмотрите, удовлетворяет ли он вашим конкретным потребностям. – BentCoder

+0

Также посмотрите на http://doctrine-orm.readthedocs.org/en/latest/reference/change-tracking-policies.html – BentCoder