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?
Craft CMS Stack Exchange is a question and answer site for administrators, end users, developers and designers for Craft CMS. It only takes a minute to sign up.
Sign up to join this communityNot 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'
Edit: This doesn't actually appear to work, at least not reliably.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.
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.