diff --git a/libs/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php b/libs/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php
index af0b6cef..76f0e387 100644
--- a/libs/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php
+++ b/libs/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php
@@ -121,7 +121,7 @@ class ContainerAwareEventDispatcher extends EventDispatcher
public function getListeners($eventName = null)
{
if (null === $eventName) {
- foreach (array_keys($this->listenerIds) as $serviceEventName) {
+ foreach ($this->listenerIds as $serviceEventName => $args) {
$this->lazyLoad($serviceEventName);
}
} else {
diff --git a/libs/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php b/libs/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php
index b796a812..7653ccfb 100644
--- a/libs/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php
+++ b/libs/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php
@@ -31,6 +31,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
private $called;
private $dispatcher;
+ private $wrappedListeners;
/**
* Constructor.
@@ -45,6 +46,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
$this->stopwatch = $stopwatch;
$this->logger = $logger;
$this->called = array();
+ $this->wrappedListeners = array();
}
/**
@@ -68,6 +70,16 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
*/
public function removeListener($eventName, $listener)
{
+ if (isset($this->wrappedListeners[$eventName])) {
+ foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) {
+ if ($wrappedListener->getWrappedListener() === $listener) {
+ $listener = $wrappedListener;
+ unset($this->wrappedListeners[$eventName][$index]);
+ break;
+ }
+ }
+ }
+
return $this->dispatcher->removeListener($eventName, $listener);
}
@@ -146,7 +158,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
$allListeners = $this->getListeners();
} catch (\Exception $e) {
if (null !== $this->logger) {
- $this->logger->info(sprintf('An exception was thrown while getting the uncalled listeners (%s)', $e->getMessage()), array('exception' => $e));
+ $this->logger->info('An exception was thrown while getting the uncalled listeners.', array('exception' => $e));
}
// unable to retrieve the uncalled listeners
@@ -216,12 +228,15 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
$this->dispatcher->removeListener($eventName, $listener);
$info = $this->getListenerInfo($listener, $eventName);
$name = isset($info['class']) ? $info['class'] : $info['type'];
- $this->dispatcher->addListener($eventName, new WrappedListener($listener, $name, $this->stopwatch));
+ $wrappedListener = new WrappedListener($listener, $name, $this->stopwatch, $this);
+ $this->wrappedListeners[$eventName][] = $wrappedListener;
+ $this->dispatcher->addListener($eventName, $wrappedListener);
}
}
private function postProcess($eventName)
{
+ unset($this->wrappedListeners[$eventName]);
$skipped = false;
foreach ($this->dispatcher->getListeners($eventName) as $listener) {
if (!$listener instanceof WrappedListener) { // #12845: a new listener was added during dispatch.
@@ -259,7 +274,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
}
/**
- * Returns information about the listener
+ * Returns information about the listener.
*
* @param object $listener The listener
* @param string $eventName The event name
diff --git a/libs/Symfony/Component/EventDispatcher/Debug/WrappedListener.php b/libs/Symfony/Component/EventDispatcher/Debug/WrappedListener.php
index c501662b..e16627d6 100644
--- a/libs/Symfony/Component/EventDispatcher/Debug/WrappedListener.php
+++ b/libs/Symfony/Component/EventDispatcher/Debug/WrappedListener.php
@@ -25,12 +25,14 @@ class WrappedListener
private $called;
private $stoppedPropagation;
private $stopwatch;
+ private $dispatcher;
- public function __construct($listener, $name, Stopwatch $stopwatch)
+ public function __construct($listener, $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null)
{
$this->listener = $listener;
$this->name = $name;
$this->stopwatch = $stopwatch;
+ $this->dispatcher = $dispatcher;
$this->called = false;
$this->stoppedPropagation = false;
}
@@ -56,7 +58,7 @@ class WrappedListener
$e = $this->stopwatch->start($this->name, 'event_listener');
- call_user_func($this->listener, $event, $eventName, $dispatcher);
+ call_user_func($this->listener, $event, $eventName, $this->dispatcher ?: $dispatcher);
if ($e->isStarted()) {
$e->stop();
diff --git a/libs/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php b/libs/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php
index afe3ecd1..7e74a37a 100644
--- a/libs/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php
+++ b/libs/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php
@@ -91,8 +91,12 @@ class RegisterListenersPass implements CompilerPassInterface
throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event subscribers are lazy-loaded.', $id));
}
+ if ($def->isAbstract()) {
+ throw new \InvalidArgumentException(sprintf('The service "%s" must not be abstract as event subscribers are lazy-loaded.', $id));
+ }
+
// We must assume that the class value has been correctly filled, even if the service is created by a factory
- $class = $def->getClass();
+ $class = $container->getParameterBag()->resolveValue($def->getClass());
$refClass = new \ReflectionClass($class);
$interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface';
diff --git a/libs/Symfony/Component/EventDispatcher/Event.php b/libs/Symfony/Component/EventDispatcher/Event.php
index dc39b05d..048bf0ac 100644
--- a/libs/Symfony/Component/EventDispatcher/Event.php
+++ b/libs/Symfony/Component/EventDispatcher/Event.php
@@ -77,7 +77,7 @@ class Event
*
* @param EventDispatcherInterface $dispatcher
*
- * @deprecated Deprecated in 2.4, to be removed in 3.0. The event dispatcher is passed to the listener call.
+ * @deprecated since version 2.4, to be removed in 3.0. The event dispatcher is passed to the listener call.
*
* @api
*/
@@ -91,12 +91,14 @@ class Event
*
* @return EventDispatcherInterface
*
- * @deprecated Deprecated in 2.4, to be removed in 3.0. The event dispatcher is passed to the listener call.
+ * @deprecated since version 2.4, to be removed in 3.0. The event dispatcher is passed to the listener call.
*
* @api
*/
public function getDispatcher()
{
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0. The event dispatcher instance can be received in the listener call instead.', E_USER_DEPRECATED);
+
return $this->dispatcher;
}
@@ -105,12 +107,14 @@ class Event
*
* @return string
*
- * @deprecated Deprecated in 2.4, to be removed in 3.0. The event name is passed to the listener call.
+ * @deprecated since version 2.4, to be removed in 3.0. The event name is passed to the listener call.
*
* @api
*/
public function getName()
{
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0. The event name can be received in the listener call instead.', E_USER_DEPRECATED);
+
return $this->name;
}
@@ -119,7 +123,7 @@ class Event
*
* @param string $name The event name.
*
- * @deprecated Deprecated in 2.4, to be removed in 3.0. The event name is passed to the listener call.
+ * @deprecated since version 2.4, to be removed in 3.0. The event name is passed to the listener call.
*
* @api
*/
diff --git a/libs/Symfony/Component/EventDispatcher/EventDispatcher.php b/libs/Symfony/Component/EventDispatcher/EventDispatcher.php
index 3b032fb0..46c11100 100644
--- a/libs/Symfony/Component/EventDispatcher/EventDispatcher.php
+++ b/libs/Symfony/Component/EventDispatcher/EventDispatcher.php
@@ -68,7 +68,7 @@ class EventDispatcher implements EventDispatcherInterface
return $this->sorted[$eventName];
}
- foreach (array_keys($this->listeners) as $eventName) {
+ foreach ($this->listeners as $eventName => $eventListeners) {
if (!isset($this->sorted[$eventName])) {
$this->sortListeners($eventName);
}
diff --git a/libs/Symfony/Component/EventDispatcher/EventDispatcherInterface.php b/libs/Symfony/Component/EventDispatcher/EventDispatcherInterface.php
index efb7c5be..9d9fc4d4 100644
--- a/libs/Symfony/Component/EventDispatcher/EventDispatcherInterface.php
+++ b/libs/Symfony/Component/EventDispatcher/EventDispatcherInterface.php
@@ -77,7 +77,7 @@ interface EventDispatcherInterface
public function removeSubscriber(EventSubscriberInterface $subscriber);
/**
- * Gets the listeners of a specific event or all listeners.
+ * Gets the listeners of a specific event or all listeners sorted by descending priority.
*
* @param string $eventName The name of the event
*
diff --git a/libs/Symfony/Component/EventDispatcher/GenericEvent.php b/libs/Symfony/Component/EventDispatcher/GenericEvent.php
index a8955ca4..6458180a 100644
--- a/libs/Symfony/Component/EventDispatcher/GenericEvent.php
+++ b/libs/Symfony/Component/EventDispatcher/GenericEvent.php
@@ -71,7 +71,7 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
return $this->arguments[$key];
}
- throw new \InvalidArgumentException(sprintf('%s not found in %s', $key, $this->getName()));
+ throw new \InvalidArgumentException(sprintf('Argument "%s" not found.', $key));
}
/**
diff --git a/libs/Symfony/Component/EventDispatcher/README.md b/libs/Symfony/Component/EventDispatcher/README.md
index 0fbc35e2..8031f4dd 100644
--- a/libs/Symfony/Component/EventDispatcher/README.md
+++ b/libs/Symfony/Component/EventDispatcher/README.md
@@ -23,5 +23,5 @@ Resources
You can run the unit tests with the following command:
$ cd path/to/Symfony/Component/EventDispatcher/
- $ composer.phar install
+ $ composer install
$ phpunit
diff --git a/libs/Symfony/Component/EventDispatcher/Tests/AbstractEventDispatcherTest.php b/libs/Symfony/Component/EventDispatcher/Tests/AbstractEventDispatcherTest.php
index b9e41949..5ff5be84 100644
--- a/libs/Symfony/Component/EventDispatcher/Tests/AbstractEventDispatcherTest.php
+++ b/libs/Symfony/Component/EventDispatcher/Tests/AbstractEventDispatcherTest.php
@@ -118,10 +118,21 @@ abstract class AbstractEventDispatcherTest extends \PHPUnit_Framework_TestCase
$this->assertInstanceOf('Symfony\Component\EventDispatcher\Event', $this->dispatcher->dispatch(self::preFoo));
$event = new Event();
$return = $this->dispatcher->dispatch(self::preFoo, $event);
- $this->assertEquals('pre.foo', $event->getName());
$this->assertSame($event, $return);
}
+ /**
+ * @group legacy
+ */
+ public function testLegacyDispatch()
+ {
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
+ $event = new Event();
+ $return = $this->dispatcher->dispatch(self::preFoo, $event);
+ $this->assertEquals('pre.foo', $event->getName());
+ }
+
public function testDispatchForClosure()
{
$invoked = 0;
@@ -239,8 +250,13 @@ abstract class AbstractEventDispatcherTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($this->dispatcher->hasListeners(self::preFoo));
}
- public function testEventReceivesTheDispatcherInstance()
+ /**
+ * @group legacy
+ */
+ public function testLegacyEventReceivesTheDispatcherInstance()
{
+ $this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
+
$dispatcher = null;
$this->dispatcher->addListener('test', function ($event) use (&$dispatcher) {
$dispatcher = $event->getDispatcher();
diff --git a/libs/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php b/libs/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php
index 47dd5da1..24e60024 100644
--- a/libs/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php
+++ b/libs/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\EventDispatcher\Tests\Debug;
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;
@@ -86,6 +87,20 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array(), $tdispatcher->getNotCalledListeners());
}
+ public function testGetCalledListenersNested()
+ {
+ $tdispatcher = null;
+ $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
+ $dispatcher->addListener('foo', function (Event $event, $eventName, $dispatcher) use (&$tdispatcher) {
+ $tdispatcher = $dispatcher;
+ $dispatcher->dispatch('bar');
+ });
+ $dispatcher->addListener('bar', function (Event $event) {});
+ $dispatcher->dispatch('foo');
+ $this->assertSame($dispatcher, $tdispatcher);
+ $this->assertCount(2, $dispatcher->getCalledListeners());
+ }
+
public function testLogger()
{
$logger = $this->getMock('Psr\Log\LoggerInterface');
@@ -160,6 +175,19 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase
$dispatcher->dispatch('foo');
$this->assertTrue($nestedCall);
}
+
+ public function testListenerCanRemoveItselfWhenExecuted()
+ {
+ $eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
+ $listener1 = function ($event, $eventName, EventDispatcherInterface $dispatcher) use (&$listener1) {
+ $dispatcher->removeListener('foo', $listener1);
+ };
+ $eventDispatcher->addListener('foo', $listener1);
+ $eventDispatcher->addListener('foo', function () {});
+ $eventDispatcher->dispatch('foo');
+
+ $this->assertCount(1, $eventDispatcher->getListeners('foo'), 'expected listener1 to be removed');
+ }
}
class EventSubscriber implements EventSubscriberInterface
diff --git a/libs/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php b/libs/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php
index b291e1ee..0fdd6372 100644
--- a/libs/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php
+++ b/libs/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php
@@ -138,6 +138,58 @@ class RegisterListenersPassTest extends \PHPUnit_Framework_TestCase
$registerListenersPass = new RegisterListenersPass();
$registerListenersPass->process($container);
}
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The service "foo" must not be abstract as event subscribers are lazy-loaded.
+ */
+ public function testAbstractEventSubscriber()
+ {
+ $container = new ContainerBuilder();
+ $container->register('foo', 'stdClass')->setAbstract(true)->addTag('kernel.event_subscriber', array());
+ $container->register('event_dispatcher', 'stdClass');
+
+ $registerListenersPass = new RegisterListenersPass();
+ $registerListenersPass->process($container);
+ }
+
+ public function testEventSubscriberResolvableClassName()
+ {
+ $container = new ContainerBuilder();
+
+ $container->setParameter('subscriber.class', 'Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService');
+ $container->register('foo', '%subscriber.class%')->addTag('kernel.event_subscriber', array());
+ $container->register('event_dispatcher', 'stdClass');
+
+ $registerListenersPass = new RegisterListenersPass();
+ $registerListenersPass->process($container);
+
+ $definition = $container->getDefinition('event_dispatcher');
+ $expected_calls = array(
+ array(
+ 'addSubscriberService',
+ array(
+ 'foo',
+ 'Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService',
+ ),
+ ),
+ );
+ $this->assertSame($expected_calls, $definition->getMethodCalls());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage You have requested a non-existent parameter "subscriber.class"
+ */
+ public function testEventSubscriberUnresolvableClassName()
+ {
+ $container = new ContainerBuilder();
+ $container->register('foo', '%subscriber.class%')->addTag('kernel.event_subscriber', array());
+ $container->register('event_dispatcher', 'stdClass');
+
+ $registerListenersPass = new RegisterListenersPass();
+ $registerListenersPass->process($container);
+ }
}
class SubscriberService implements \Symfony\Component\EventDispatcher\EventSubscriberInterface
diff --git a/libs/Symfony/Component/EventDispatcher/Tests/EventTest.php b/libs/Symfony/Component/EventDispatcher/Tests/EventTest.php
index 8f2fb735..4bd26972 100644
--- a/libs/Symfony/Component/EventDispatcher/Tests/EventTest.php
+++ b/libs/Symfony/Component/EventDispatcher/Tests/EventTest.php
@@ -60,6 +60,9 @@ class EventTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($this->event->isPropagationStopped());
}
+ /**
+ * @group legacy
+ */
public function testLegacySetDispatcher()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
@@ -67,18 +70,27 @@ class EventTest extends \PHPUnit_Framework_TestCase
$this->assertSame($this->dispatcher, $this->event->getDispatcher());
}
+ /**
+ * @group legacy
+ */
public function testLegacyGetDispatcher()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$this->assertNull($this->event->getDispatcher());
}
+ /**
+ * @group legacy
+ */
public function testLegacyGetName()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$this->assertNull($this->event->getName());
}
+ /**
+ * @group legacy
+ */
public function testLegacySetName()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
diff --git a/libs/Symfony/Component/EventDispatcher/composer.json b/libs/Symfony/Component/EventDispatcher/composer.json
index 6c58d4e4..d7058629 100644
--- a/libs/Symfony/Component/EventDispatcher/composer.json
+++ b/libs/Symfony/Component/EventDispatcher/composer.json
@@ -3,7 +3,7 @@
"type": "library",
"description": "Symfony EventDispatcher Component",
"keywords": [],
- "homepage": "http://symfony.com",
+ "homepage": "https://symfony.com",
"license": "MIT",
"authors": [
{
@@ -12,13 +12,14 @@
},
{
"name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
+ "homepage": "https://symfony.com/contributors"
}
],
"require": {
- "php": ">=5.3.3"
+ "php": ">=5.3.9"
},
"require-dev": {
+ "symfony/phpunit-bridge": "~2.7",
"symfony/dependency-injection": "~2.6",
"symfony/expression-language": "~2.6",
"symfony/config": "~2.0,>=2.0.5",
@@ -30,13 +31,12 @@
"symfony/http-kernel": ""
},
"autoload": {
- "psr-0": { "Symfony\\Component\\EventDispatcher\\": "" }
+ "psr-4": { "Symfony\\Component\\EventDispatcher\\": "" }
},
- "target-dir": "Symfony/Component/EventDispatcher",
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "2.6-dev"
+ "dev-master": "2.7-dev"
}
}
}
diff --git a/libs/Symfony/Component/EventDispatcher/phpunit.xml.dist b/libs/Symfony/Component/EventDispatcher/phpunit.xml.dist
index 9a7728e9..ae0586e0 100644
--- a/libs/Symfony/Component/EventDispatcher/phpunit.xml.dist
+++ b/libs/Symfony/Component/EventDispatcher/phpunit.xml.dist
@@ -7,9 +7,9 @@
bootstrap="vendor/autoload.php"
>
-
-
+
+
./Tests/
diff --git a/libs/curl-easy/cURL/Event.php b/libs/curl-easy/cURL/Event.php
index d98238c7..53804cf6 100644
--- a/libs/curl-easy/cURL/Event.php
+++ b/libs/curl-easy/cURL/Event.php
@@ -5,6 +5,18 @@ use Symfony\Component\EventDispatcher\Event as SymfonyEvent;
class Event extends SymfonyEvent
{
- /** @var Response $response */
- public $response = null;
+ /**
+ * @var Response
+ */
+ public $response;
+
+ /**
+ * @var Request
+ */
+ public $request;
+
+ /**
+ * @var RequestsQueue
+ */
+ public $queue;
}
diff --git a/libs/curl-easy/cURL/Request.php b/libs/curl-easy/cURL/Request.php
index 461d8ad8..199ebfac 100644
--- a/libs/curl-easy/cURL/Request.php
+++ b/libs/curl-easy/cURL/Request.php
@@ -54,7 +54,7 @@ class Request extends EventDispatcher implements RequestInterface
public function getOptions()
{
if (!isset($this->options)) {
- $this->options = new Options;
+ $this->options = new Options();
}
return $this->options;
}
@@ -97,6 +97,8 @@ class Request extends EventDispatcher implements RequestInterface
* This function should be called after initializing a cURL
* session and all the options for the session are set.
*
+ * Warning: it doesn't fire 'complete' event.
+ *
* @return Response
*/
public function send()
@@ -113,32 +115,31 @@ class Request extends EventDispatcher implements RequestInterface
}
return $response;
}
-
- protected function prepareQueue()
- {
- if (!isset($this->queue)) {
- $request = $this;
- $this->queue = new RequestsQueue;
- $this->queue->addListener(
- 'complete',
- function ($event) use ($request) {
- $request->dispatch('complete', $event);
- }
- );
- $this->queue->attach($this);
- }
- }
-
+
+ /**
+ * Creates new RequestsQueue with single Request attached to it
+ * and calls RequestsQueue::socketPerform() method.
+ *
+ * @see RequestsQueue::socketPerform()
+ */
public function socketPerform()
{
- $this->prepareQueue();
+ if (!isset($this->queue)) {
+ $this->queue = new RequestsQueue();
+ $this->queue->attach($this);
+ }
return $this->queue->socketPerform();
}
-
+
+ /**
+ * Calls socketSelect() on previously created RequestsQueue
+ *
+ * @see RequestsQueue::socketSelect()
+ */
public function socketSelect($timeout = 1)
{
if (!isset($this->queue)) {
- throw new Exception('Cannot select without perform before.');
+ throw new Exception('You need to call socketPerform() before.');
}
return $this->queue->socketSelect($timeout);
}
diff --git a/libs/curl-easy/cURL/RequestsQueue.php b/libs/curl-easy/cURL/RequestsQueue.php
index 0758946e..d97661b2 100644
--- a/libs/curl-easy/cURL/RequestsQueue.php
+++ b/libs/curl-easy/cURL/RequestsQueue.php
@@ -2,9 +2,8 @@
namespace cURL;
use Symfony\Component\EventDispatcher\EventDispatcher;
-use Countable;
-class RequestsQueue extends EventDispatcher implements RequestsQueueInterface, Countable
+class RequestsQueue extends EventDispatcher implements RequestsQueueInterface, \Countable
{
/**
* @var Options Default options for new Requests attached to RequestsQueue
@@ -59,7 +58,7 @@ class RequestsQueue extends EventDispatcher implements RequestsQueueInterface, C
public function getDefaultOptions()
{
if (!isset($this->defaultOptions)) {
- $this->defaultOptions = new Options;
+ $this->defaultOptions = new Options();
}
return $this->defaultOptions;
}
@@ -126,7 +125,7 @@ class RequestsQueue extends EventDispatcher implements RequestsQueueInterface, C
unset($this->running[$request->getUID()]);
$this->detach($request);
- $event = new Event;
+ $event = new Event();
$event->request = $request;
$event->response = new Response($request, curl_multi_getcontent($request->getHandle()));
if ($result !== CURLE_OK) {
@@ -134,6 +133,7 @@ class RequestsQueue extends EventDispatcher implements RequestsQueueInterface, C
}
$event->queue = $this;
$this->dispatch('complete', $event);
+ $request->dispatch('complete', $event);
}
return $n;
@@ -168,9 +168,11 @@ class RequestsQueue extends EventDispatcher implements RequestsQueueInterface, C
*/
protected function getRequestsNotRunning()
{
- return array_diff_key($this->queue, $this->running);
+ $map = $this->queue;
+ foreach($this->running as $k => $v) unset($map[$k]);
+ return $map;
}
-
+
/**
* Download available data on socket.
*
@@ -200,12 +202,15 @@ class RequestsQueue extends EventDispatcher implements RequestsQueueInterface, C
$mrc = curl_multi_exec($this->mh, $this->runningCount);
} while ($mrc === CURLM_CALL_MULTI_PERFORM);
$runningAfter = $this->runningCount;
-
- $completed = ($runningAfter < $runningBefore) ? $this->read() : 0;
+
+ if ($runningAfter < $runningBefore) {
+ $this->read();
+ }
$notRunning = $this->getRequestsNotRunning();
} while (count($notRunning) > 0);
-
+ // Why the loop? New requests might be added at runtime on 'complete' event.
+ // So we need to attach them to curl_multi handle immediately.
return $this->count() > 0;
}