EventDispatcher.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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\AutoloadGenerator;
  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. }
  47. /**
  48. * Dispatch a package event.
  49. *
  50. * @param string $eventName The constant in ScriptEvents
  51. * @param OperationInterface $operation The package being installed/updated/removed
  52. */
  53. public function dispatchPackageEvent($eventName, OperationInterface $operation)
  54. {
  55. $this->doDispatch(new PackageEvent($eventName, $this->composer, $this->io, $operation));
  56. }
  57. /**
  58. * Dispatch a command event.
  59. *
  60. * @param string $eventName The constant in ScriptEvents
  61. */
  62. public function dispatchCommandEvent($eventName)
  63. {
  64. $this->doDispatch(new CommandEvent($eventName, $this->composer, $this->io));
  65. }
  66. /**
  67. * Triggers the listeners of an event.
  68. *
  69. * @param Event $event The event object to pass to the event handlers/listeners.
  70. */
  71. protected function doDispatch(Event $event)
  72. {
  73. $listeners = $this->getListeners($event);
  74. foreach ($listeners as $callable) {
  75. $className = substr($callable, 0, strpos($callable, '::'));
  76. $methodName = substr($callable, strpos($callable, '::') + 2);
  77. if (!class_exists($className)) {
  78. throw new \UnexpectedValueException('Class '.$className.' is not autoloadable, can not call '.$event->getName().' script');
  79. }
  80. if (!is_callable($callable)) {
  81. throw new \UnexpectedValueException('Method '.$callable.' is not callable, can not call '.$event->getName().' script');
  82. }
  83. $className::$methodName($event);
  84. }
  85. }
  86. /**
  87. * @param Event $event Event object
  88. * @return array Listeners
  89. */
  90. protected function getListeners(Event $event)
  91. {
  92. $package = $this->composer->getPackage();
  93. $scripts = $package->getScripts();
  94. if (empty($scripts[$event->getName()])) {
  95. return array();
  96. }
  97. if ($this->loader) {
  98. $this->loader->unregister();
  99. }
  100. $generator = new AutoloadGenerator;
  101. $packages = $this->composer->getRepositoryManager()->getLocalRepository()->getPackages();
  102. $packageMap = $generator->buildPackageMap($this->composer->getInstallationManager(), $package, $packages);
  103. $map = $generator->parseAutoloads($packageMap);
  104. $this->loader = $generator->createLoader($map);
  105. $this->loader->register();
  106. return $scripts[$event->getName()];
  107. }
  108. }