Jump to:

3431 Posts in 1058 Topics by 734 members

Data Model Questions

SilverStripe Forums » Data Model Questions » onBeforeWrite called multiple times

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1 2
Go to End
Author Topic: 2956 Views
  • Nathan Cox
    Avatar
    Community Member
    99 Posts

    onBeforeWrite called multiple times Link to this post

    Hi, I'm making a site in 2.3.1 and trying to put some code in Page::onBeforeWrite().
    The problem is, onBeforeWrite always gets called multiple times - twice if I just click "save", four times if I click "save and publish".

    Is this the normal behaviour? What can I do to just get it to run some code once?

  • UncleCheese
    Avatar
    4085 Posts

    Re: onBeforeWrite called multiple times Link to this post

    Yes! I made a post about this a while back, as well. Annoying, isn't it? My solution was really crude. I set a static class variable to choke the onBeforeWrite() after the first execution.

    static $has_written = false;

    public function onBeforeWrite()
    {
    if(!self::$has_written) {
    // do stuff
    self::$has_written = true;
    }
    parent::onBeforeWrite();
    }

    I'd really like more information about it, though, cause as you can see, it's a total hack and should not be necessary.

  • Nathan Cox
    Avatar
    Community Member
    99 Posts

    Re: onBeforeWrite called multiple times Link to this post

    Yeah this is making no sense to me at all...unfortunately your method doesn't entirely work for me since if I only make a change on one of the iterations it seems to get overwritten by later ones.
    For example, I tried just adding "-test" to the URLSegment in onBeforeWrite, but if I use a static var to only do it once the change shows up in the sitetree table/cms but it it doesn't add -test to sitetree_live, so doesn't show up on the frontend. Without the static var filter I end up with things like -test-test on my URLSegment.

    I did a dump of $this and compared all four times it ran. I'm wondering if it runs for every table attached to the object? The first one doesn't show the newly posted data or have any of the class-specific $db fields. It makes a new version number every time, though. The status attribute goes Published -> Saved (update) -> Published -> Published, and each time the changed and original arrays do or don't have different attributes but I'm not seeing a pattern.

    So in short I don't know why it does this but it's stuffing up the probably-way-too complicated bit of hacking I was trying to do here :/

  • Ingo
    Avatar
    Forum Moderator
    801 Posts

    Re: onBeforeWrite called multiple times Link to this post

    Have a look in LeftAndMain->save() - if you hit "Save and Publish" in the CMS, these four lines cause the record to be written:
    $record->writeWithoutVersion();
    $record = $record->newClassInstance( $newClass );
    $record->write();
    $record->doPublish();

    There's no easy way around this, as far as I can see we need to write at least twice. In case of the "-test-test" problem, you'll have that as well if the record persists a bit longer in memory than you think in different cases. The easiest solid way is to make sure you didn't add "-test" already I guess? You can also use getChangedFields() to detect if any fields have changed (which gets reset after each write call). So in case of the URL, you could just react in your onBeforeWrite() if the URL has actually changed.

  • Fuzz10
    Avatar
    Community Member
    787 Posts

    Re: onBeforeWrite called multiple times Link to this post

    ;-)

    Just bumped into this myself just now. Interesting bug.

    Someone made a ticket for this already ?

  • Ben Gribaudo
    Avatar
    Community Member
    181 Posts

    Re: onBeforeWrite called multiple times Link to this post

    It would be nice for this issue to be fixed!

  • Harley
    Avatar
    Community Member
    153 Posts

    Re: onBeforeWrite called multiple times Link to this post

    I'm also having this trouble, would be good if there was a fix. Any updates?

    Regards

    Harley

  • dalesaurus
    Avatar
    Community Member
    283 Posts

    Re: onBeforeWrite called multiple times Link to this post

    Just ran into this and am successfully using UncleCheese's hack. Effective!

    2956 Views
Page: 1 2
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.