-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EventedMapper as a proxy #74 #3
Open
nawarian
wants to merge
9
commits into
Respect:master
Choose a base branch
from
nawarian:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 8 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
2035024
EventedMapper structure
nawarian 0aaa4e3
Creating EventManager structure
Rafael-BP 234d08f
Updating namespaces
nawarian d68e90a
Fixing some missing files
nawarian 922850b
Fixing some syntax on EventManager
Rafael-BP 0fa906f
Finishing event dispatching under EventedMapper
nawarian 202e6ce
Making sure that none Mapper method has changed under this implementa…
nawarian 444406a
Adding removeEvent from EventManager inside EventedMapper
nawarian da3cde8
Changing on function to 'if'
Rafael-BP File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
<?php | ||
|
||
namespace Respect\Data\Event; | ||
|
||
use Respect\Data\Event\Interfaces\EventManager as EventManagerInterface; | ||
use Respect\Data\Event\Interfaces\Listener; | ||
|
||
class EventManager implements EventManagerInterface | ||
{ | ||
/* | ||
* This is the events array | ||
* @var array | ||
* @example | ||
* array( | ||
* "EventName1" => array( | ||
* 0 => callable, | ||
* 1 => concreteListener | ||
* ... | ||
* ) | ||
* ... | ||
* ) | ||
*/ | ||
private $events; | ||
|
||
/** | ||
* Construct | ||
*/ | ||
public function __construct() | ||
{ | ||
$this->events = array(); | ||
} | ||
|
||
/** | ||
* Add a callable or listener to a new or existent event | ||
* @param string $eventName The event to attach the listener | ||
* @param \Respect\Data\Event\Interfaces\Listener|\callable $action The event listener callback | ||
* @return void | ||
*/ | ||
public function on($eventName, $action) | ||
{ | ||
switch (true) { | ||
case ( (is_callable($action)) || ($action instanceof Listener) ): | ||
|
||
// The block below you can use for control or remove it | ||
$events = $this->getEvents(); | ||
if (array_key_exists("attach", $events)) { | ||
$this->dispatch("attach", array($eventName, $action)); | ||
} | ||
|
||
$this->events[$eventName][] = $action; | ||
break; | ||
default: | ||
$message = 'Invalid type of action provided for event manager'; | ||
throw new \InvalidArgumentException($message, 400); | ||
} | ||
} | ||
|
||
/** | ||
* Dispatch event | ||
* | ||
* If your event have more than one action, unless all the actions doesn't have | ||
* any args, the args array need to be a array of arrays, each index of the | ||
* args array needs to correspond to the index of the actions in the event | ||
* array to work properly. | ||
* | ||
* @param string $eventName The event to be dispatched | ||
* @param array $args Optional args for event actions | ||
* | ||
* @return void | ||
*/ | ||
public function dispatch($eventName, $args = array()) | ||
{ | ||
$events = $this->getEvents(); | ||
if (array_key_exists($eventName, $events)) { | ||
$argsIndex = 0; | ||
foreach ($events[$eventName] as $action) { | ||
switch (true) { | ||
case is_callable($action): | ||
if ( (count($events[$eventName]) > 1) && !empty($args) ) { | ||
call_user_func_array($action, $args[$argsIndex]); | ||
} else { | ||
call_user_func_array($action, $args); | ||
} | ||
break; | ||
case $action instanceof Listener: | ||
if ( (count($events[$eventName]) > 1) && !empty($args) ) { | ||
$action->update($args[$argsIndex]); | ||
} else { | ||
$action->update($args); | ||
} | ||
break; | ||
default: | ||
$message = 'Invalid type of action provided on event manager'; | ||
throw new \InvalidArgumentException($message, 400); | ||
} | ||
$argsIndex++; | ||
} | ||
} | ||
|
||
} | ||
|
||
/** | ||
* Return events array | ||
* @return array | ||
*/ | ||
public function getEvents() | ||
{ | ||
return $this->events; | ||
} | ||
|
||
/** | ||
* Search and return event from the events array | ||
* @param string $eventName the event name | ||
* @return array | ||
*/ | ||
public function getEvent($eventName) | ||
{ | ||
$events = $this->getEvents(); | ||
if (array_key_exists($eventName, $events)) { | ||
return $events[$eventName]; | ||
} | ||
return null; | ||
} | ||
|
||
/** | ||
* Remove event from events array | ||
* @param string $eventName The event to be removed | ||
* @return void | ||
*/ | ||
public function removeEvent($eventName) | ||
{ | ||
$events = $this->getEvents(); | ||
if (array_key_exists($eventName, $events)) { | ||
$this->events = array_splice($events, $eventName, 1); | ||
} | ||
} | ||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
<?php | ||
|
||
namespace Respect\Data\Event; | ||
|
||
use Respect\Data\AbstractMapper; | ||
|
||
class EventedMapper | ||
{ | ||
|
||
protected $mapper; | ||
|
||
protected $eventManager; | ||
|
||
public function __construct(AbstractMapper $mapper) | ||
{ | ||
$this->mapper = $mapper; | ||
$this->eventManager = new EventManager(); | ||
} | ||
|
||
public function __get($name) | ||
{ | ||
return $this->mapper->__get($name); | ||
} | ||
|
||
public function __set($alias, $collection) | ||
{ | ||
return $this->mapper->__set($alias, $collection); | ||
} | ||
|
||
public function __call($name, $children) | ||
{ | ||
return $this->mapper->__call($name, $children); | ||
} | ||
|
||
public function __isset($alias) | ||
{ | ||
return $this->mapper->__isset($alias); | ||
} | ||
|
||
public function on($event, $callback) | ||
{ | ||
return $this->eventManager->on($event, $callback); | ||
} | ||
|
||
public function removeEvent($eventName) | ||
{ | ||
return $this->eventManager->removeEvent($eventName); | ||
} | ||
|
||
public function flush() | ||
{ | ||
$trackedQueue = $this->getTrackedQueue(); | ||
$trackedEntities = $this->getTrackedEntities(); | ||
|
||
$this->processFlushQueue($trackedQueue, $trackedEntities, 'pre'); | ||
$flushResult = $this->mapper->flush(); | ||
$this->processFlushQueue($trackedQueue, $trackedEntities, 'post'); | ||
|
||
return $flushResult; | ||
} | ||
|
||
protected function processFlushQueue($queue, $trackedEntities, $eventSuffix) | ||
{ | ||
$em = $this->eventManager; | ||
|
||
foreach ($queue as $eventType => $objects) { | ||
foreach ($objects as $entity) { | ||
$collection = $trackedEntities[$entity]; | ||
|
||
$em->dispatch( | ||
"{$collection->getName()}:{$eventType}:{$eventSuffix}", | ||
array($entity, $collection) | ||
); | ||
} | ||
} | ||
} | ||
|
||
protected function getTrackedQueue() | ||
{ | ||
$m = $this->mapper; | ||
$inserts = $this->getObjectPropertyFromReflection($m, 'new'); | ||
$updates = $this->getObjectPropertyFromReflection($m, 'changed'); | ||
$deletes = $this->getObjectPropertyFromReflection($m, 'removed'); | ||
|
||
return array( | ||
'insert' => $inserts, | ||
'update' => $updates, | ||
'delete' => $deletes | ||
); | ||
} | ||
|
||
protected function getTrackedEntities() | ||
{ | ||
return $this->getObjectPropertyFromReflection( | ||
$this->mapper, | ||
'tracked' | ||
); | ||
} | ||
|
||
private function getObjectPropertyFromReflection( | ||
$object, | ||
$property | ||
) { | ||
$ref = new \ReflectionObject($object); | ||
$refProp = $ref->getProperty($property); | ||
if ($refProp->isPrivate() || $refProp->isProtected()) { | ||
$refProp->setAccessible(true); | ||
} | ||
|
||
return $refProp->getValue($object); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?php | ||
|
||
namespace Respect\Data\Event\Interfaces; | ||
|
||
interface EventManager | ||
{ | ||
/** | ||
* Do the dispatch of a specific event | ||
* @param string $eventName | ||
* @param array $args | ||
* | ||
* @return void | ||
*/ | ||
public function dispatch($eventName, $args = array()); | ||
|
||
/** | ||
* Add action (Listener or callable) for a event | ||
* @param string $eventName | ||
* @param \Respect\Data\Event\Interfaces\Listener|\callable $action | ||
*/ | ||
public function on($eventName, $action); | ||
|
||
/** | ||
* Remove a Event from the events array | ||
* @param string $eventName | ||
*/ | ||
public function removeEvent($eventName); | ||
|
||
/** | ||
* Return the events array | ||
* @return array | ||
*/ | ||
public function getEvents(); | ||
|
||
/** | ||
* Search and return event | ||
* @param string $eventName | ||
* @return array | ||
*/ | ||
public function getEvent($eventName); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
namespace Respect\Data\Event\Interfaces; | ||
|
||
interface Listener | ||
{ | ||
|
||
/** | ||
* Update listener, can recevei optional args array | ||
* @param array $args | ||
* @return void | ||
*/ | ||
function update($args = array()); | ||
|
||
} | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this switch?
Can we use
if
instead?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably for future implementations or checks. I don't see any trouble by changing it.
@Rafael-BP could you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, no problem.