pax_global_header 0000666 0000000 0000000 00000000064 12172232500 0014504 g ustar 00root root 0000000 0000000 52 comment=14f284eede050859e72ac41064df0eac25327190
sabre-event-1.0.0/ 0000775 0000000 0000000 00000000000 12172232500 0013715 5 ustar 00root root 0000000 0000000 sabre-event-1.0.0/.gitignore 0000664 0000000 0000000 00000000125 12172232500 0015703 0 ustar 00root root 0000000 0000000 #composer
vendor
composer.lock
#vim lock files
.*.swp
#development stuff
tests/cov
sabre-event-1.0.0/.travis.yml 0000664 0000000 0000000 00000000167 12172232500 0016032 0 ustar 00root root 0000000 0000000 language: php
php:
- 5.4
- 5.5
script: phpunit --configuration tests/phpunit.xml
before_script: composer install
sabre-event-1.0.0/ChangeLog 0000664 0000000 0000000 00000000301 12172232500 0015461 0 ustar 00root root 0000000 0000000 1.0.0-stable (2013-07-19)
* Added: removeListener, removeAllListeners
* Added: once, to only listen to an event emitting once.
* Added README.md.
0.0.1-alpha (2013-06-29)
* First version!
sabre-event-1.0.0/LICENSE 0000664 0000000 0000000 00000003034 12172232500 0014722 0 ustar 00root root 0000000 0000000 Copyright (C) 2013 fruux GmbH (https://fruux.com/)
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 Sabre 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.
sabre-event-1.0.0/README.md 0000664 0000000 0000000 00000010342 12172232500 0015174 0 ustar 00root root 0000000 0000000 sabre/event
===========
A lightweight library for event management in PHP.
It's design is inspired by Node.js's [EventEmitter][1]. sabre/event requires
PHP 5.4.
It's distinct from [Événement][2], because I needed a couple of features that
were in conflict with it's design goals. Namely: prioritization, and the
ability to stop the event chain, like javascript's `preventDefault`.
Installation
------------
Make sure you have [composer][3] installed. In your project directory, create,
or edit a `composer.json` file, and make sure it contains something like this:
```json
{
"require" : {
"sabre/event" : "~0.0.1@alpha"
}
}
```
After that, just hit `composer install` and you should be rolling.
Usage
-----
In an event system there are emitters, and listeners. Emitters trigger an
event, at which point a listener is notified.
Example:
```php
use Sabre\Event\EventEmitter;
include 'vendor/autoload.php';
$eventEmitter = new EventEmitter();
// subscribing
$eventEmitter->on('create', function() {
echo "Something got created, apparently\n"
});
$eventEmitter->emit('create');
```
The name of the event (`create`) can be any free-form string.
### Priorities
By supplying a priority, you can make sure that subscribers are handled in a
specific order. The default priority is 100. Anything below that will be
triggered earlier, anything higher later.
If there's two subscribers with the same priority, they will execute in an
undefined, but deterministic order.
```php
$eventEmitter->on('create', function() {
// This event will be handled first.
}, 50);
```
### Callbacks
All default PHP callbacks are supported, so closures are not required.
```php
$eventEmitter->on('create', 'myFunction');
$eventEmitter->on('create', ['myClass', 'myMethod']);
$eventEmitter->on('create', [$myInstance, 'myMethod']);
```
### Canceling the event handler.
If a callback returns `false` the event chain is stopped immidiately.
A usecase is to use a listener to check if a user has permission to perform
a certain action, and stop execution if they don't.
```php
$eventEmitter->on('create', function() {
if (!checkPermission()) {
return false;
}
}, 10);
```
`EventEmitter::emit()` will return `false` if the event was cancelled, and
true if it wasn't.
SabreDAV uses this feature heavily as well. When a HTTP request is received
various plugins see if they are capable of handling the request. If they
do, they can return false so other plugins will not also attempt to handle
the request.
Throwing an exception will also stop the chain.
### Passing arguments
Arguments can be passed as an array.
```php
$eventEmitter->on('create', function($entityId) {
echo "An entity with id ", $entityId, " just got created.\n";
});
$entityId = 5;
$eventEmitter->emit('create', [$entityId]);
```
Because you cannot really do anything with the return value of a listener,
you can pass arguments by reference to communicate between listeners and
back to the emitter.
```php
$eventEmitter->on('create', function($entityId, &$warnings) {
echo "An entity with id ", $entityId, " just got created.\n";
$warnings[] = "Something bad may or may not have happened.\n";
});
$warnings = [];
$eventEmitter->emit('create', [$entityId, &$warnings]);
print_r($warnings);
```
### Integration into other objects.
To add `EventEmitter` capabilities to any class, you can simply extend it.
If you cannot extend, because the class is already part of an existing class
hierarchy you can use the supplied trait.
```php
use Sabre\Event;
class MyNotUneventfulApplication
extends AppController
implements Event\EventEmitterInterface
{
use Event\EventEmitterTrait();
}
```
In the preceeding example, `MyNotUneventfulApplication` has all the
capabilities of `EventEmitter`.
Questions?
----------
Head over to the [sabre/dav mailinglist][4], or you can also just open a ticket
on [GitHub][5].
Made at fruux
-------------
This library is being developed by [fruux](https://fruux.com/). Drop us a line for commercial services or enterprise support.
[1]: http://nodejs.org/api/events.html
[2]: https://github.com/igorw/evenement
[3]: http://getcomposer.org/
[4]: http://groups.google.com/group/sabredav-discuss
[5]: https://github.com/fruux/sabre-event/issues/
sabre-event-1.0.0/composer.json 0000664 0000000 0000000 00000001405 12172232500 0016437 0 ustar 00root root 0000000 0000000 {
"name": "sabre/event",
"description" : "The sabre/event library provides utilities for lightweight event-based programming",
"keywords" : [ "Events" ],
"homepage" : "https://github.com/fruux/sabre-event",
"license" : "BSD-3-Clause",
"require" : {
"php" : ">=5.4.1"
},
"authors" : [
{
"name" : "Evert Pot",
"email" : "evert@rooftopsolutions.nl",
"homepage" : "http://evertpot.com/",
"role" : "Developer"
}
],
"support" : {
"forum" : "https://groups.google.com/group/sabredav-discuss",
"source" : "https://github.com/fruux/sabre-event"
},
"autoload" : {
"psr-0" : {
"Sabre\\Event" : "lib/"
}
}
}
sabre-event-1.0.0/lib/ 0000775 0000000 0000000 00000000000 12172232500 0014463 5 ustar 00root root 0000000 0000000 sabre-event-1.0.0/lib/Sabre/ 0000775 0000000 0000000 00000000000 12172232500 0015517 5 ustar 00root root 0000000 0000000 sabre-event-1.0.0/lib/Sabre/Event/ 0000775 0000000 0000000 00000000000 12172232500 0016600 5 ustar 00root root 0000000 0000000 sabre-event-1.0.0/lib/Sabre/Event/EventEmitter.php 0000664 0000000 0000000 00000000635 12172232500 0021730 0 ustar 00root root 0000000 0000000 listeners($eventName);
$listeners[] = [$priority, $callBack];
usort($listeners, function($a, $b) {
return $a[0]-$b[0];
});
}
/**
* Subscribe to an event exactly once.
*
* @param string $eventName
* @param callable $callBack
* @param int $priority
* @return void
*/
public function once($eventName, callable $callBack, $priority = 100) {
$wrapper = null;
$wrapper = function() use ($eventName, $callBack, &$wrapper) {
$this->removeListener($eventName, $wrapper);
$result = call_user_func_array($callBack, func_get_args());
};
$this->on($eventName, $wrapper);
}
/**
* Emits an event.
*
* This method will return true if 0 or more listeners were succesfully
* handled. false is returned if one of the events broke the event chain.
*
* @param string $eventName
* @param array $arguments
* @return bool
*/
public function emit($eventName, array $arguments = []) {
foreach($this->listeners($eventName) as $listener) {
$result = call_user_func_array($listener[1], $arguments);
if ($result === false) {
return false;
}
}
return true;
}
/**
* Returns the list of listeners for an event.
*
* The list is returned as an array. Every item is another array with 2
* elements: priority and the callback.
*
* The array is returned by reference, and can therefore be used to
* manipulate the list of events.
*
* @param string $eventName
* @return array
*/
public function &listeners($eventName) {
if (!isset($this->listeners[$eventName])) {
$this->listeners[$eventName] = [];
}
return $this->listeners[$eventName];
}
/**
* Removes a specific listener from an event.
*
* @param string $eventName
* @param callable $listener
* @return void
*/
public function removeListener($eventName, callable $listener) {
$listeners =& $this->listeners($eventName);
foreach($listeners as $index => $check) {
if ($check[1]===$listener) {
unset($listeners[$index]);
break;
}
}
}
/**
* Removes all listeners from the specified event.
*
* @param string $eventName
* @return void
*/
public function removeAllListeners($eventName) {
$listeners =& $this->listeners($eventName);
$listeners = [];
}
}
sabre-event-1.0.0/lib/Sabre/Event/Version.php 0000664 0000000 0000000 00000000564 12172232500 0020743 0 ustar 00root root 0000000 0000000 assertInstanceOf('Sabre\\Event\\EventEmitter', $ee);
}
/**
* @depends testInit
*/
function testHandleEvent() {
$argResult = null;
$ee = new EventEmitter();
$ee->on('foo', function($arg) use (&$argResult) {
$argResult = $arg;
});
$this->assertTrue(
$ee->emit('foo', ['bar'])
);
$this->assertEquals('bar', $argResult);
}
/**
* @depends testHandleEvent
*/
function testCancelEvent() {
$argResult = 0;
$ee = new EventEmitter();
$ee->on('foo', function($arg) use (&$argResult) {
$argResult = 1;
return false;
});
$ee->on('foo', function($arg) use (&$argResult) {
$argResult = 2;
});
$this->assertFalse(
$ee->emit('foo', ['bar'])
);
$this->assertEquals(1, $argResult);
}
/**
* @depends testCancelEvent
*/
function testPriority() {
$argResult = 0;
$ee = new EventEmitter();
$ee->on('foo', function($arg) use (&$argResult) {
$argResult = 1;
return false;
});
$ee->on('foo', function($arg) use (&$argResult) {
$argResult = 2;
return false;
}, 1);
$this->assertFalse(
$ee->emit('foo', ['bar'])
);
$this->assertEquals(2, $argResult);
}
/**
* @depends testPriority
*/
function testPriority2() {
$result = [];
$ee = new EventEmitter();
$ee->on('foo', function() use (&$result) {
$result[] = 'a';
}, 200);
$ee->on('foo', function() use (&$result) {
$result[] = 'b';
}, 50);
$ee->on('foo', function() use (&$result) {
$result[] = 'c';
}, 300);
$ee->on('foo', function() use (&$result) {
$result[] = 'd';
});
$ee->emit('foo');
$this->assertEquals(['b','d','a','c'], $result);
}
function testRemoveListener() {
$result = false;
$callBack = function() use (&$result) {
$result = true;
};
$ee = new EventEmitter();
$ee->on('foo', $callBack);
$ee->emit('foo');
$this->assertTrue($result);
$result = false;
$ee->removeListener('foo', $callBack);
$ee->emit('foo');
$this->assertFalse($result);
}
function testRemoveAllListeners() {
$result = false;
$callBack = function() use (&$result) {
$result = true;
};
$ee = new EventEmitter();
$ee->on('foo', $callBack);
$ee->emit('foo');
$this->assertTrue($result);
$result = false;
$ee->removeAllListeners('foo');
$ee->emit('foo');
$this->assertFalse($result);
}
function testOnce() {
$result = 0;
$callBack = function() use (&$result) {
$result++;
};
$ee = new EventEmitter();
$ee->once('foo', $callBack);
$ee->emit('foo');
$ee->emit('foo');
$this->assertEquals(1, $result);
}
}
sabre-event-1.0.0/tests/bootstrap.php 0000664 0000000 0000000 00000000064 12172232500 0017605 0 ustar 00root root 0000000 0000000
Sabre/
../lib/