FOF30\Event\Dispatcher::chainHandle PHP Method

chainHandle() public method

Asks each observer to handle an event based on the provided arguments. The first observer to return a non-null result wins. This is a *very* simplistic implementation of the Chain of Command pattern.
public chainHandle ( string $event, array $args = [] ) : mixed
$event string The event name to handle
$args array The arguments to the event
return mixed Null if the event can't be handled by any observer
    public function chainHandle($event, $args = array())
    {
        $event = strtolower($event);
        $result = null;
        // Make sure the event is known to us, otherwise return an empty array
        if (!isset($this->events[$event]) || empty($this->events[$event])) {
            return $result;
        }
        foreach ($this->events[$event] as $className) {
            // Make sure the observer exists.
            if (!isset($this->observers[$className])) {
                continue;
            }
            // Get the observer
            $observer = $this->observers[$className];
            // Make sure the method exists
            if (!method_exists($observer, $event)) {
                continue;
            }
            // Call the event handler and add its output to the return value. The switch allows for execution up to 2x
            // faster than using call_user_func_array
            switch (count($args)) {
                case 0:
                    $result = $observer->{$event}();
                    break;
                case 1:
                    $result = $observer->{$event}($args[0]);
                    break;
                case 2:
                    $result = $observer->{$event}($args[0], $args[1]);
                    break;
                case 3:
                    $result = $observer->{$event}($args[0], $args[1], $args[2]);
                    break;
                case 4:
                    $result = $observer->{$event}($args[0], $args[1], $args[2], $args[3]);
                    break;
                case 5:
                    $result = $observer->{$event}($args[0], $args[1], $args[2], $args[3], $args[4]);
                    break;
                default:
                    $result = call_user_func_array(array($observer, $event), $args);
                    break;
            }
            if (!is_null($result)) {
                return $result;
            }
        }
        // Return the observers' result in an array
        return $result;
    }

Usage Example

Esempio n. 1
0
 /**
  * @covers FOF30\Event\Dispatcher::chainHandle
  */
 public function testChainHandle()
 {
     ReflectionHelper::setValue($this->object, 'observers', array());
     ReflectionHelper::setValue($this->object, 'events', array());
     $observer1 = new FirstObserver($this->object);
     $observer2 = new SecondObserver($this->object);
     // Trigger a non-existent event
     $result = $this->object->chainHandle('notthere');
     $this->assertNull($result);
     // Trigger a non-existent event with data
     $result = $this->object->chainHandle('notthere', array('whatever', 'nevermind'));
     $this->assertNull($result);
     // Trigger an event with one observer responding to it
     $result = $this->object->chainHandle('onlySecond');
     $this->assertEquals('only second', $result);
     // Trigger an event with two observers responding to it
     $result = $this->object->chainHandle('identifyYourself');
     $this->assertEquals('one', $result);
     // Trigger an event with two observers responding to it, with parameters
     $result = $this->object->chainHandle('returnConditional', array('one'));
     $this->assertEquals(true, $result);
     // Trigger an event with two observers responding to it, with parameters
     $result = $this->object->chainHandle('returnConditional', array('two'));
     $this->assertEquals(false, $result);
     // Trigger a real chain handler
     $result = $this->object->chainHandle('chain', array('one'));
     $this->assertEquals('one', $result);
     // Trigger a real chain handler
     $result = $this->object->chainHandle('chain', array('two'));
     $this->assertEquals('two', $result);
 }