Skip to content

Commit

Permalink
Add event manager to ProfileService (foregoing use of trait for now)
Browse files Browse the repository at this point in the history
See #10
  • Loading branch information
adamlundrigan committed Jul 12, 2014
1 parent acc0446 commit 4c62ce6
Show file tree
Hide file tree
Showing 2 changed files with 199 additions and 0 deletions.
78 changes: 78 additions & 0 deletions src/LdcUserProfile/Service/ProfileService.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace LdcUserProfile\Service;

use Zend\Form\FormInterface;
use Zend\EventManager\EventManagerInterface;
use LdcUserProfile\Extensions\AbstractExtension;
use ZfcUser\Entity\UserInterface;
use LdcUserProfile\Form\PrototypeForm;
Expand All @@ -32,20 +33,33 @@ class ProfileService
*/
protected $moduleOptions;

/**
* @var EventManagerInterface
*/
protected $events;

public function registerExtension(AbstractExtension $e)
{
$argv = array('extension' => $e);

$this->getEventManager()->trigger(__METHOD__ . '.pre', $this, $argv);
$this->extensions[$e->getName()] = $e;
$this->getEventManager()->trigger(__METHOD__ . '.post', $this, $argv);

return $this;
}

public function unregisterExtension($nameOrInstance)
{
$argv = array('extension' => $nameOrInstance);

$this->getEventManager()->trigger(__METHOD__ . '.pre', $this, $argv);
unset($this->extensions[
$nameOrInstance instanceof AbstractExtension
? $nameOrInstance->getName()
: (string) $nameOrInstance]
);
$this->getEventManager()->trigger(__METHOD__ . '.post', $this, $argv);

return $this;
}
Expand All @@ -69,15 +83,22 @@ public function constructFormForUser(UserInterface $user)
{
$form = clone $this->getFormPrototype();
$entity = clone $form->getObject();
$argv = compact('form', 'entity', 'user');

$vgOverrides = $this->getModuleOptions()->getValidationGroupOverrides();

$this->getEventManager()->trigger(__METHOD__ . '.pre', $this, $argv);

$validationGroup = array();
foreach ( $this->getExtensions() as $name => $ext ) {
$form->add($ext->getFieldset(), array('name' => $name));
$form->getInputFilter()->add($ext->getInputFilter(), $name);
$entity->{$name} = $ext->getObjectForUser($user);

$this->getEventManager()->trigger(__METHOD__ . '.extension', $this, $argv + array(
'extension' => $ext,
));

// Process validation group + overrides
if ( isset($vgOverrides[$name]) ) {
$ext->setFieldsetValidationGroup($vgOverrides[$name]);
Expand All @@ -91,16 +112,28 @@ public function constructFormForUser(UserInterface $user)

$form->bind($entity);

unset($argv['extension']);
$this->getEventManager()->trigger(__METHOD__ . '.post', $this, $argv);

return $form;
}

public function save($entity)
{
$argv = compact('entity');

$this->getEventManager()->trigger(__METHOD__ . '.pre', $this, $argv);

$result = true;
foreach ( $this->getExtensions() as $name => $ext ) {
$result = $result && $ext->save($entity);
}

unset($argv['extension']);
$this->getEventManager()->trigger(__METHOD__ . '.post', $this, $argv + array(
'result' => $result
));

return $result;
}

Expand Down Expand Up @@ -136,4 +169,49 @@ public function setModuleOptions(ModuleOptions $moduleOptions)
return $this;
}

/**
* Set the event manager instance used by this context.
*
* For convenience, this method will also set the class name / LSB name as
* identifiers, in addition to any string or array of strings set to the
* $this->eventIdentifier property.
*
* @param EventManagerInterface $events
* @return mixed
*/
public function setEventManager(EventManagerInterface $events)
{
$identifiers = array(__CLASS__, get_class($this));
if (isset($this->eventIdentifier)) {
if ((is_string($this->eventIdentifier))
|| (is_array($this->eventIdentifier))
|| ($this->eventIdentifier instanceof Traversable)
) {
$identifiers = array_unique(array_merge($identifiers, (array) $this->eventIdentifier));
} elseif (is_object($this->eventIdentifier)) {
$identifiers[] = $this->eventIdentifier;
}
// silently ignore invalid eventIdentifier types
}
$events->setIdentifiers($identifiers);
$this->events = $events;

return $this;
}

/**
* Retrieve the event manager
*
* Lazy-loads an EventManager instance if none registered.
*
* @return EventManagerInterface
*/
public function getEventManager()
{
if (!$this->events instanceof EventManagerInterface) {
$this->setEventManager(new \Zend\EventManager\EventManager());
}

return $this->events;
}
}
121 changes: 121 additions & 0 deletions tests/LdcUserProfileTest/Service/ProfileServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Zend\Form\Element\Text;
use Zend\Stdlib\Hydrator\ObjectProperty;
use Zend\Form\FormInterface;
use Zend\EventManager\EventManager;

class ProfileServiceTest extends \PHPUnit_Framework_TestCase
{
Expand Down Expand Up @@ -40,6 +41,19 @@ public function testRegisterExtension()
return $ext;
}

public function testRegisterExtensionFiresEvents()
{
$mockEventManager = new TriggerCountingEventManager();
$this->service->setEventManager($mockEventManager);

$this->testRegisterExtension();

$this->assertEquals(array(
'LdcUserProfile\Service\ProfileService::registerExtension.pre' => 1,
'LdcUserProfile\Service\ProfileService::registerExtension.post' => 1,
), $mockEventManager->triggeredEventCount);
}

public function testRegisterExtensionRejectsInvalidExtension()
{
$this->setExpectedException('PHPUnit_Framework_Error');
Expand Down Expand Up @@ -68,6 +82,21 @@ public function testUnregisterExtensionByName()
$this->assertArrayNotHasKey('testext', $this->service->getExtensions());
}

public function testUnregisterExtensionFiresEvents()
{
$ext = $this->testRegisterExtension();

$mockEventManager = new TriggerCountingEventManager();
$this->service->setEventManager($mockEventManager);

$this->service->unregisterExtension($ext->getName());

$this->assertEquals(array(
'LdcUserProfile\Service\ProfileService::unregisterExtension.pre' => 1,
'LdcUserProfile\Service\ProfileService::unregisterExtension.post' => 1,
), $mockEventManager->triggeredEventCount);
}

public function testHasExtensionByName()
{
$ext = $this->testRegisterExtension();
Expand Down Expand Up @@ -102,6 +131,20 @@ public function testSaveCallsSaveOnEachRegsiteredExtensionAndReturnsFalseWhenAnE
$this->assertFalse($this->service->save($payload));
}

public function testSaveFiresEvents()
{
$mockEventManager = new TriggerCountingEventManager();
$mockEventManager->matchingRegex = '{^LdcUserProfile\\\\Service\\\\ProfileService::save}is';
$this->service->setEventManager($mockEventManager);

$this->testSaveCallsSaveOnEachRegsiteredExtension();

$this->assertEquals(array(
'LdcUserProfile\Service\ProfileService::save.pre' => 1,
'LdcUserProfile\Service\ProfileService::save.post' => 1,
), $mockEventManager->triggeredEventCount);
}

public function testConstructFormForUser()
{
$mockUserData = new \stdClass();
Expand Down Expand Up @@ -135,6 +178,21 @@ public function testConstructFormForUser()
$this->assertTrue($form->getInputFilter()->get('testext')->has('test'));
}

public function testConstructFormForUserFiresEvents()
{
$mockEventManager = new TriggerCountingEventManager();
$mockEventManager->matchingRegex = '{^LdcUserProfile\\\\Service\\\\ProfileService::constructFormForUser}is';
$this->service->setEventManager($mockEventManager);

$this->testConstructFormForUser();

$this->assertEquals(array(
'LdcUserProfile\Service\ProfileService::constructFormForUser.pre' => 1,
'LdcUserProfile\Service\ProfileService::constructFormForUser.extension' => 1,
'LdcUserProfile\Service\ProfileService::constructFormForUser.post' => 1,
), $mockEventManager->triggeredEventCount);
}

public function testConstructFormForUserObeysValidationGroupOverrides()
{
$mockUserData = new \stdClass();
Expand Down Expand Up @@ -210,4 +268,67 @@ public function testConstructFormForUseIgnoresEmptyValidationGroupOverridesForAn
$this->assertTrue($form->getInputFilter()->has('testext'));
$this->assertTrue($form->getInputFilter()->get('testext')->has('test'));
}

public function testGetSetEventManager()
{
$mock = \Mockery::mock('Zend\EventManager\EventManagerInterface');
$mock->shouldReceive('setIdentifiers')->withArgs(array(array(
'LdcUserProfile\\Service\\ProfileService',
'LdcUserProfile\\Service\\ProfileService',
)))->andReturnNull();

$this->service->setEventManager($mock);
$this->assertSame($mock, $this->service->getEventManager());
}

public function testGetSetEventManagerAcceptsIdentifierFromInternalProperty()
{
$mock = \Mockery::mock('Zend\EventManager\EventManagerInterface');
$mock->shouldReceive('setIdentifiers')->withArgs(array(array(
'LdcUserProfile\\Service\\ProfileService',
'LdcUserProfileTest\\Service\\ProfileServiceWithExtraEventManagerIdentifier',
'someOtherIdentifier'
)))->andReturnNull();

$service = new ProfileServiceWithExtraEventManagerIdentifier();
$service->eventIdentifier = array('someOtherIdentifier');
$service->setEventManager($mock);
}

public function testGetSetEventManagerAcceptsObjectIdentifierFromInternalProperty()
{
$mock = \Mockery::mock('Zend\EventManager\EventManagerInterface');
$mock->shouldReceive('setIdentifiers')->withArgs(array(array(
'LdcUserProfile\\Service\\ProfileService',
'LdcUserProfileTest\\Service\\ProfileServiceWithExtraEventManagerIdentifier',
new \stdClass(),
)))->andReturnNull();

$service = new ProfileServiceWithExtraEventManagerIdentifier();
$service->eventIdentifier = new \stdClass();
$service->setEventManager($mock);
}
}

class ProfileServiceWithExtraEventManagerIdentifier extends ProfileService
{
public $eventIdentifier = null;
}

class TriggerCountingEventManager extends EventManager
{
public $triggeredEventCount = array();
public $matchingRegex = null;

public function trigger($event, $target = null, $argv = array(), $callback = null)
{
if ( !empty($this->matchingRegex) && !preg_match($this->matchingRegex, $event) ) {
return;
}

if ( ! isset($this->triggeredEventCount[$event]) ) {
$this->triggeredEventCount[$event] = 0;
}
$this->triggeredEventCount[$event]++;
}
}

0 comments on commit 4c62ce6

Please sign in to comment.