File manager - Edit - /home/jardides/www/Jardi-design/images/administrator/event.tar
Back
event.php 0000644 00000003341 15247132625 0006406 0 ustar 00 <?php /** * @package Joomla.Platform * @subpackage Event * * @copyright (C) 2005 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE */ defined('JPATH_PLATFORM') or die; /** * JEvent Class * * @since 1.5 * @deprecated 4.0 The CMS' Event classes will be replaced with the `joomla/event` package */ abstract class JEvent extends JObject { /** * Event object to observe. * * @var object * @since 2.5 */ protected $_subject = null; /** * Constructor * * @param object &$subject The object to observe. * * @since 2.5 */ public function __construct(&$subject) { // Register the observer ($this) so we can be notified $subject->attach($this); // Set the subject to observe $this->_subject = &$subject; } /** * Method to trigger events. * The method first generates the even from the argument array. Then it unsets the argument * since the argument has no bearing on the event handler. * If the method exists it is called and returns its return value. If it does not exist it * returns null. * * @param array &$args Arguments * * @return mixed Routine return value * * @since 1.5 */ public function update(&$args) { // First let's get the event from the argument array. Next we will unset the // event argument as it has no bearing on the method to handle the event. $event = $args['event']; unset($args['event']); /* * If the method to handle an event exists, call it and return its return * value. If it does not exist, return null. */ if (method_exists($this, $event)) { return call_user_func_array(array($this, $event), array_values($args)); } } } index.html 0000644 00000000037 15247132625 0006550 0 ustar 00 <!DOCTYPE html><title></title> dispatcher.php 0000644 00000013373 15247132625 0007421 0 ustar 00 <?php /** * @package Joomla.Platform * @subpackage Event * * @copyright (C) 2005 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE */ defined('JPATH_PLATFORM') or die; /** * Class to handle dispatching of events. * * This is the Observable part of the Observer design pattern * for the event architecture. * * @see JPlugin * @since 3.0.0 * @deprecated 4.0 The CMS' Event classes will be replaced with the `joomla/event` package */ class JEventDispatcher extends JObject { /** * An array of Observer objects to notify * * @var array * @since 3.0.0 */ protected $_observers = array(); /** * The state of the observable object * * @var mixed * @since 3.0.0 */ protected $_state = null; /** * A multi dimensional array of [function][] = key for observers * * @var array * @since 3.0.0 */ protected $_methods = array(); /** * Stores the singleton instance of the dispatcher. * * @var JEventDispatcher * @since 3.0.0 */ protected static $instance = null; /** * Returns the global Event Dispatcher object, only creating it * if it doesn't already exist. * * @return JEventDispatcher The EventDispatcher object. * * @since 3.0.0 */ public static function getInstance() { if (self::$instance === null) { self::$instance = new static; } return self::$instance; } /** * Get the state of the JEventDispatcher object * * @return mixed The state of the object. * * @since 3.0.0 */ public function getState() { return $this->_state; } /** * Registers an event handler to the event dispatcher * * @param string $event Name of the event to register handler for * @param string $handler Name of the event handler * * @return void * * @since 3.0.0 * @throws InvalidArgumentException */ public function register($event, $handler) { // Are we dealing with a class or callback type handler? if (is_callable($handler)) { // Ok, function type event handler... let's attach it. $method = array('event' => $event, 'handler' => $handler); $this->attach($method); } elseif (class_exists($handler)) { // Ok, class type event handler... let's instantiate and attach it. $this->attach(new $handler($this)); } else { throw new InvalidArgumentException('Invalid event handler.'); } } /** * Triggers an event by dispatching arguments to all observers that handle * the event and returning their return values. * * @param string $event The event to trigger. * @param array $args An array of arguments. * * @return array An array of results from each function call. * * @since 3.0.0 */ public function trigger($event, $args = array()) { $result = array(); /* * If no arguments were passed, we still need to pass an empty array to * the call_user_func_array function. */ $args = (array) $args; $event = strtolower($event); // Check if any plugins are attached to the event. if (!isset($this->_methods[$event]) || empty($this->_methods[$event])) { // No Plugins Associated To Event! return $result; } // Loop through all plugins having a method matching our event foreach ($this->_methods[$event] as $key) { // Check if the plugin is present. if (!isset($this->_observers[$key])) { continue; } // Fire the event for an object based observer. if (is_object($this->_observers[$key])) { $args['event'] = $event; $value = $this->_observers[$key]->update($args); } // Fire the event for a function based observer. elseif (is_array($this->_observers[$key])) { $value = call_user_func_array($this->_observers[$key]['handler'], array_values($args)); } if (isset($value)) { $result[] = $value; } } return $result; } /** * Attach an observer object * * @param object $observer An observer object to attach * * @return void * * @since 3.0.0 */ public function attach($observer) { if (is_array($observer)) { if (!isset($observer['handler']) || !isset($observer['event']) || !is_callable($observer['handler'])) { return; } // Make sure we haven't already attached this array as an observer foreach ($this->_observers as $check) { if (is_array($check) && $check['event'] === $observer['event'] && $check['handler'] === $observer['handler']) { return; } } $this->_observers[] = $observer; $methods = array($observer['event']); } else { if (!($observer instanceof JEvent)) { return; } // Make sure we haven't already attached this object as an observer $class = get_class($observer); foreach ($this->_observers as $check) { if ($check instanceof $class) { return; } } $this->_observers[] = $observer; $methods = array_diff(get_class_methods($observer), get_class_methods('JPlugin')); } end($this->_observers); $key = key($this->_observers); foreach ($methods as $method) { $method = strtolower($method); if (!isset($this->_methods[$method])) { $this->_methods[$method] = array(); } $this->_methods[$method][] = $key; } } /** * Detach an observer object * * @param object $observer An observer object to detach. * * @return boolean True if the observer object was detached. * * @since 3.0.0 */ public function detach($observer) { $retval = false; $key = array_search($observer, $this->_observers); if ($key !== false) { unset($this->_observers[$key]); $retval = true; foreach ($this->_methods as &$method) { $k = array_search($key, $method); if ($k !== false) { unset($method[$k]); } } } return $retval; } } lib/EventEmitterInterface.php 0000604 00000005677 15247165557 0012313 0 ustar 00 <?php namespace Sabre\Event; /** * Event Emitter Interface * * Anything that accepts listeners and emits events should implement this * interface. * * @copyright Copyright (C) 2013-2015 fruux GmbH (https://fruux.com/). * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License */ interface EventEmitterInterface { /** * Subscribe to an event. * * @param string $eventName * @param callable $callBack * @param int $priority * @return void */ function on($eventName, callable $callBack, $priority = 100); /** * Subscribe to an event exactly once. * * @param string $eventName * @param callable $callBack * @param int $priority * @return void */ function once($eventName, callable $callBack, $priority = 100); /** * 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. * * If the continueCallBack is specified, this callback will be called every * time before the next event handler is called. * * If the continueCallback returns false, event propagation stops. This * allows you to use the eventEmitter as a means for listeners to implement * functionality in your application, and break the event loop as soon as * some condition is fulfilled. * * Note that returning false from an event subscriber breaks propagation * and returns false, but if the continue-callback stops propagation, this * is still considered a 'successful' operation and returns true. * * Lastly, if there are 5 event handlers for an event. The continueCallback * will be called at most 4 times. * * @param string $eventName * @param array $arguments * @param callback $continueCallBack * @return bool */ function emit($eventName, array $arguments = [], callable $continueCallBack = null); /** * Returns the list of listeners for an event. * * The list is returned as an array, and the list of events are sorted by * their priority. * * @param string $eventName * @return callable[] */ function listeners($eventName); /** * Removes a specific listener from an event. * * If the listener could not be found, this method will return false. If it * was removed it will return true. * * @param string $eventName * @param callable $listener * @return bool */ function removeListener($eventName, callable $listener); /** * Removes all listeners. * * If the eventName argument is specified, all listeners for that event are * removed. If it is not specified, every listener for every event is * removed. * * @param string $eventName * @return void */ function removeAllListeners($eventName = null); } lib/Promise/functions.php 0000604 00000006603 15247165557 0011473 0 ustar 00 <?php namespace Sabre\Event\Promise; use Sabre\Event\Promise; /** * This file contains a set of functions that are useful for dealing with the * Promise object. * * @copyright Copyright (C) 2013-2015 fruux GmbH (https://fruux.com/). * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License */ /** * This function takes an array of Promises, and returns a Promise that * resolves when all of the given arguments have resolved. * * The returned Promise will resolve with a value that's an array of all the * values the given promises have been resolved with. * * This array will be in the exact same order as the array of input promises. * * If any of the given Promises fails, the returned promise will immidiately * fail with the first Promise that fails, and its reason. * * @param Promise[] $promises * @return Promise */ function all(array $promises) { return new Promise(function($success, $fail) use ($promises) { $successCount = 0; $completeResult = []; foreach ($promises as $promiseIndex => $subPromise) { $subPromise->then( function($result) use ($promiseIndex, &$completeResult, &$successCount, $success, $promises) { $completeResult[$promiseIndex] = $result; $successCount++; if ($successCount === count($promises)) { $success($completeResult); } return $result; } )->error( function($reason) use ($fail) { $fail($reason); } ); } }); } /** * The race function returns a promise that resolves or rejects as soon as * one of the promises in the argument resolves or rejects. * * The returned promise will resolve or reject with the value or reason of * that first promise. * * @param Promise[] $promises * @return Promise */ function race(array $promises) { return new Promise(function($success, $fail) use ($promises) { $alreadyDone = false; foreach ($promises as $promise) { $promise->then( function($result) use ($success, &$alreadyDone) { if ($alreadyDone) { return; } $alreadyDone = true; $success($result); }, function($reason) use ($fail, &$alreadyDone) { if ($alreadyDone) { return; } $alreadyDone = true; $fail($reason); } ); } }); } /** * Returns a Promise that resolves with the given value. * * If the value is a promise, the returned promise will attach itself to that * promise and eventually get the same state as the followed promise. * * @param mixed $value * @return Promise */ function resolve($value) { if ($value instanceof Promise) { return $value->then(); } else { $promise = new Promise(); $promise->fulfill($value); return $promise; } } /** * Returns a Promise that will reject with the given reason. * * @param mixed $reason * @return Promise */ function reject($reason) { $promise = new Promise(); $promise->reject($reason); return $promise; } lib/EventEmitter.php 0000604 00000000625 15247165557 0010456 0 ustar 00 <?php namespace Sabre\Event; /** * EventEmitter object. * * Instantiate this class, or subclass it for easily creating event emitters. * * @copyright Copyright (C) 2013-2015 fruux GmbH (https://fruux.com/). * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License */ class EventEmitter implements EventEmitterInterface { use EventEmitterTrait; } lib/Promise.php 0000604 00000023715 15247165557 0007466 0 ustar 00 <?php namespace Sabre\Event; use Exception; /** * An implementation of the Promise pattern. * * A promise represents the result of an asynchronous operation. * At any given point a promise can be in one of three states: * * 1. Pending (the promise does not have a result yet). * 2. Fulfilled (the asynchronous operation has completed with a result). * 3. Rejected (the asynchronous operation has completed with an error). * * To get a callback when the operation has finished, use the `then` method. * * @copyright Copyright (C) 2013-2015 fruux GmbH (https://fruux.com/). * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License */ class Promise { /** * The asynchronous operation is pending. */ const PENDING = 0; /** * The asynchronous operation has completed, and has a result. */ const FULFILLED = 1; /** * The asynchronous operation has completed with an error. */ const REJECTED = 2; /** * The current state of this promise. * * @var int */ public $state = self::PENDING; /** * Creates the promise. * * The passed argument is the executor. The executor is automatically * called with two arguments. * * Each are callbacks that map to $this->fulfill and $this->reject. * Using the executor is optional. * * @param callable $executor */ function __construct(callable $executor = null) { if ($executor) { $executor( [$this, 'fulfill'], [$this, 'reject'] ); } } /** * This method allows you to specify the callback that will be called after * the promise has been fulfilled or rejected. * * Both arguments are optional. * * This method returns a new promise, which can be used for chaining. * If either the onFulfilled or onRejected callback is called, you may * return a result from this callback. * * If the result of this callback is yet another promise, the result of * _that_ promise will be used to set the result of the returned promise. * * If either of the callbacks return any other value, the returned promise * is automatically fulfilled with that value. * * If either of the callbacks throw an exception, the returned promise will * be rejected and the exception will be passed back. * * @param callable $onFulfilled * @param callable $onRejected * @return Promise */ function then(callable $onFulfilled = null, callable $onRejected = null) { // This new subPromise will be returned from this function, and will // be fulfilled with the result of the onFulfilled or onRejected event // handlers. $subPromise = new self(); switch ($this->state) { case self::PENDING : // The operation is pending, so we keep a reference to the // event handlers so we can call them later. $this->subscribers[] = [$subPromise, $onFulfilled, $onRejected]; break; case self::FULFILLED : // The async operation is already fulfilled, so we trigger the // onFulfilled callback asap. $this->invokeCallback($subPromise, $onFulfilled); break; case self::REJECTED : // The async operation failed, so we call teh onRejected // callback asap. $this->invokeCallback($subPromise, $onRejected); break; } return $subPromise; } /** * Add a callback for when this promise is rejected. * * Its usage is identical to then(). However, the otherwise() function is * preferred. * * @param callable $onRejected * @return Promise */ function otherwise(callable $onRejected) { return $this->then(null, $onRejected); } /** * Marks this promise as fulfilled and sets its return value. * * @param mixed $value * @return void */ function fulfill($value = null) { if ($this->state !== self::PENDING) { throw new PromiseAlreadyResolvedException('This promise is already resolved, and you\'re not allowed to resolve a promise more than once'); } $this->state = self::FULFILLED; $this->value = $value; foreach ($this->subscribers as $subscriber) { $this->invokeCallback($subscriber[0], $subscriber[1]); } } /** * Marks this promise as rejected, and set it's rejection reason. * * While it's possible to use any PHP value as the reason, it's highly * recommended to use an Exception for this. * * @param mixed $reason * @return void */ function reject($reason = null) { if ($this->state !== self::PENDING) { throw new PromiseAlreadyResolvedException('This promise is already resolved, and you\'re not allowed to resolve a promise more than once'); } $this->state = self::REJECTED; $this->value = $reason; foreach ($this->subscribers as $subscriber) { $this->invokeCallback($subscriber[0], $subscriber[2]); } } /** * Stops execution until this promise is resolved. * * This method stops exection completely. If the promise is successful with * a value, this method will return this value. If the promise was * rejected, this method will throw an exception. * * This effectively turns the asynchronous operation into a synchronous * one. In PHP it might be useful to call this on the last promise in a * chain. * * @throws Exception * @return mixed */ function wait() { $hasEvents = true; while ($this->state === self::PENDING) { if (!$hasEvents) { throw new \LogicException('There were no more events in the loop. This promise will never be fulfilled.'); } // As long as the promise is not fulfilled, we tell the event loop // to handle events, and to block. $hasEvents = Loop\tick(true); } if ($this->state === self::FULFILLED) { // If the state of this promise is fulfilled, we can return the value. return $this->value; } else { // If we got here, it means that the asynchronous operation // errored. Therefore we need to throw an exception. $reason = $this->value; if ($reason instanceof Exception) { throw $reason; } elseif (is_scalar($reason)) { throw new Exception($reason); } else { $type = is_object($reason) ? get_class($reason) : gettype($reason); throw new Exception('Promise was rejected with reason of type: ' . $type); } } } /** * A list of subscribers. Subscribers are the callbacks that want us to let * them know if the callback was fulfilled or rejected. * * @var array */ protected $subscribers = []; /** * The result of the promise. * * If the promise was fulfilled, this will be the result value. If the * promise was rejected, this property hold the rejection reason. * * @var mixed */ protected $value = null; /** * This method is used to call either an onFulfilled or onRejected callback. * * This method makes sure that the result of these callbacks are handled * correctly, and any chained promises are also correctly fulfilled or * rejected. * * @param Promise $subPromise * @param callable $callBack * @return void */ private function invokeCallback(Promise $subPromise, callable $callBack = null) { // We use 'nextTick' to ensure that the event handlers are always // triggered outside of the calling stack in which they were originally // passed to 'then'. // // This makes the order of execution more predictable. Loop\nextTick(function() use ($callBack, $subPromise) { if (is_callable($callBack)) { try { $result = $callBack($this->value); if ($result instanceof self) { // If the callback (onRejected or onFulfilled) // returned a promise, we only fulfill or reject the // chained promise once that promise has also been // resolved. $result->then([$subPromise, 'fulfill'], [$subPromise, 'reject']); } else { // If the callback returned any other value, we // immediately fulfill the chained promise. $subPromise->fulfill($result); } } catch (Exception $e) { // If the event handler threw an exception, we need to make sure that // the chained promise is rejected as well. $subPromise->reject($e); } } else { if ($this->state === self::FULFILLED) { $subPromise->fulfill($this->value); } else { $subPromise->reject($this->value); } } }); } /** * Alias for 'otherwise'. * * This function is now deprecated and will be removed in a future version. * * @param callable $onRejected * @deprecated * @return Promise */ function error(callable $onRejected) { return $this->otherwise($onRejected); } /** * Deprecated. * * Please use Sabre\Event\Promise::all * * @param Promise[] $promises * @deprecated * @return Promise */ static function all(array $promises) { return Promise\all($promises); } } lib/EventEmitterTrait.php 0000604 00000013304 15247165557 0011460 0 ustar 00 <?php namespace Sabre\Event; /** * Event Emitter Trait * * This trait contains all the basic functions to implement an * EventEmitterInterface. * * Using the trait + interface allows you to add EventEmitter capabilities * without having to change your base-class. * * @copyright Copyright (C) 2013-2015 fruux GmbH (https://fruux.com/). * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License */ trait EventEmitterTrait { /** * The list of listeners * * @var array */ protected $listeners = []; /** * Subscribe to an event. * * @param string $eventName * @param callable $callBack * @param int $priority * @return void */ function on($eventName, callable $callBack, $priority = 100) { if (!isset($this->listeners[$eventName])) { $this->listeners[$eventName] = [ true, // If there's only one item, it's sorted [$priority], [$callBack] ]; } else { $this->listeners[$eventName][0] = false; // marked as unsorted $this->listeners[$eventName][1][] = $priority; $this->listeners[$eventName][2][] = $callBack; } } /** * Subscribe to an event exactly once. * * @param string $eventName * @param callable $callBack * @param int $priority * @return void */ function once($eventName, callable $callBack, $priority = 100) { $wrapper = null; $wrapper = function() use ($eventName, $callBack, &$wrapper) { $this->removeListener($eventName, $wrapper); return call_user_func_array($callBack, func_get_args()); }; $this->on($eventName, $wrapper, $priority); } /** * 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. * * If the continueCallBack is specified, this callback will be called every * time before the next event handler is called. * * If the continueCallback returns false, event propagation stops. This * allows you to use the eventEmitter as a means for listeners to implement * functionality in your application, and break the event loop as soon as * some condition is fulfilled. * * Note that returning false from an event subscriber breaks propagation * and returns false, but if the continue-callback stops propagation, this * is still considered a 'successful' operation and returns true. * * Lastly, if there are 5 event handlers for an event. The continueCallback * will be called at most 4 times. * * @param string $eventName * @param array $arguments * @param callback $continueCallBack * @return bool */ function emit($eventName, array $arguments = [], callable $continueCallBack = null) { if (is_null($continueCallBack)) { foreach ($this->listeners($eventName) as $listener) { $result = call_user_func_array($listener, $arguments); if ($result === false) { return false; } } } else { $listeners = $this->listeners($eventName); $counter = count($listeners); foreach ($listeners as $listener) { $counter--; $result = call_user_func_array($listener, $arguments); if ($result === false) { return false; } if ($counter > 0) { if (!$continueCallBack()) break; } } } return true; } /** * Returns the list of listeners for an event. * * The list is returned as an array, and the list of events are sorted by * their priority. * * @param string $eventName * @return callable[] */ function listeners($eventName) { if (!isset($this->listeners[$eventName])) { return []; } // The list is not sorted if (!$this->listeners[$eventName][0]) { // Sorting array_multisort($this->listeners[$eventName][1], SORT_NUMERIC, $this->listeners[$eventName][2]); // Marking the listeners as sorted $this->listeners[$eventName][0] = true; } return $this->listeners[$eventName][2]; } /** * Removes a specific listener from an event. * * If the listener could not be found, this method will return false. If it * was removed it will return true. * * @param string $eventName * @param callable $listener * @return bool */ function removeListener($eventName, callable $listener) { if (!isset($this->listeners[$eventName])) { return false; } foreach ($this->listeners[$eventName][2] as $index => $check) { if ($check === $listener) { unset($this->listeners[$eventName][1][$index]); unset($this->listeners[$eventName][2][$index]); return true; } } return false; } /** * Removes all listeners. * * If the eventName argument is specified, all listeners for that event are * removed. If it is not specified, every listener for every event is * removed. * * @param string $eventName * @return void */ function removeAllListeners($eventName = null) { if (!is_null($eventName)) { unset($this->listeners[$eventName]); } else { $this->listeners = []; } } } lib/PromiseAlreadyResolvedException.php 0000604 00000000643 15247165557 0014346 0 ustar 00 <?php namespace Sabre\Event; /** * This exception is thrown when the user tried to reject or fulfill a promise, * after either of these actions were already performed. * * @copyright Copyright (C) 2013-2015 fruux GmbH (https://fruux.com/). * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License */ class PromiseAlreadyResolvedException extends \LogicException { } lib/Loop/functions.php 0000604 00000006116 15247165557 0010765 0 ustar 00 <?php namespace Sabre\Event\Loop; /** * Executes a function after x seconds. * * @param callable $cb * @param float $timeout timeout in seconds * @return void */ function setTimeout(callable $cb, $timeout) { instance()->setTimeout($cb, $timeout); } /** * Executes a function every x seconds. * * The value this function returns can be used to stop the interval with * clearInterval. * * @param callable $cb * @param float $timeout * @return array */ function setInterval(callable $cb, $timeout) { return instance()->setInterval($cb, $timeout); } /** * Stops a running internval. * * @param array $intervalId * @return void */ function clearInterval($intervalId) { instance()->clearInterval($intervalId); } /** * Runs a function immediately at the next iteration of the loop. * * @param callable $cb * @return void */ function nextTick(callable $cb) { instance()->nextTick($cb); } /** * Adds a read stream. * * The callback will be called as soon as there is something to read from * the stream. * * You MUST call removeReadStream after you are done with the stream, to * prevent the eventloop from never stopping. * * @param resource $stream * @param callable $cb * @return void */ function addReadStream($stream, callable $cb) { instance()->addReadStream($stream, $cb); } /** * Adds a write stream. * * The callback will be called as soon as the system reports it's ready to * receive writes on the stream. * * You MUST call removeWriteStream after you are done with the stream, to * prevent the eventloop from never stopping. * * @param resource $stream * @param callable $cb * @return void */ function addWriteStream($stream, callable $cb) { instance()->addWriteStream($stream, $cb); } /** * Stop watching a stream for reads. * * @param resource $stream * @return void */ function removeReadStream($stream) { instance()->removeReadStream($stream); } /** * Stop watching a stream for writes. * * @param resource $stream * @return void */ function removeWriteStream($stream) { instance()->removeWriteStream($stream); } /** * Runs the loop. * * This function will run continiously, until there's no more events to * handle. * * @return void */ function run() { instance()->run(); } /** * Executes all pending events. * * If $block is turned true, this function will block until any event is * triggered. * * If there are now timeouts, nextTick callbacks or events in the loop at * all, this function will exit immediately. * * This function will return true if there are _any_ events left in the * loop after the tick. * * @param bool $block * @return bool */ function tick($block = false) { return instance()->tick($block); } /** * Stops a running eventloop * * @return void */ function stop() { instance()->stop(); } /** * Retrieves or sets the global Loop object. * * @param Loop $newLoop */ function instance(Loop $newLoop = null) { static $loop; if ($newLoop) { $loop = $newLoop; } elseif (!$loop) { $loop = new Loop(); } return $loop; } lib/Loop/Loop.php 0000604 00000021757 15247165557 0007676 0 ustar 00 <?php namespace Sabre\Event\Loop; /** * A simple eventloop implementation. * * This eventloop supports: * * nextTick * * setTimeout for delayed functions * * setInterval for repeating functions * * stream events using stream_select * * @copyright Copyright (C) 2007-2015 fruux GmbH. (https://fruux.com/) * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License */ class Loop { /** * Executes a function after x seconds. * * @param callable $cb * @param float $timeout timeout in seconds * @return void */ function setTimeout(callable $cb, $timeout) { $triggerTime = microtime(true) + ($timeout); if (!$this->timers) { // Special case when the timers array was empty. $this->timers[] = [$triggerTime, $cb]; return; } // We need to insert these values in the timers array, but the timers // array must be in reverse-order of trigger times. // // So here we search the array for the insertion point. $index = count($this->timers) - 1; while (true) { if ($triggerTime < $this->timers[$index][0]) { array_splice( $this->timers, $index + 1, 0, [[$triggerTime, $cb]] ); break; } elseif ($index === 0) { array_unshift($this->timers, [$triggerTime, $cb]); break; } $index--; } } /** * Executes a function every x seconds. * * The value this function returns can be used to stop the interval with * clearInterval. * * @param callable $cb * @param float $timeout * @return array */ function setInterval(callable $cb, $timeout) { $keepGoing = true; $f = null; $f = function() use ($cb, &$f, $timeout, &$keepGoing) { if ($keepGoing) { $cb(); $this->setTimeout($f, $timeout); } }; $this->setTimeout($f, $timeout); // Really the only thing that matters is returning the $keepGoing // boolean value. // // We need to pack it in an array to allow returning by reference. // Because I'm worried people will be confused by using a boolean as a // sort of identifier, I added an extra string. return ['I\'m an implementation detail', &$keepGoing]; } /** * Stops a running internval. * * @param array $intervalId * @return void */ function clearInterval($intervalId) { $intervalId[1] = false; } /** * Runs a function immediately at the next iteration of the loop. * * @param callable $cb * @return void */ function nextTick(callable $cb) { $this->nextTick[] = $cb; } /** * Adds a read stream. * * The callback will be called as soon as there is something to read from * the stream. * * You MUST call removeReadStream after you are done with the stream, to * prevent the eventloop from never stopping. * * @param resource $stream * @param callable $cb * @return void */ function addReadStream($stream, callable $cb) { $this->readStreams[(int)$stream] = $stream; $this->readCallbacks[(int)$stream] = $cb; } /** * Adds a write stream. * * The callback will be called as soon as the system reports it's ready to * receive writes on the stream. * * You MUST call removeWriteStream after you are done with the stream, to * prevent the eventloop from never stopping. * * @param resource $stream * @param callable $cb * @return void */ function addWriteStream($stream, callable $cb) { $this->writeStreams[(int)$stream] = $stream; $this->writeCallbacks[(int)$stream] = $cb; } /** * Stop watching a stream for reads. * * @param resource $stream * @return void */ function removeReadStream($stream) { unset( $this->readStreams[(int)$stream], $this->readCallbacks[(int)$stream] ); } /** * Stop watching a stream for writes. * * @param resource $stream * @return void */ function removeWriteStream($stream) { unset( $this->writeStreams[(int)$stream], $this->writeCallbacks[(int)$stream] ); } /** * Runs the loop. * * This function will run continiously, until there's no more events to * handle. * * @return void */ function run() { $this->running = true; do { $hasEvents = $this->tick(true); } while ($this->running && $hasEvents); $this->running = false; } /** * Executes all pending events. * * If $block is turned true, this function will block until any event is * triggered. * * If there are now timeouts, nextTick callbacks or events in the loop at * all, this function will exit immediately. * * This function will return true if there are _any_ events left in the * loop after the tick. * * @param bool $block * @return bool */ function tick($block = false) { $this->runNextTicks(); $nextTimeout = $this->runTimers(); // Calculating how long runStreams should at most wait. if (!$block) { // Don't wait $streamWait = 0; } elseif ($this->nextTick) { // There's a pending 'nextTick'. Don't wait. $streamWait = 0; } elseif (is_numeric($nextTimeout)) { // Wait until the next Timeout should trigger. $streamWait = $nextTimeout; } else { // Wait indefinitely $streamWait = null; } $this->runStreams($streamWait); return ($this->readStreams || $this->writeStreams || $this->nextTick || $this->timers); } /** * Stops a running eventloop * * @return void */ function stop() { $this->running = false; } /** * Executes all 'nextTick' callbacks. * * return void */ protected function runNextTicks() { $nextTick = $this->nextTick; $this->nextTick = []; foreach ($nextTick as $cb) { $cb(); } } /** * Runs all pending timers. * * After running the timer callbacks, this function returns the number of * seconds until the next timer should be executed. * * If there's no more pending timers, this function returns null. * * @return float */ protected function runTimers() { $now = microtime(true); while (($timer = array_pop($this->timers)) && $timer[0] < $now) { $timer[1](); } // Add the last timer back to the array. if ($timer) { $this->timers[] = $timer; return $timer[0] - microtime(true); } } /** * Runs all pending stream events. * * @param float $timeout */ protected function runStreams($timeout) { if ($this->readStreams || $this->writeStreams) { $read = $this->readStreams; $write = $this->writeStreams; $except = null; if (stream_select($read, $write, $except, null, $timeout)) { // See PHP Bug https://bugs.php.net/bug.php?id=62452 // Fixed in PHP7 foreach ($read as $readStream) { $readCb = $this->readCallbacks[(int)$readStream]; $readCb(); } foreach ($write as $writeStream) { $writeCb = $this->writeCallbacks[(int)$writeStream]; $writeCb(); } } } elseif ($this->running && ($this->nextTick || $this->timers)) { usleep($timeout !== null ? $timeout * 1000000 : 200000); } } /** * Is the main loop active * * @var bool */ protected $running = false; /** * A list of timers, added by setTimeout. * * @var array */ protected $timers = []; /** * A list of 'nextTick' callbacks. * * @var callable[] */ protected $nextTick = []; /** * List of readable streams for stream_select, indexed by stream id. * * @var resource[] */ protected $readStreams = []; /** * List of writable streams for stream_select, indexed by stream id. * * @var resource[] */ protected $writeStreams = []; /** * List of read callbacks, indexed by stream id. * * @var callback[] */ protected $readCallbacks = []; /** * List of write callbacks, indexed by stream id. * * @var callback[] */ protected $writeCallbacks = []; } lib/Version.php 0000604 00000000557 15247165557 0007474 0 ustar 00 <?php namespace Sabre\Event; /** * This class contains the version number for this package. * * @copyright Copyright (C) 2013-2015 fruux GmbH (https://fruux.com/). * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License */ class Version { /** * Full version number */ const VERSION = '3.0.0'; } lib/coroutine.php 0000604 00000007352 15247165557 0010056 0 ustar 00 <?php namespace Sabre\Event; use Generator; use Exception; /** * Turn asynchronous promise-based code into something that looks synchronous * again, through the use of generators. * * Example without coroutines: * * $promise = $httpClient->request('GET', '/foo'); * $promise->then(function($value) { * * return $httpClient->request('DELETE','/foo'); * * })->then(function($value) { * * return $httpClient->request('PUT', '/foo'); * * })->error(function($reason) { * * echo "Failed because: $reason\n"; * * }); * * Example with coroutines: * * coroutine(function() { * * try { * yield $httpClient->request('GET', '/foo'); * yield $httpClient->request('DELETE', /foo'); * yield $httpClient->request('PUT', '/foo'); * } catch(\Exception $reason) { * echo "Failed because: $reason\n"; * } * * }); * * @copyright Copyright (C) 2013-2015 fruux GmbH. All rights reserved. * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License */ function coroutine(callable $gen) { $generator = $gen(); if (!$generator instanceof Generator) { throw new \InvalidArgumentException('You must pass a generator function'); } // This is the value we're returning. $promise = new Promise(); $lastYieldResult = null; /** * So tempted to use the mythical y-combinator here, but it's not needed in * PHP. */ $advanceGenerator = function() use (&$advanceGenerator, $generator, $promise, &$lastYieldResult) { while ($generator->valid()) { $yieldedValue = $generator->current(); if ($yieldedValue instanceof Promise) { $yieldedValue->then( function($value) use ($generator, &$advanceGenerator, &$lastYieldResult) { $lastYieldResult = $value; $generator->send($value); $advanceGenerator(); }, function($reason) use ($generator, $advanceGenerator) { if ($reason instanceof Exception) { $generator->throw($reason); } elseif (is_scalar($reason)) { $generator->throw(new Exception($reason)); } else { $type = is_object($reason) ? get_class($reason) : gettype($reason); $generator->throw(new Exception('Promise was rejected with reason of type: ' . $type)); } $advanceGenerator(); } )->error(function($reason) use ($promise) { // This error handler would be called, if something in the // generator throws an exception, and it's not caught // locally. $promise->reject($reason); }); // We need to break out of the loop, because $advanceGenerator // will be called asynchronously when the promise has a result. break; } else { // If the value was not a promise, we'll just let it pass through. $lastYieldResult = $yieldedValue; $generator->send($yieldedValue); } } // If the generator is at the end, and we didn't run into an exception, // we can fullfill the promise with the last thing that was yielded to // us. if (!$generator->valid() && $promise->state === Promise::PENDING) { $promise->fulfill($lastYieldResult); } }; try { $advanceGenerator(); } catch (Exception $e) { $promise->reject($e); } return $promise; } composer.json 0000604 00000002131 15247165557 0007300 0 ustar 00 { "name": "sabre/event", "description": "sabre/event is a library for lightweight event-based programming", "keywords": [ "Events", "EventEmitter", "Promise", "Hooks", "Plugin", "Signal", "Async" ], "homepage": "http://sabre.io/event/", "license": "BSD-3-Clause", "require": { "php": ">=5.5" }, "authors": [ { "name": "Evert Pot", "email": "me@evertpot.com", "homepage": "http://evertpot.com/", "role": "Developer" } ], "support": { "forum": "https://groups.google.com/group/sabredav-discuss", "source": "https://github.com/fruux/sabre-event" }, "autoload": { "psr-4": { "Sabre\\Event\\": "lib/" }, "files" : [ "lib/coroutine.php", "lib/Loop/functions.php", "lib/Promise/functions.php" ] }, "require-dev": { "sabre/cs": "~0.0.4", "phpunit/phpunit" : "*" }, "config" : { "bin-dir" : "bin/" } } LICENSE 0000604 00000003041 15247165557 0005564 0 ustar 00 Copyright (C) 2013-2015 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. .gitignore 0000604 00000000220 15247165557 0006543 0 ustar 00 #composer vendor composer.lock #binaries bin/sabre-cs-fixer bin/php-cs-fixer bin/phpunit #vim lock files .*.swp #development stuff tests/cov README.md 0000604 00000002747 15247165557 0006052 0 ustar 00 sabre/event =========== A lightweight library for event-based development in PHP. This library provides the following event-based concepts: 1. EventEmitter. 2. Promises. 3. An event loop. 4. Co-routines. Full documentation can be found on [the website][1]. Installation ------------ Make sure you have [composer][3] installed, and then run: composer require sabre/event "~3.0.0" This package requires PHP 5.5. The 2.0 branch is still maintained as well, and supports PHP 5.4. Build status ------------ | branch | status | | ------ | ------ | | master | [](https://travis-ci.org/fruux/sabre-event) | | 2.0 | [](https://travis-ci.org/fruux/sabre-event) | | 1.0 | [](https://travis-ci.org/fruux/sabre-event) | | php53 | [](https://travis-ci.org/fruux/sabre-event) | 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://sabre.io/event/ [3]: http://getcomposer.org/ [4]: http://groups.google.com/group/sabredav-discuss [5]: https://github.com/fruux/sabre-event/issues/ CHANGELOG.md 0000604 00000004515 15247165557 0006377 0 ustar 00 ChangeLog ========= 3.0.0 (2015-11-05) ------------------ * Now requires PHP 5.5! * `Promise::all()` is moved to `Promise\all()`. * Aside from the `Promise\all()` function, there's now also `Promise\race()`. * `Promise\reject()` and `Promise\resolve()` have also been added. * Now 100% compatible with the Ecmascript 6 Promise. 3.0.0-alpha1 (2015-10-23) ------------------------- * This package now requires PHP 5.5. * #26: Added an event loop implementation. Also knows as the Reactor Pattern. * Renamed `Promise::error` to `Promise::otherwise` to be consistent with ReactPHP and Guzzle. The `error` method is kept for BC but will be removed in a future version. * #27: Support for Promise-based coroutines via the `Sabre\Event\coroutine` function. * BC Break: Promises now use the EventLoop to run "then"-events in a separate execution context. In practise that means you need to run the event loop to wait for any `then`/`otherwise` callbacks to trigger. * Promises now have a `wait()` method. Allowing you to make a promise synchronous and simply wait for a result (or exception) to happen. 2.0.2 (2015-05-19) ------------------ * This release has no functional changes. It's just been brought up to date with the latest coding standards. 2.0.1 (2014-10-06) ------------------ * Fixed: `$priority` was ignored in `EventEmitter::once` method. * Fixed: Breaking the event chain was not possible in `EventEmitter::once`. 2.0.0 (2014-06-21) ------------------ * Added: When calling emit, it's now possible to specify a callback that will be triggered after each method handled. This is dubbed the 'continueCallback' and can be used to implement strategy patterns. * Added: Promise object! * Changed: EventEmitter::listeners now returns just the callbacks for an event, and no longer returns the list by reference. The list is now automatically sorted by priority. * Update: Speed improvements. * Updated: It's now possible to remove all listeners for every event. * Changed: Now uses psr-4 autoloading. 1.0.1 (2014-06-12) ------------------ * hhvm compatible! * Fixed: Issue #4. Compatiblitiy for PHP < 5.4.14. 1.0.0 (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! phpunit.xml.dist 0000604 00000000652 15247165557 0007737 0 ustar 00 <phpunit colors="true" bootstrap="vendor/autoload.php" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" strict="true" > <testsuite name="sabre-event"> <directory>tests/</directory> </testsuite> <filter> <whitelist addUncoveredFilesFromWhitelist="true"> <directory suffix=".php">./lib/</directory> </whitelist> </filter> </phpunit>
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0 |
proxy
|
phpinfo
|
Settings