2013-08-06 09:47:42 +04:00
< ? php
namespace Doctrine\Tests\ORM\Functional ;
2014-04-05 10:45:00 +04:00
use Doctrine\Common\Util\ClassUtils ;
2013-08-06 09:47:42 +04:00
use Doctrine\Tests\Models\CMS\CmsUser ;
use Doctrine\Tests\Models\CMS\CmsPhonenumber ;
use Doctrine\Tests\Models\CMS\CmsAddress ;
use Doctrine\Tests\Models\CMS\CmsEmail ;
use Doctrine\ORM\Event\LifecycleEventArgs ;
use Doctrine\ORM\Events ;
/**
* PostLoadEventTest
*
* @ author Guilherme Blanco < guilhermeblanco @ hotmail . com >
*/
class PostLoadEventTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
/**
* @ var integer
*/
private $userId ;
/**
* { @ inheritdoc }
*/
protected function setUp ()
{
$this -> useModelSet ( 'cms' );
parent :: setUp ();
$this -> loadFixture ();
}
public function testLoadedEntityUsingFindShouldTriggerEvent ()
{
$mockListener = $this -> getMock ( 'Doctrine\Tests\ORM\Functional\PostLoadListener' );
// CmsUser and CmsAddres, because it's a ToOne inverse side on CmsUser
$mockListener
-> expects ( $this -> exactly ( 2 ))
-> method ( 'postLoad' )
-> will ( $this -> returnValue ( true ));
$eventManager = $this -> _em -> getEventManager ();
$eventManager -> addEventListener ( array ( Events :: postLoad ), $mockListener );
$this -> _em -> find ( 'Doctrine\Tests\Models\CMS\CmsUser' , $this -> userId );
}
public function testLoadedEntityUsingQueryShouldTriggerEvent ()
{
$mockListener = $this -> getMock ( 'Doctrine\Tests\ORM\Functional\PostLoadListener' );
// CmsUser and CmsAddres, because it's a ToOne inverse side on CmsUser
$mockListener
-> expects ( $this -> exactly ( 2 ))
-> method ( 'postLoad' )
-> will ( $this -> returnValue ( true ));
$eventManager = $this -> _em -> getEventManager ();
$eventManager -> addEventListener ( array ( Events :: postLoad ), $mockListener );
$query = $this -> _em -> createQuery ( 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :id' );
$query -> setParameter ( 'id' , $this -> userId );
$query -> getResult ();
}
public function testLoadedAssociationToOneShouldTriggerEvent ()
{
$mockListener = $this -> getMock ( 'Doctrine\Tests\ORM\Functional\PostLoadListener' );
// CmsUser (root), CmsAddress (ToOne inverse side), CmsEmail (joined association)
$mockListener
-> expects ( $this -> exactly ( 3 ))
-> method ( 'postLoad' )
-> will ( $this -> returnValue ( true ));
$eventManager = $this -> _em -> getEventManager ();
$eventManager -> addEventListener ( array ( Events :: postLoad ), $mockListener );
$query = $this -> _em -> createQuery ( 'SELECT u, e FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e WHERE u.id = :id' );
$query -> setParameter ( 'id' , $this -> userId );
$query -> getResult ();
}
public function testLoadedAssociationToManyShouldTriggerEvent ()
{
$mockListener = $this -> getMock ( 'Doctrine\Tests\ORM\Functional\PostLoadListener' );
// CmsUser (root), CmsAddress (ToOne inverse side), 2 CmsPhonenumber (joined association)
$mockListener
-> expects ( $this -> exactly ( 4 ))
-> method ( 'postLoad' )
-> will ( $this -> returnValue ( true ));
$eventManager = $this -> _em -> getEventManager ();
$eventManager -> addEventListener ( array ( Events :: postLoad ), $mockListener );
$query = $this -> _em -> createQuery ( 'SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p WHERE u.id = :id' );
$query -> setParameter ( 'id' , $this -> userId );
$query -> getResult ();
}
public function testLoadedProxyEntityShouldTriggerEvent ()
{
$eventManager = $this -> _em -> getEventManager ();
// Should not be invoked during getReference call
$mockListener = $this -> getMock ( 'Doctrine\Tests\ORM\Functional\PostLoadListener' );
$mockListener
-> expects ( $this -> never ())
-> method ( 'postLoad' )
-> will ( $this -> returnValue ( true ));
$eventManager -> addEventListener ( array ( Events :: postLoad ), $mockListener );
$userProxy = $this -> _em -> getReference ( 'Doctrine\Tests\Models\CMS\CmsUser' , $this -> userId );
// Now deactivate original listener and attach new one
$eventManager -> removeEventListener ( array ( Events :: postLoad ), $mockListener );
$mockListener2 = $this -> getMock ( 'Doctrine\Tests\ORM\Functional\PostLoadListener' );
$mockListener2
-> expects ( $this -> exactly ( 2 ))
-> method ( 'postLoad' )
-> will ( $this -> returnValue ( true ));
$eventManager -> addEventListener ( array ( Events :: postLoad ), $mockListener2 );
$userProxy -> getName ();
}
2013-08-09 04:53:11 +04:00
public function testLoadedProxyPartialShouldTriggerEvent ()
{
$eventManager = $this -> _em -> getEventManager ();
// Should not be invoked during getReference call
$mockListener = $this -> getMock ( 'Doctrine\Tests\ORM\Functional\PostLoadListener' );
// CmsUser (partially loaded), CmsAddress (inverse ToOne), 2 CmsPhonenumber
$mockListener
-> expects ( $this -> exactly ( 4 ))
-> method ( 'postLoad' )
-> will ( $this -> returnValue ( true ));
$eventManager -> addEventListener ( array ( Events :: postLoad ), $mockListener );
$query = $this -> _em -> createQuery ( 'SELECT PARTIAL u.{id, name}, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p WHERE u.id = :id' );
$query -> setParameter ( 'id' , $this -> userId );
$query -> getResult ();
}
2013-08-06 09:47:42 +04:00
public function testLoadedProxyAssociationToOneShouldTriggerEvent ()
{
$user = $this -> _em -> find ( 'Doctrine\Tests\Models\CMS\CmsUser' , $this -> userId );
$mockListener = $this -> getMock ( 'Doctrine\Tests\ORM\Functional\PostLoadListener' );
// CmsEmail (proxy)
$mockListener
-> expects ( $this -> exactly ( 1 ))
-> method ( 'postLoad' )
-> will ( $this -> returnValue ( true ));
$eventManager = $this -> _em -> getEventManager ();
$eventManager -> addEventListener ( array ( Events :: postLoad ), $mockListener );
$emailProxy = $user -> getEmail ();
$emailProxy -> getEmail ();
}
public function testLoadedProxyAssociationToManyShouldTriggerEvent ()
{
$user = $this -> _em -> find ( 'Doctrine\Tests\Models\CMS\CmsUser' , $this -> userId );
$mockListener = $this -> getMock ( 'Doctrine\Tests\ORM\Functional\PostLoadListener' );
// 2 CmsPhonenumber (proxy)
$mockListener
-> expects ( $this -> exactly ( 2 ))
-> method ( 'postLoad' )
-> will ( $this -> returnValue ( true ));
$eventManager = $this -> _em -> getEventManager ();
$eventManager -> addEventListener ( array ( Events :: postLoad ), $mockListener );
$phonenumbersCol = $user -> getPhonenumbers ();
$phonenumbersCol -> first ();
}
2015-01-13 01:50:16 +03:00
/**
* @ group DDC - 3005
*/
2014-04-04 21:30:13 +04:00
public function testAssociationsArePopulatedWhenEventIsFired ()
{
2014-09-21 21:51:18 +04:00
$checkerListener = new PostLoadListenerCheckAssociationsArePopulated ();
2014-04-04 21:30:13 +04:00
$this -> _em -> getEventManager () -> addEventListener ( array ( Events :: postLoad ), $checkerListener );
$qb = $this -> _em -> getRepository ( 'Doctrine\Tests\Models\CMS\CmsUser' ) -> createQueryBuilder ( 'u' );
$qb -> leftJoin ( 'u.email' , 'email' );
$qb -> addSelect ( 'email' );
$qb -> getQuery () -> getSingleResult ();
$this -> assertTrue ( $checkerListener -> checked , 'postLoad event is not invoked' );
$this -> assertTrue ( $checkerListener -> populated , 'Association of email is not populated in postLoad event' );
}
2015-01-13 01:50:16 +03:00
/**
* @ group DDC - 3005
*/
2014-04-05 10:45:00 +04:00
public function testEventRaisedCorrectTimesWhenOtherEntityLoadedInEventHandler ()
{
$eventManager = $this -> _em -> getEventManager ();
2014-09-21 21:51:18 +04:00
$listener = new PostLoadListenerLoadEntityInEventHandler ();
2014-04-05 10:45:00 +04:00
$eventManager -> addEventListener ( array ( Events :: postLoad ), $listener );
$this -> _em -> find ( 'Doctrine\Tests\Models\CMS\CmsUser' , $this -> userId );
$this -> assertSame ( 1 , $listener -> countHandledEvents ( 'Doctrine\Tests\Models\CMS\CmsUser' ), 'Doctrine\Tests\Models\CMS\CmsUser should be handled once!' );
$this -> assertSame ( 1 , $listener -> countHandledEvents ( 'Doctrine\Tests\Models\CMS\CmsEmail' ), '\Doctrine\Tests\Models\CMS\CmsEmail should be handled once!' );
}
2013-08-06 09:47:42 +04:00
private function loadFixture ()
{
$user = new CmsUser ;
$user -> name = 'Roman' ;
$user -> username = 'romanb' ;
$user -> status = 'developer' ;
$address = new CmsAddress ;
$address -> country = 'Germany' ;
$address -> city = 'Berlin' ;
$address -> zip = '12345' ;
$user -> setAddress ( $address );
$email = new CmsEmail ;
$email -> setEmail ( 'roman@domain.com' );
$user -> setEmail ( $email );
$ph1 = new CmsPhonenumber ;
$ph1 -> phonenumber = " 0301234 " ;
$ph2 = new CmsPhonenumber ;
$ph2 -> phonenumber = " 987654321 " ;
$user -> addPhonenumber ( $ph1 );
$user -> addPhonenumber ( $ph2 );
$this -> _em -> persist ( $user );
$this -> _em -> flush ();
$this -> userId = $user -> getId ();
$this -> _em -> clear ();
}
}
class PostLoadListener
{
public function postLoad ( LifecycleEventArgs $event )
{
// Expected to be mocked out
echo 'Should never be called!' ;
}
2014-04-07 16:43:25 +04:00
}
2014-04-04 21:30:13 +04:00
2014-09-21 21:51:18 +04:00
class PostLoadListenerCheckAssociationsArePopulated
2014-04-04 21:30:13 +04:00
{
public $checked = false ;
public $populated = false ;
public function postLoad ( LifecycleEventArgs $event )
{
$object = $event -> getObject ();
if ( $object instanceof CmsUser ) {
if ( $this -> checked ) {
throw new \RuntimeException ( 'Expected to be one user!' );
}
$this -> checked = true ;
$this -> populated = null !== $object -> getEmail ();
}
}
}
2014-04-05 10:45:00 +04:00
2014-09-21 21:51:18 +04:00
class PostLoadListenerLoadEntityInEventHandler
2014-04-05 10:45:00 +04:00
{
private $firedByClasses = array ();
public function postLoad ( LifecycleEventArgs $event )
{
$object = $event -> getObject ();
$class = ClassUtils :: getClass ( $object );
if ( ! isset ( $this -> firedByClasses [ $class ])) {
$this -> firedByClasses [ $class ] = 1 ;
} else {
$this -> firedByClasses [ $class ] ++ ;
}
if ( $object instanceof CmsUser ) {
$object -> getEmail () -> getEmail ();
}
}
public function countHandledEvents ( $className )
{
return isset ( $this -> firedByClasses [ $className ]) ? $this -> firedByClasses [ $className ] : 0 ;
}
}