From a67b127a1a993aa89c79f8026cb04de6a43c923e Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 24 Apr 2016 15:48:48 +0100 Subject: [PATCH] Add deprecation notice for the event type hint rewrites, refs #5238 --- doc/articles/scripts.md | 6 ++-- .../EventDispatcher/EventDispatcher.php | 28 +++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/doc/articles/scripts.md b/doc/articles/scripts.md index 415d56f63..463e59875 100644 --- a/doc/articles/scripts.md +++ b/doc/articles/scripts.md @@ -150,11 +150,13 @@ class MyClass } ``` +## Event classes + When an event is fired, your PHP callback receives as first argument a `Composer\EventDispatcher\Event` object. This object has a `getName()` method -that lets you retrieve event name. +that lets you retrieve the event name. -Depending on the script types (see list above) you will get various event +Depending on the [script types](#event-names) you will get various event subclasses containing various getters with relevant data and associated objects: diff --git a/src/Composer/EventDispatcher/EventDispatcher.php b/src/Composer/EventDispatcher/EventDispatcher.php index 57218f676..358b03181 100644 --- a/src/Composer/EventDispatcher/EventDispatcher.php +++ b/src/Composer/EventDispatcher/EventDispatcher.php @@ -262,6 +262,14 @@ class EventDispatcher */ protected function checkListenerExpectedEvent($target, Event $event) { + if (in_array($event->getName(), array( + 'init', + 'command', + 'pre-file-download', + ), true)) { + return $event; + } + try { $reflected = new \ReflectionParameter($target, 0); } catch (\Exception $e) { @@ -278,11 +286,13 @@ class EventDispatcher // BC support if (!$event instanceof $expected && $expected === 'Composer\Script\CommandEvent') { + trigger_error('The callback '.$this->serializeCallback($target).' declared at '.$reflected->getDeclaringFunction()->getFileName().' accepts a '.$expected.' but '.$event->getName().' events use a '.get_class($event).' instance. Please adjust your type hint accordingly, see https://getcomposer.org/doc/articles/scripts.md#event-classes', E_USER_DEPRECATED); $event = new \Composer\Script\CommandEvent( $event->getName(), $event->getComposer(), $event->getIO(), $event->isDevMode(), $event->getArguments() ); } if (!$event instanceof $expected && $expected === 'Composer\Script\PackageEvent') { + trigger_error('The callback '.$this->serializeCallback($target).' declared at '.$reflected->getDeclaringFunction()->getFileName().' accepts a '.$expected.' but '.$event->getName().' events use a '.get_class($event).' instance. Please adjust your type hint accordingly, see https://getcomposer.org/doc/articles/scripts.md#event-classes', E_USER_DEPRECATED); $event = new \Composer\Script\PackageEvent( $event->getName(), $event->getComposer(), $event->getIO(), $event->isDevMode(), $event->getPolicy(), $event->getPool(), $event->getInstalledRepo(), $event->getRequest(), @@ -290,6 +300,7 @@ class EventDispatcher ); } if (!$event instanceof $expected && $expected === 'Composer\Script\Event') { + trigger_error('The callback '.$this->serializeCallback($target).' declared at '.$reflected->getDeclaringFunction()->getFileName().' accepts a '.$expected.' but '.$event->getName().' events use a '.get_class($event).' instance. Please adjust your type hint accordingly, see https://getcomposer.org/doc/articles/scripts.md#event-classes', E_USER_DEPRECATED); $event = new \Composer\Script\Event( $event->getName(), $event->getComposer(), $event->getIO(), $event->isDevMode(), $event->getArguments(), $event->getFlags() @@ -299,6 +310,23 @@ class EventDispatcher return $event; } + private function serializeCallback($cb) + { + if (is_array($cb) && count($cb) === 2) { + if (is_object($cb[0])) { + $cb[0] = get_class($cb[0]); + } + if (is_string($cb[0]) && is_string($cb[1])) { + $cb = implode('::', $cb); + } + } + if (is_string($cb)) { + return $cb; + } + + return var_export($cb, true); + } + /** * Add a listener for a particular event *