2

I need to find out if any changes have been made to the entry on successful save.

Using events entries.onBeforeSaveEntry and entries.onSaveEntry seems to be a way to do it. Maybe.

Can I pass some entry variables as arguments to the function on event listener?

public function init()
{
    parent::init();

    $oldVar = "";

    //Event: onBeforeSaveEntry
    craft()->on('entries.beforeSaveEntry', function (Event $event)
    {
        $entryModel = $event->params['entry'];
        $oldVar     = $entryModel->fieldVar;
    });

    //Event: onSaveEntry
    craft()->on('entries.saveEntry', function (Event $event)
    {
        $entryModel = $event->params['entry'];
        $newVar     = $entryModel->fieldVar;

        if ( $oldVar !== $newVar ){
            // ...
        }
    });
}

1 Answer 1

2

This will not work as the field value will be the new value in both events. You'll need to get the old value from the entry that exists in Craft before saving the new entry, and then perform the comparison.

If the value has changed then store the entry ID to process once the entry has successfully saved.

Note that the $entryIdChanged variable in the anonymous event functions is not in the same as that in the init() method. You can resolve this as follows:

  1. Bring the $entryIdChanged variable into the anonymous functions using the use operator.
  2. PHP will by default "pass by value", meaning that if the value of the variable within the function is changed, it does not get changed outside of the function. So you should pass the variable in "by reference", using an ampersand & before the variable name, which will change it outside the function as well.

See the PHP guide on Passing by Reference.

public function init()
{
    parent::init();

    $entryIdChanged = null;

    // Event: onBeforeSaveEntry
    craft()->on('entries.beforeSaveEntry', function (Event $event) use (&$entryIdChanged)
    {
        $entryModel = $event->params['entry'];
        $newVar     = $entryModel->fieldVar;

        $oldEntry = craft()->entries->getEntryById($entryModel->id);
        $oldVar = $oldEntry !== null ? $oldEntry->fieldVar : '';

        if ($oldVar !== $newVar){
            $entryIdChanged = $entryModel->id;
        }
    });

    // Event: onSaveEntry
    craft()->on('entries.SaveEntry', function (Event $event) use ($entryIdChanged)
    {
        $entryModel = $event->params['entry'];

        if ($entryModel->id === $entryIdChanged){
            // ...
        }
    });
}
14
  • I'll try it. Actually I've recently been reading that PHP guide but I haven't had a chance to try it. But definitely I would start with use ($oldVar) without an ampersand &. Commented Nov 12, 2018 at 21:09
  • 1
    I've updated my answer to explain why the ampersand is important.
    – Ben Croker
    Commented Nov 13, 2018 at 7:27
  • I'm testing it on lightswitch field but I'm getting the same output value from both events. I've also checked what output value of that lightswitch field will give beforeSaveEntry event. The output is always oposite. Commented Nov 20, 2018 at 11:04
  • 1
    I've rewritten the answer which should work or at least get you 90% of the way there :)
    – Ben Croker
    Commented Nov 20, 2018 at 15:44
  • That worked well :) But I'm thinking to pass the $oldVar to function on saveEntry event and I'll be sure that an email sends only if entry is saved. I've already tested and it works. Commented Nov 20, 2018 at 19:01

Your Answer

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

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