EventDispatcher.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <?php
  2. /*
  3. * This file is part of Composer.
  4. *
  5. * (c) Nils Adermann <naderman@naderman.de>
  6. * Jordi Boggiano <j.boggiano@seld.be>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Composer\Script;
  12. use Composer\Json\JsonFile;
  13. use Composer\Repository\FilesystemRepository;
  14. use Composer\Autoload\ClassLoader;
  15. use Composer\Package\PackageInterface;
  16. use Composer\IO\IOInterface;
  17. use Composer\Composer;
  18. use Composer\DependencyResolver\Operation\OperationInterface;
  19. /**
  20. * The Event Dispatcher.
  21. *
  22. * Example in command:
  23. * $dispatcher = new EventDispatcher($this->getComposer(), $this->getApplication()->getIO());
  24. * // ...
  25. * $dispatcher->dispatch(ScriptEvents::POST_INSTALL_CMD);
  26. * // ...
  27. *
  28. * @author François Pluchino <francois.pluchino@opendisplay.com>
  29. * @author Jordi Boggiano <j.boggiano@seld.be>
  30. */
  31. class EventDispatcher
  32. {
  33. protected $composer;
  34. protected $io;
  35. protected $loader;
  36. /**
  37. * Constructor.
  38. *
  39. * @param Composer $composer The composer instance
  40. * @param IOInterface $io The IOInterface instance
  41. */
  42. public function __construct(Composer $composer, IOInterface $io)
  43. {
  44. $this->composer = $composer;
  45. $this->io = $io;
  46. $this->loader = new ClassLoader();
  47. $this->loader->register();
  48. }
  49. /**
  50. * Dispatch a package event.
  51. *
  52. * @param string $eventName The constant in ScriptEvents
  53. * @param OperationInterface $operation The package being installed/updated/removed
  54. */
  55. public function dispatchPackageEvent($eventName, OperationInterface $operation)
  56. {
  57. $this->doDispatch(new PackageEvent($eventName, $this->composer, $this->io, $operation));
  58. }
  59. /**
  60. * Dispatch a command event.
  61. *
  62. * @param string $eventName The constant in ScriptEvents
  63. */
  64. public function dispatchCommandEvent($eventName)
  65. {
  66. $this->doDispatch(new CommandEvent($eventName, $this->composer, $this->io));
  67. }
  68. /**
  69. * Triggers the listeners of an event.
  70. *
  71. * @param Event $event The event object to pass to the event handlers/listeners.
  72. */
  73. protected function doDispatch(Event $event)
  74. {
  75. $listeners = $this->getListeners($event);
  76. foreach ($listeners as $callable) {
  77. $className = substr($callable, 0, strpos($callable, '::'));
  78. $methodName = substr($callable, strpos($callable, '::') + 2);
  79. if (!class_exists($className)) {
  80. throw new \UnexpectedValueException('Class '.$className.' is not autoloadable, can not call '.$event->getName().' script');
  81. }
  82. if (!is_callable($callable)) {
  83. throw new \UnexpectedValueException('Method '.$callable.' is not callable, can not call '.$event->getName().' script');
  84. }
  85. $className::$methodName($event);
  86. }
  87. }
  88. /**
  89. * @param Event $event Event object
  90. * @return array Listeners
  91. */
  92. protected function getListeners(Event $event)
  93. {
  94. $package = $this->composer->getPackage();
  95. $scripts = $package->getScripts();
  96. $autoload = $package->getAutoload();
  97. // get namespaces in composer.json project
  98. if (!$this->loader->getPrefixes() && isset($autoload['psr-0'])) {
  99. krsort($autoload['psr-0']);
  100. foreach ($autoload['psr-0'] as $ns => $path) {
  101. $this->loader->add($ns, rtrim(getcwd().'/'.$path, '/'));
  102. }
  103. }
  104. return isset($scripts[$event->getName()]) ? $scripts[$event->getName()] : array();
  105. }
  106. }