Плагин Composer после автозагрузки дампа срабатывает слишком поздно

Я пытаюсь написать плагин composer для модульной структуры, которую я создаю, чтобы каждый модуль проверялся и регистрировался после того, как автозагрузчик был выгружен.

Если я вручную запустить скрипт через обертку в "scripts" часть composer.json кажется, работает, однако плагин не срабатывает на событие.

Это урезанная версия плагина, ограниченная только событием.

<?php

namespace My\Namespace;

use Composer\Composer;
use Composer\Config;
use Composer\EventDispatcher\EventSubscriberInterface;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginEvents;
use Composer\Plugin\PluginInterface;
use Composer\Script\CommandEvent;

class Plugin implements PluginInterface, EventSubscriberInterface
{
    /**
     * @param Composer $composer
     * @param IOInterface $io
     */
    public function activate(Composer $composer, IOInterface $io) { }

    /**
     * Once the autoloader has been dumped
     * @param Event $event
     */
    public function onPostAutoloadDump(CommandEvent $event)
    {
        $event->getIO()->write('Autoload dumped.');
    }

    /**
     * @return array
     */
    public static function getSubscribedEvents()
    {
        return [
            PluginEvents::COMMAND => [
                ['onPostAutoloadDump' => 0]
            ]
        ];
    }
}

Документация по плагину находится здесь: https://getcomposer.org/doc/articles/plugins.md
Имена событий здесь: https://getcomposer.org/doc/articles/scripts.md#event-names

В состав composer.json входит

{
  ...
  "type": "composer-plugin",
  "extra": {
    "class": "My\\Namespace\\Plugin"
  },
  ...
}

Я пытался изменить CommandEvent для обычного Event и я попытался изменить тип события на onPreFileDownload,

Иногда это будет бросать:

[ErrorException]     
Undefined offset: 0  

Но я не могу понять это также, поскольку нет следа стека.

Я не могу понять, что мне не хватает.

1 ответ

Решение

Это не очевидно (по крайней мере для меня) в документации, но все, что вам нужно сделать, это:

Чтобы зарегистрировать метод в событии, просто верните массив, ключом которого является имя события (приведенное здесь), а значением - имя метода в этом классе, который нужно вызвать.

/**
 * @return array
 */
public static function getSubscribedEvents()
{
    return [
        'post-autoload-dump' => 'methodToBeCalled',
        // ^ event name ^         ^ method name ^                   
    ];
}

По умолчанию приоритет обработчика событий установлен равным 0. Приоритет можно изменить, добавив кортеж, в котором первое значение является именем метода, как и раньше, а второе значение является целым числом, представляющим приоритет. Более высокие целые числа представляют более высокие приоритеты, поэтому приоритет 2 вызывается перед приоритетом 1 и т. Д.

/**
 * @return array
 */
public static function getSubscribedEvents()
{
    return [
        // Will be called before events with priority 0
        'post-autoload-dump' => ['methodToBeCalled', 1] 
    ];
}

Если нужно вызвать несколько методов, к каждому событию можно прикрепить массив кортежей. Кортежи не должны включать приоритет. Если он опущен, по умолчанию он будет равен 0.

/**
 * @return array
 */
public static function getSubscribedEvents()
{
    return [
        'post-autoload-dump' => [
            ['methodToBeCalled'      ], // Priority defaults to 0
            ['someOtherMethodName', 1], // This fires first
        ]
    ];
}
Другие вопросы по тегам