4

I have 2 separate plugins that listen to same event.

Now I want to make sure Plugin B starts its action only after Plugin A has finished its job.

Is there a way in Craft CMS to set priority / execution order for plugins that listen to same event?

1 Answer 1

5

Not really – there's no priority system built into events for Craft or Yii.

The easy way out is taking advantage of the fact that Craft actually loads plugins alphabetically, by name (i.e. the string returned by the plugins' getName() method). This means that if your plugins are in fact named "Plugin A" and "Plugin B", then Plugin A will be loaded before Plugin B and you can be sure that its event listener is also attached earlier, meaning that – in theory, I haven't tested this – it's event listener should also be called before Plugin B's event listener. Edit: This doesn't actually appear to work, at least not reliably.

Of course, the correct way to solve the issue is to write your code in a way that negates the need for sequentially dependent event handlers. One way to do this is to use custom events – for instance, you could have Plugin A listen to the native entries.saveEntry event, but have Plugin B listen to some custom event instead, where Plugin A fires the custom event after completing its work inside the saveEntry handler.

You could also consider dropping the event listener altogether for Plugin B, and just call one of its service methods directly from Plugin A's event listener (you can even pass in the event object if you need it):

// Plugin A
craft()->on('entries.saveEntry', function (Event $event)
{
    ...
    // Stuff happens, then let Plugin B do its thing
    $pluginB = craft()->plugins->getPlugin('pluginB');
    if ($pluginB) {
        craft()->pluginB->someMethodName($event);
    }
}

...and in Craft 3:

// Plugin A
yii\base\Event::on(
    craft\elements\Entry::class,
    craft\base\element::EVENT_AFTER_SAVE,
    function (craft\events\ModelEvent $event) {
        ...
        // Stuff happens, then let Plugin B do its thing
        $pluginB = Craft::$app->getPlugins()->getPlugin('plugin-b');
        if ($pluginB) {
            $pluginB->someService->someMethodName($event);
        }
    }
);

Beyond this, its hard to advise without seeing some code examples or a more elaborate use case.

4
  • Unfortunately relying on alphabetical order did not work for me. I ended up with calling Plugin B directly from Plugin A Jun 20, 2016 at 10:12
  • Allright, thanks for clearing that up @YuriSalimovskiy :) Jun 20, 2016 at 10:15
  • @MatsMikkelRummelhoff how can we do the same for Craft 3? Oct 18, 2021 at 2:23
  • @BhashkarYadav Just updated the answer with that same code example for Craft 3. Oct 19, 2021 at 6:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.