pax_global_header00006660000000000000000000000064126453035640014522gustar00rootroot0000000000000052 comment=b4354f75f694504d32e7d080641854f830acb865 zend-eventmanager-release-2.6.2/000077500000000000000000000000001264530356400165615ustar00rootroot00000000000000zend-eventmanager-release-2.6.2/CHANGELOG.md000066400000000000000000000073771264530356400204100ustar00rootroot00000000000000# Changelog All notable changes to this project will be documented in this file, in reverse chronological order by release. ## 2.6.2 - 2016-01-12 ### Added - [#19](https://github.com/zendframework/zend-eventmanager/pull/19) adds a new trait, `Zend\EventManager\Test\EventListenerIntrospectionTrait`, intended for composition in unit tests. It provides a number of methods that can be used to retrieve listeners with or without associated priority, and the assertion `assertListenerAtPriority(callable $listener, $priority, $event, EventManager $events, $message = '')`, which can be used for testing that a listener was registered at the specified priority with the specified event. The features in this patch are intended to facilitate testing against both version 2 and version 3 of zend-eventmanager, as it provides a consistent API for retrieving lists of events and listeners between the two versions. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - Nothing. ## 2.6.0 - 2015-09-29 ### Added - Added `Zend\EventManager\SharedEventsCapableInterface`. This interface will largely replace `Zend\EventManager\SharedEventManagerAwareInterface` in version 3, and the latter was updated to extend it. - Added `EventManager::triggerEvent(EventInterface $event)` as a forwards-compatibility feature. - Add `EventManager::triggerEventUntil(callable $callback, EventIterface $event)` as a forwards-compatibility feature. - Adds [Athletic](https://github.com/polyfractal/athletic) benchmarks to aid in gauging performanc impact of changes; these are a development change only. ### Deprecated - Marked `GlobalEventManager` as deprecated; this class will be removed in version 3. - Marked `StaticEventManager` as deprecated; this class will be removed in version 3. - Marked `SharedListenerAggregateInterface` as deprecated; this interface will be removed in version 3. - Marked `SharedEventAggregateAwareInterface` as deprecated; this interface will be removed in version 3. - Marked `SharedEventManagerAwareInterface` as deprecated; this interface will be removed in version 3. - Marked `EventManager::setSharedManager()` as deprecated; this method will be removed in version 3. - Marked `EventManager::unsetSharedManager()` as deprecated; this method will be removed in version 3. - Marked `EventManagerInterface::` and `EventManager::getEvents()` as deprecated; this method will be removed in version 3. - Marked `EventManagerInterface::` and `EventManager::getListeners()` as deprecated; this method will be removed in version 3. - Marked `EventManagerInterface::` and `Eventmanager::setEventClass()` as deprecated; this method is renamed to `setEventPrototype(EventInterface $event)` in version 3. - Marked `EventManagerInterface::` and `EventManager::attachAggregate()` as deprecated; this method will be removed in version 3. - Marked `EventManagerInterface::` and `EventManager::detachAggregate()` as deprecated; this method will be removed in version 3. - Marked `SharedEventManagerInterface::` and `SharedEventManager::getEvents()` as deprecated; this method will be removed in version 3. ### Removed - Nothing. ### Fixed - Nothing. ## 2.5.2 - 2015-07-16 ### Added - [#5](https://github.com/zendframework/zend-eventmanager/pull/5) adds a number of unit tests to improve test coverage, and thus maintainability and stability. ### Deprecated - Nothing. ### Removed - [#3](https://github.com/zendframework/zend-eventmanager/pull/3) removes some PHP 5.3- and 5.4-isms (such as marking Traits as requiring 5.4, and closing over a copy of `$this`) from the test suite. ### Fixed - [#5](https://github.com/zendframework/zend-eventmanager/pull/5) fixes a bug in `FilterIterator` that occurs when attempting to extract from an empty heap. zend-eventmanager-release-2.6.2/CONTRIBUTING.md000066400000000000000000000166531264530356400210250ustar00rootroot00000000000000# CONTRIBUTING ## RESOURCES If you wish to contribute to Zend Framework, please be sure to read/subscribe to the following resources: - [Coding Standards](https://github.com/zendframework/zf2/wiki/Coding-Standards) - [Contributor's Guide](http://framework.zend.com/participate/contributor-guide) - ZF Contributor's mailing list: Archives: http://zend-framework-community.634137.n4.nabble.com/ZF-Contributor-f680267.html Subscribe: zf-contributors-subscribe@lists.zend.com - ZF Contributor's IRC channel: #zftalk.dev on Freenode.net If you are working on new features or refactoring [create a proposal](https://github.com/zendframework/zend-event-manager/issues/new). ## Reporting Potential Security Issues If you have encountered a potential security vulnerability, please **DO NOT** report it on the public issue tracker: send it to us at [zf-security@zend.com](mailto:zf-security@zend.com) instead. We will work with you to verify the vulnerability and patch it as soon as possible. When reporting issues, please provide the following information: - Component(s) affected - A description indicating how to reproduce the issue - A summary of the security vulnerability and impact We request that you contact us via the email address above and give the project contributors a chance to resolve the vulnerability and issue a new release prior to any public exposure; this helps protect users and provides them with a chance to upgrade and/or update in order to protect their applications. For sensitive email communications, please use [our PGP key](http://framework.zend.com/zf-security-pgp-key.asc). ## RUNNING TESTS > ### Note: testing versions prior to 2.4 > > This component originates with Zend Framework 2. During the lifetime of ZF2, > testing infrastructure migrated from PHPUnit 3 to PHPUnit 4. In most cases, no > changes were necessary. However, due to the migration, tests may not run on > versions < 2.4. As such, you may need to change the PHPUnit dependency if > attempting a fix on such a version. To run tests: - Clone the repository: ```console $ git clone git@github.com:zendframework/zend-event-manager.git $ cd ``` - Install dependencies via composer: ```console $ curl -sS https://getcomposer.org/installer | php -- $ ./composer.phar install ``` If you don't have `curl` installed, you can also download `composer.phar` from https://getcomposer.org/ - Run the tests via `phpunit` and the provided PHPUnit config, like in this example: ```console $ ./vendor/bin/phpunit ``` You can turn on conditional tests with the phpunit.xml file. To do so: - Copy `phpunit.xml.dist` file to `phpunit.xml` - Edit `phpunit.xml` to enable any specific functionality you want to test, as well as to provide test values to utilize. ## Running Coding Standards Checks This component uses [php-cs-fixer](http://cs.sensiolabs.org/) for coding standards checks, and provides configuration for our selected checks. `php-cs-fixer` is installed by default via Composer. To run checks only: ```console $ ./vendor/bin/php-cs-fixer fix . -v --diff --dry-run --config-file=.php_cs ``` To have `php-cs-fixer` attempt to fix problems for you, omit the `--dry-run` flag: ```console $ ./vendor/bin/php-cs-fixer fix . -v --diff --config-file=.php_cs ``` If you allow php-cs-fixer to fix CS issues, please re-run the tests to ensure they pass, and make sure you add and commit the changes after verification. ## Recommended Workflow for Contributions Your first step is to establish a public repository from which we can pull your work into the master repository. We recommend using [GitHub](https://github.com), as that is where the component is already hosted. 1. Setup a [GitHub account](http://github.com/), if you haven't yet 2. Fork the repository (http://github.com/zendframework/zend-event-manager) 3. Clone the canonical repository locally and enter it. ```console $ git clone git://github.com:zendframework/zend-event-manager.git $ cd zend-event-manager ``` 4. Add a remote to your fork; substitute your GitHub username in the command below. ```console $ git remote add {username} git@github.com:{username}/zend-event-manager.git $ git fetch {username} ``` ### Keeping Up-to-Date Periodically, you should update your fork or personal repository to match the canonical ZF repository. Assuming you have setup your local repository per the instructions above, you can do the following: ```console $ git checkout master $ git fetch origin $ git rebase origin/master # OPTIONALLY, to keep your remote up-to-date - $ git push {username} master:master ``` If you're tracking other branches -- for example, the "develop" branch, where new feature development occurs -- you'll want to do the same operations for that branch; simply substitute "develop" for "master". ### Working on a patch We recommend you do each new feature or bugfix in a new branch. This simplifies the task of code review as well as the task of merging your changes into the canonical repository. A typical workflow will then consist of the following: 1. Create a new local branch based off either your master or develop branch. 2. Switch to your new local branch. (This step can be combined with the previous step with the use of `git checkout -b`.) 3. Do some work, commit, repeat as necessary. 4. Push the local branch to your remote repository. 5. Send a pull request. The mechanics of this process are actually quite trivial. Below, we will create a branch for fixing an issue in the tracker. ```console $ git checkout -b hotfix/9295 Switched to a new branch 'hotfix/9295' ``` ... do some work ... ```console $ git commit ``` ... write your log message ... ```console $ git push {username} hotfix/9295:hotfix/9295 Counting objects: 38, done. Delta compression using up to 2 threads. Compression objects: 100% (18/18), done. Writing objects: 100% (20/20), 8.19KiB, done. Total 20 (delta 12), reused 0 (delta 0) To ssh://git@github.com/{username}/zend-event-manager.git b5583aa..4f51698 HEAD -> master ``` To send a pull request, you have two options. If using GitHub, you can do the pull request from there. Navigate to your repository, select the branch you just created, and then select the "Pull Request" button in the upper right. Select the user/organization "zendframework" as the recipient. If using your own repository - or even if using GitHub - you can use `git format-patch` to create a patchset for us to apply; in fact, this is **recommended** for security-related patches. If you use `format-patch`, please send the patches as attachments to: - zf-devteam@zend.com for patches without security implications - zf-security@zend.com for security patches #### What branch to issue the pull request against? Which branch should you issue a pull request against? - For fixes against the stable release, issue the pull request against the "master" branch. - For new features, or fixes that introduce new elements to the public API (such as new public methods or properties), issue the pull request against the "develop" branch. ### Branch Cleanup As you might imagine, if you are a frequent contributor, you'll start to get a ton of branches both locally and on your remote. Once you know that your changes have been accepted to the master repository, we suggest doing some cleanup of these branches. - Local branch cleanup ```console $ git branch -d ``` - Remote branch removal ```console $ git push {username} : ``` zend-eventmanager-release-2.6.2/LICENSE.md000066400000000000000000000027551264530356400201760ustar00rootroot00000000000000Copyright (c) 2005-2015, Zend Technologies USA, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Zend Technologies USA, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. zend-eventmanager-release-2.6.2/README.md000066400000000000000000000023351264530356400200430ustar00rootroot00000000000000# zend-eventmanager [![Build Status](https://secure.travis-ci.org/zendframework/zend-eventmanager.svg?branch=master)](https://secure.travis-ci.org/zendframework/zend-eventmanager) [![Coverage Status](https://coveralls.io/repos/zendframework/zend-eventmanager/badge.svg?branch=master)](https://coveralls.io/r/zendframework/zend-eventmanager?branch=master) The `Zend\EventManager` is a component designed for the following use cases: - Implementing simple subject/observer patterns. - Implementing Aspect-Oriented designs. - Implementing event-driven architectures. The basic architecture allows you to attach and detach listeners to named events, both on a per-instance basis as well as via shared collections; trigger events; and interrupt execution of listeners. - File issues at https://github.com/zendframework/zend-eventmanager/issues - Documentation is at http://framework.zend.com/manual/current/en/index.html#zend-eventmanager ## Benchmarks We provide scripts for benchmarking zend-eventmanager using the [Athletic](https://github.com/polyfractal/athletic) framework; these can be found in the `benchmarks/` directory. To execute the benchmarks you can run the following command: ```bash $ vendor/bin/athletic -p benchmarks ``` zend-eventmanager-release-2.6.2/composer.json000066400000000000000000000016351264530356400213100ustar00rootroot00000000000000{ "name": "zendframework/zend-eventmanager", "description": " ", "license": "BSD-3-Clause", "keywords": [ "zf2", "eventmanager" ], "homepage": "https://github.com/zendframework/zend-eventmanager", "autoload": { "psr-4": { "Zend\\EventManager\\": "src/" } }, "require": { "php": ">=5.5", "zendframework/zend-stdlib": "~2.5" }, "minimum-stability": "dev", "prefer-stable": true, "extra": { "branch-alias": { "dev-master": "2.6-dev", "dev-develop": "3.0-dev" } }, "autoload-dev": { "psr-4": { "ZendTest\\EventManager\\": "test/", "ZendBench\\EventManager\\": "benchmarks/" } }, "require-dev": { "fabpot/php-cs-fixer": "1.7.*", "phpunit/PHPUnit": "~4.0", "athletic/athletic": "dev-master" } } zend-eventmanager-release-2.6.2/src/000077500000000000000000000000001264530356400173505ustar00rootroot00000000000000zend-eventmanager-release-2.6.2/src/AbstractListenerAggregate.php000066400000000000000000000015071264530356400251440ustar00rootroot00000000000000listeners as $index => $callback) { if ($events->detach($callback)) { unset($this->listeners[$index]); } } } } zend-eventmanager-release-2.6.2/src/Event.php000066400000000000000000000110231264530356400211370ustar00rootroot00000000000000setName($name); } if (null !== $target) { $this->setTarget($target); } if (null !== $params) { $this->setParams($params); } } /** * Get event name * * @return string */ public function getName() { return $this->name; } /** * Get the event target * * This may be either an object, or the name of a static method. * * @return string|object */ public function getTarget() { return $this->target; } /** * Set parameters * * Overwrites parameters * * @param array|ArrayAccess|object $params * @return Event * @throws Exception\InvalidArgumentException */ public function setParams($params) { if (!is_array($params) && !is_object($params)) { throw new Exception\InvalidArgumentException( sprintf('Event parameters must be an array or object; received "%s"', gettype($params)) ); } $this->params = $params; return $this; } /** * Get all parameters * * @return array|object|ArrayAccess */ public function getParams() { return $this->params; } /** * Get an individual parameter * * If the parameter does not exist, the $default value will be returned. * * @param string|int $name * @param mixed $default * @return mixed */ public function getParam($name, $default = null) { // Check in params that are arrays or implement array access if (is_array($this->params) || $this->params instanceof ArrayAccess) { if (!isset($this->params[$name])) { return $default; } return $this->params[$name]; } // Check in normal objects if (!isset($this->params->{$name})) { return $default; } return $this->params->{$name}; } /** * Set the event name * * @param string $name * @return Event */ public function setName($name) { $this->name = (string) $name; return $this; } /** * Set the event target/context * * @param null|string|object $target * @return Event */ public function setTarget($target) { $this->target = $target; return $this; } /** * Set an individual parameter to a value * * @param string|int $name * @param mixed $value * @return Event */ public function setParam($name, $value) { if (is_array($this->params) || $this->params instanceof ArrayAccess) { // Arrays or objects implementing array access $this->params[$name] = $value; } else { // Objects $this->params->{$name} = $value; } return $this; } /** * Stop further event propagation * * @param bool $flag * @return void */ public function stopPropagation($flag = true) { $this->stopPropagation = (bool) $flag; } /** * Is propagation stopped? * * @return bool */ public function propagationIsStopped() { return $this->stopPropagation; } } zend-eventmanager-release-2.6.2/src/EventInterface.php000066400000000000000000000037651264530356400227760ustar00rootroot00000000000000setIdentifiers($identifiers); } /** * Set the event class to utilize * * @deprecated This method is deprecated with 2.6.0, and will be removed in 3.0.0. * See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/removed.md} * for details. * @param string $class * @return EventManager */ public function setEventClass($class) { $this->eventClass = $class; return $this; } /** * Set shared event manager * * @deprecated This method is deprecated with 2.6.0, and will be removed in 3.0.0. * See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/removed.md} * for details. * @param SharedEventManagerInterface $sharedEventManager * @return EventManager */ public function setSharedManager(SharedEventManagerInterface $sharedEventManager) { $this->sharedManager = $sharedEventManager; StaticEventManager::setInstance($sharedEventManager); return $this; } /** * Remove any shared event manager currently attached * * @deprecated This method is deprecated with 2.6.0, and will be removed in 3.0.0. * See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/removed.md} * for details. * @return void */ public function unsetSharedManager() { $this->sharedManager = false; } /** * Get shared event manager * * If one is not defined, but we have a static instance in * StaticEventManager, that one will be used and set in this instance. * * If none is available in the StaticEventManager, a boolean false is * returned. * * @return false|SharedEventManagerInterface */ public function getSharedManager() { // "false" means "I do not want a shared manager; don't try and fetch one" if (false === $this->sharedManager || $this->sharedManager instanceof SharedEventManagerInterface ) { return $this->sharedManager; } if (!StaticEventManager::hasInstance()) { return false; } $this->sharedManager = StaticEventManager::getInstance(); return $this->sharedManager; } /** * Get the identifier(s) for this EventManager * * @return array */ public function getIdentifiers() { return $this->identifiers; } /** * Set the identifiers (overrides any currently set identifiers) * * @param string|int|array|Traversable $identifiers * @return EventManager Provides a fluent interface */ public function setIdentifiers($identifiers) { if (is_array($identifiers) || $identifiers instanceof Traversable) { $this->identifiers = array_unique((array) $identifiers); } elseif ($identifiers !== null) { $this->identifiers = [$identifiers]; } return $this; } /** * Add some identifier(s) (appends to any currently set identifiers) * * @param string|int|array|Traversable $identifiers * @return EventManager Provides a fluent interface */ public function addIdentifiers($identifiers) { if (is_array($identifiers) || $identifiers instanceof Traversable) { $this->identifiers = array_unique(array_merge($this->identifiers, (array) $identifiers)); } elseif ($identifiers !== null) { $this->identifiers = array_unique(array_merge($this->identifiers, [$identifiers])); } return $this; } /** * Trigger all listeners for a given event * * @param string|EventInterface $event * @param string|object $target Object calling emit, or symbol describing target (such as static method name) * @param array|ArrayAccess $argv Array of arguments; typically, should be associative * @param null|callable $callback Trigger listeners until return value of this callback evaluate to true * @return ResponseCollection All listener return values * @throws Exception\InvalidCallbackException */ public function trigger($event, $target = null, $argv = [], $callback = null) { if ($event instanceof EventInterface) { $e = $event; $event = $e->getName(); $callback = $target; } elseif ($target instanceof EventInterface) { $e = $target; $e->setName($event); $callback = $argv; } elseif ($argv instanceof EventInterface) { $e = $argv; $e->setName($event); $e->setTarget($target); } else { $e = new $this->eventClass(); $e->setName($event); $e->setTarget($target); $e->setParams($argv); } if ($callback && !is_callable($callback)) { throw new Exception\InvalidCallbackException('Invalid callback provided'); } // Initial value of stop propagation flag should be false $e->stopPropagation(false); return $this->triggerListeners($event, $e, $callback); } /** * Trigger listeners until return value of one causes a callback to * evaluate to true * * Triggers listeners until the provided callback evaluates the return * value of one as true, or until all listeners have been executed. * * @deprecated The signature of this method will change in 3.0.0. * See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/changed.md} * for details. * @param string|EventInterface $event * @param string|object $target Object calling emit, or symbol describing target (such as static method name) * @param array|ArrayAccess $argv Array of arguments; typically, should be associative * @param callable $callback * @return ResponseCollection * @throws Exception\InvalidCallbackException if invalid callable provided */ public function triggerUntil($event, $target, $argv = null, $callback = null) { trigger_error( 'This method is deprecated and will be removed in the future. Please use trigger() instead.', E_USER_DEPRECATED ); return $this->trigger($event, $target, $argv, $callback); } /** * Trigger an event instance. * * @param EventInterface $event * @return ResponseCollection */ public function triggerEvent(EventInterface $event) { return $this->triggerListeners($event->getName(), $event); } /** * Trigger an event instance, short-circuiting if a listener response evaluates true via the callback. * * @param callable $callback * @param EventInterface $event * @return ResponseCollection */ public function triggerEventUntil(callable $callback, EventInterface $event) { return $this->triggerListeners($event->getName(), $event, $callback); } /** * Attach a listener to an event * * The first argument is the event, and the next argument describes a * callback that will respond to that event. A CallbackHandler instance * describing the event listener combination will be returned. * * The last argument indicates a priority at which the event should be * executed. By default, this value is 1; however, you may set it for any * integer value. Higher values have higher priority (i.e., execute first). * * You can specify "*" for the event name. In such cases, the listener will * be triggered for every event. * * @param string|array|ListenerAggregateInterface $event An event or array of event names. If a ListenerAggregateInterface, proxies to {@link attachAggregate()}. * @param callable|int $callback If string $event provided, expects PHP callback; for a ListenerAggregateInterface $event, this will be the priority * @param int $priority If provided, the priority at which to register the callable * @return CallbackHandler|mixed CallbackHandler if attaching callable (to allow later unsubscribe); mixed if attaching aggregate * @throws Exception\InvalidArgumentException */ public function attach($event, $callback = null, $priority = 1) { // Proxy ListenerAggregateInterface arguments to attachAggregate() if ($event instanceof ListenerAggregateInterface) { return $this->attachAggregate($event, $callback); } // Null callback is invalid if (null === $callback) { throw new Exception\InvalidArgumentException(sprintf( '%s: expects a callback; none provided', __METHOD__ )); } // Array of events should be registered individually, and return an array of all listeners if (is_array($event)) { $listeners = []; foreach ($event as $name) { $listeners[] = $this->attach($name, $callback, $priority); } return $listeners; } // If we don't have a priority queue for the event yet, create one if (empty($this->events[$event])) { $this->events[$event] = new PriorityQueue(); } // Create a callback handler, setting the event and priority in its metadata $listener = new CallbackHandler($callback, ['event' => $event, 'priority' => $priority]); // Inject the callback handler into the queue $this->events[$event]->insert($listener, $priority); return $listener; } /** * Attach a listener aggregate * * Listener aggregates accept an EventManagerInterface instance, and call attach() * one or more times, typically to attach to multiple events using local * methods. * * @deprecated This method is deprecated with 2.6.0, and will be removed in 3.0.0. * See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/removed.md} * for details. * @param ListenerAggregateInterface $aggregate * @param int $priority If provided, a suggested priority for the aggregate to use * @return mixed return value of {@link ListenerAggregateInterface::attach()} */ public function attachAggregate(ListenerAggregateInterface $aggregate, $priority = 1) { return $aggregate->attach($this, $priority); } /** * Unsubscribe a listener from an event * * @param CallbackHandler|ListenerAggregateInterface $listener * @return bool Returns true if event and listener found, and unsubscribed; returns false if either event or listener not found * @throws Exception\InvalidArgumentException if invalid listener provided */ public function detach($listener) { if ($listener instanceof ListenerAggregateInterface) { return $this->detachAggregate($listener); } if (!$listener instanceof CallbackHandler) { throw new Exception\InvalidArgumentException(sprintf( '%s: expected a ListenerAggregateInterface or CallbackHandler; received "%s"', __METHOD__, (is_object($listener) ? get_class($listener) : gettype($listener)) )); } $event = $listener->getMetadatum('event'); if (!$event || empty($this->events[$event])) { return false; } $return = $this->events[$event]->remove($listener); if (!$return) { return false; } if (!count($this->events[$event])) { unset($this->events[$event]); } return true; } /** * Detach a listener aggregate * * Listener aggregates accept an EventManagerInterface instance, and call detach() * of all previously attached listeners. * * @deprecated This method is deprecated with 2.6.0, and will be removed in 3.0.0. * See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/removed.md} * for details. * @param ListenerAggregateInterface $aggregate * @return mixed return value of {@link ListenerAggregateInterface::detach()} */ public function detachAggregate(ListenerAggregateInterface $aggregate) { return $aggregate->detach($this); } /** * Retrieve all registered events * * @deprecated This method is deprecated with 2.6.0, and will be removed in 3.0.0. * See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/removed.md} * for details. * @return array */ public function getEvents() { return array_keys($this->events); } /** * Retrieve all listeners for a given event * * @deprecated This method is deprecated with 2.6.0, and will be removed in 3.0.0. * See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/removed.md} * for details. * @param string $event * @return PriorityQueue */ public function getListeners($event) { if (!array_key_exists($event, $this->events)) { return new PriorityQueue(); } return $this->events[$event]; } /** * Clear all listeners for a given event * * @param string $event * @return void */ public function clearListeners($event) { if (!empty($this->events[$event])) { unset($this->events[$event]); } } /** * Prepare arguments * * Use this method if you want to be able to modify arguments from within a * listener. It returns an ArrayObject of the arguments, which may then be * passed to trigger(). * * @param array $args * @return ArrayObject */ public function prepareArgs(array $args) { return new ArrayObject($args); } /** * Trigger listeners * * Actual functionality for triggering listeners, to which trigger() delegate. * * @param string $event Event name * @param EventInterface $e * @param null|callable $callback * @return ResponseCollection */ protected function triggerListeners($event, EventInterface $e, $callback = null) { $responses = new ResponseCollection; $listeners = $this->getListeners($event); // Add shared/wildcard listeners to the list of listeners, // but don't modify the listeners object $sharedListeners = $this->getSharedListeners($event); $sharedWildcardListeners = $this->getSharedListeners('*'); $wildcardListeners = $this->getListeners('*'); if (count($sharedListeners) || count($sharedWildcardListeners) || count($wildcardListeners)) { $listeners = clone $listeners; // Shared listeners on this specific event $this->insertListeners($listeners, $sharedListeners); // Shared wildcard listeners $this->insertListeners($listeners, $sharedWildcardListeners); // Add wildcard listeners $this->insertListeners($listeners, $wildcardListeners); } foreach ($listeners as $listener) { $listenerCallback = $listener->getCallback(); // Trigger the listener's callback, and push its result onto the // response collection $responses->push(call_user_func($listenerCallback, $e)); // If the event was asked to stop propagating, do so if ($e->propagationIsStopped()) { $responses->setStopped(true); break; } // If the result causes our validation callback to return true, // stop propagation if ($callback && call_user_func($callback, $responses->last())) { $responses->setStopped(true); break; } } return $responses; } /** * Get list of all listeners attached to the shared event manager for * identifiers registered by this instance * * @param string $event * @return array */ protected function getSharedListeners($event) { if (!$sharedManager = $this->getSharedManager()) { return []; } $identifiers = $this->getIdentifiers(); //Add wildcard id to the search, if not already added if (!in_array('*', $identifiers)) { $identifiers[] = '*'; } $sharedListeners = []; foreach ($identifiers as $id) { if (!$listeners = $sharedManager->getListeners($id, $event)) { continue; } if (!is_array($listeners) && !($listeners instanceof Traversable)) { continue; } foreach ($listeners as $listener) { if (!$listener instanceof CallbackHandler) { continue; } $sharedListeners[] = $listener; } } return $sharedListeners; } /** * Add listeners to the master queue of listeners * * Used to inject shared listeners and wildcard listeners. * * @param PriorityQueue $masterListeners * @param array|Traversable $listeners * @return void */ protected function insertListeners($masterListeners, $listeners) { foreach ($listeners as $listener) { $priority = $listener->getMetadatum('priority'); if (null === $priority) { $priority = 1; } elseif (is_array($priority)) { // If we have an array, likely using PriorityQueue. Grab first // element of the array, as that's the actual priority. $priority = array_shift($priority); } $masterListeners->insert($listener, $priority); } } } zend-eventmanager-release-2.6.2/src/EventManagerAwareInterface.php000066400000000000000000000012721264530356400252400ustar00rootroot00000000000000eventIdentifier property. * * @param EventManagerInterface $events * @return mixed */ public function setEventManager(EventManagerInterface $events) { $identifiers = [__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; if (method_exists($this, 'attachDefaultListeners')) { $this->attachDefaultListeners(); } 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 EventManager()); } return $this->events; } } zend-eventmanager-release-2.6.2/src/EventManagerInterface.php000066400000000000000000000127371264530356400242700ustar00rootroot00000000000000setExtractFlags(self::EXTR_BOTH); // Iterate and remove any matches $removed = false; $items = []; $this->rewind(); while (!$this->isEmpty()) { $item = $this->extract(); if ($item['data'] === $datum) { $removed = true; continue; } $items[] = $item; } // Repopulate foreach ($items as $item) { $this->insert($item['data'], $item['priority']); } $this->setExtractFlags(self::EXTR_DATA); return $removed; } /** * Iterate the next filter in the chain * * Iterates and calls the next filter in the chain. * * @param mixed $context * @param array $params * @param FilterIterator $chain * @return mixed */ public function next($context = null, array $params = [], $chain = null) { if (empty($context) || ($chain instanceof FilterIterator && $chain->isEmpty())) { return; } //We can't extract from an empty heap if ($this->isEmpty()) { return; } $next = $this->extract(); if (!$next instanceof CallbackHandler) { return; } $return = call_user_func($next->getCallback(), $context, $params, $chain); return $return; } } zend-eventmanager-release-2.6.2/src/FilterChain.php000066400000000000000000000056441264530356400222620ustar00rootroot00000000000000filters = new Filter\FilterIterator(); } /** * Apply the filters * * Begins iteration of the filters. * * @param mixed $context Object under observation * @param mixed $argv Associative array of arguments * @return mixed */ public function run($context, array $argv = []) { $chain = clone $this->getFilters(); if ($chain->isEmpty()) { return; } $next = $chain->extract(); if (!$next instanceof CallbackHandler) { return; } return call_user_func($next->getCallback(), $context, $argv, $chain); } /** * Connect a filter to the chain * * @param callable $callback PHP Callback * @param int $priority Priority in the queue at which to execute; defaults to 1 (higher numbers == higher priority) * @return CallbackHandler (to allow later unsubscribe) * @throws Exception\InvalidCallbackException */ public function attach($callback, $priority = 1) { if (empty($callback)) { throw new Exception\InvalidCallbackException('No callback provided'); } $filter = new CallbackHandler($callback, ['priority' => $priority]); $this->filters->insert($filter, $priority); return $filter; } /** * Detach a filter from the chain * * @param CallbackHandler $filter * @return bool Returns true if filter found and unsubscribed; returns false otherwise */ public function detach(CallbackHandler $filter) { return $this->filters->remove($filter); } /** * Retrieve all filters * * @return Filter\FilterIterator */ public function getFilters() { return $this->filters; } /** * Clear all filters * * @return void */ public function clearFilters() { $this->filters = new Filter\FilterIterator(); } /** * Return current responses * * Only available while the chain is still being iterated. Returns the * current ResponseCollection. * * @return null|ResponseCollection */ public function getResponses() { return; } } zend-eventmanager-release-2.6.2/src/GlobalEventManager.php000066400000000000000000000074421264530356400235650ustar00rootroot00000000000000trigger($event, $context, $argv, $callback); } /** * Trigger listeners until return value of one causes a callback to evaluate * to true. * * @param string $event * @param string|object $context * @param array|object $argv * @param callable $callback * @return ResponseCollection * @deprecated Please use trigger() */ public static function triggerUntil($event, $context, $argv, $callback) { trigger_error( 'This method is deprecated and will be removed in the future. Please use trigger() instead.', E_USER_DEPRECATED ); return static::trigger($event, $context, $argv, $callback); } /** * Attach a listener to an event * * @param string $event * @param callable $callback * @param int $priority * @return CallbackHandler */ public static function attach($event, $callback, $priority = 1) { return static::getEventCollection()->attach($event, $callback, $priority); } /** * Detach a callback from a listener * * @param CallbackHandler $listener * @return bool */ public static function detach(CallbackHandler $listener) { return static::getEventCollection()->detach($listener); } /** * Retrieve list of events this object manages * * @return array */ public static function getEvents() { return static::getEventCollection()->getEvents(); } /** * Retrieve all listeners for a given event * * @param string $event * @return PriorityQueue|array */ public static function getListeners($event) { return static::getEventCollection()->getListeners($event); } /** * Clear all listeners for a given event * * @param string $event * @return void */ public static function clearListeners($event) { static::getEventCollection()->clearListeners($event); } } zend-eventmanager-release-2.6.2/src/ListenerAggregateInterface.php000066400000000000000000000023351264530356400253010ustar00rootroot00000000000000listeners as $index => $callback) { if ($events->detach($callback)) { unset($this->listeners[$index]); } } } } zend-eventmanager-release-2.6.2/src/ProvidesEvents.php000066400000000000000000000013531264530356400230430ustar00rootroot00000000000000stopped; } /** * Mark the collection as stopped (or its opposite) * * @param bool $flag * @return ResponseCollection */ public function setStopped($flag) { $this->stopped = (bool) $flag; return $this; } /** * Convenient access to the first handler return value. * * @return mixed The first handler return value */ public function first() { return parent::bottom(); } /** * Convenient access to the last handler return value. * * If the collection is empty, returns null. Otherwise, returns value * returned by last handler. * * @return mixed The last handler return value */ public function last() { if (count($this) === 0) { return; } return parent::top(); } /** * Check if any of the responses match the given value. * * @param mixed $value The value to look for among responses * @return bool */ public function contains($value) { foreach ($this as $response) { if ($response === $value) { return true; } } return false; } } zend-eventmanager-release-2.6.2/src/SharedEventAggregateAwareInterface.php000066400000000000000000000025401264530356400267020ustar00rootroot00000000000000 * $sharedEventManager = new SharedEventManager(); * $sharedEventManager->attach( * array('My\Resource\AbstractResource', 'My\Resource\EntityResource'), * 'getAll', * function ($e) use ($cache) { * if (!$id = $e->getParam('id', false)) { * return; * } * if (!$data = $cache->load(get_class($resource) . '::getOne::' . $id )) { * return; * } * return $data; * } * ); * * * @param string|array $id Identifier(s) for event emitting component(s) * @param string $event * @param callable $callback PHP Callback * @param int $priority Priority at which listener should execute * @return CallbackHandler|array Either CallbackHandler or array of CallbackHandlers */ public function attach($id, $event, $callback, $priority = 1) { $ids = (array) $id; $listeners = []; foreach ($ids as $id) { if (!array_key_exists($id, $this->identifiers)) { $this->identifiers[$id] = new EventManager($id); } $listeners[] = $this->identifiers[$id]->attach($event, $callback, $priority); } if (count($listeners) > 1) { return $listeners; } return $listeners[0]; } /** * Attach a listener aggregate * * Listener aggregates accept an EventManagerInterface instance, and call attachShared() * one or more times, typically to attach to multiple events using local * methods. * * @param SharedListenerAggregateInterface $aggregate * @param int $priority If provided, a suggested priority for the aggregate to use * @return mixed return value of {@link ListenerAggregateInterface::attachShared()} */ public function attachAggregate(SharedListenerAggregateInterface $aggregate, $priority = 1) { return $aggregate->attachShared($this, $priority); } /** * Detach a listener from an event offered by a given resource * * @param string|int $id * @param CallbackHandler $listener * @return bool Returns true if event and listener found, and unsubscribed; returns false if either event or listener not found */ public function detach($id, CallbackHandler $listener) { if (!array_key_exists($id, $this->identifiers)) { return false; } return $this->identifiers[$id]->detach($listener); } /** * Detach a listener aggregate * * Listener aggregates accept a SharedEventManagerInterface instance, and call detachShared() * of all previously attached listeners. * * @param SharedListenerAggregateInterface $aggregate * @return mixed return value of {@link SharedListenerAggregateInterface::detachShared()} */ public function detachAggregate(SharedListenerAggregateInterface $aggregate) { return $aggregate->detachShared($this); } /** * Retrieve all registered events for a given resource * * @deprecated This method is deprecated with 2.6.0, and will be removed in 3.0.0. * See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/removed.md} * for details. * @param string|int $id * @return array */ public function getEvents($id) { if (!array_key_exists($id, $this->identifiers)) { //Check if there are any id wildcards listeners if ('*' != $id && array_key_exists('*', $this->identifiers)) { return $this->identifiers['*']->getEvents(); } return false; } return $this->identifiers[$id]->getEvents(); } /** * Retrieve all listeners for a given identifier and event * * @param string|int $id * @param string|int $event * @return false|PriorityQueue */ public function getListeners($id, $event) { if (!array_key_exists($id, $this->identifiers)) { return false; } return $this->identifiers[$id]->getListeners($event); } /** * Clear all listeners for a given identifier, optionally for a specific event * * @param string|int $id * @param null|string $event * @return bool */ public function clearListeners($id, $event = null) { if (!array_key_exists($id, $this->identifiers)) { return false; } if (null === $event) { unset($this->identifiers[$id]); return true; } return $this->identifiers[$id]->clearListeners($event); } } zend-eventmanager-release-2.6.2/src/SharedEventManagerAwareInterface.php000066400000000000000000000021471264530356400263710ustar00rootroot00000000000000getEvents(); } /** * Retrieve an interable list of listeners for an event. * * Given an event and an event manager, returns an iterator with the * listeners for that event, in priority order. * * If $withPriority is true, the key values will be the priority at which * the given listener is attached. * * Do not pass $withPriority if you want to cast the iterator to an array, * as many listeners will likely have the same priority, and thus casting * will collapse to the last added. * * @param string $event * @param EventManager $events * @param bool $withPriority * @return \Traversable */ private function getListenersForEvent($event, EventManager $events, $withPriority = false) { $listeners = $events->getListeners($event); return $this->traverseListeners($listeners, $withPriority); } /** * Assert that a given listener exists at the specified priority. * * @param callable $expectedListener * @param int $expectedPriority * @param string $event * @param EventManager $events * @param string $message Failure message to use, if any. */ private function assertListenerAtPriority( callable $expectedListener, $expectedPriority, $event, EventManager $events, $message = '' ) { $message = $message ?: sprintf( 'Listener not found for event "%s" and priority %d', $event, $expectedPriority ); $listeners = $this->getListenersForEvent($event, $events, true); $found = false; foreach ($listeners as $priority => $listener) { if ($listener === $expectedListener && $priority === $expectedPriority ) { $found = true; break; } } Assert::assertTrue($found, $message); } /** * Returns an indexed array of listeners for an event. * * Returns an indexed array of listeners for an event, in priority order. * Priority values will not be included; use this only for testing if * specific listeners are present, or for a count of listeners. * * @param string $event * @param EventManager $events * @return callable[] */ private function getArrayOfListenersForEvent($event, EventManager $events) { return iterator_to_array($this->getListenersForEvent($event, $events)); } /** * Generator for traversing listeners in priority order. * * @param PriorityQueue $listeners * @param bool $withPriority When true, yields priority as key. */ public function traverseListeners(PriorityQueue $queue, $withPriority = false) { foreach ($queue as $handler) { $listener = $handler->getCallback(); if ($withPriority) { $priority = (int) $handler->getMetadatum('priority'); yield $priority => $listener; } else { yield $listener; } } } }