Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

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

onAfterWrite not giving correct link()


Reply


4 Posts   1172 Views

Avatar
otherjohn

Community Member, 125 Posts

1 June 2011 at 4:21am

Hi all,
I am trying to send blog posts to an api but when I try to get the $this->Link() in my onAfterWrite function, it returns the link that is automatically created, not the saved one.

For example, if its a blog post Link returns "/blog/new-blogentry/" instead of "/blog/my-set-link/"
if its a page it returns "/new-page" instead of "/my-page-link"

Any idea what I need to do to get the correct link?

Also "$this->obj('Content')->NoHTML();" is coming up blank...

I have the following in my Page.php file.

public function onAfterWrite() {
         parent::onAfterWrite();
.... $this->Link();
... $this->obj('Content')->NoHTML();
...
...
}

Avatar
swaiba

Forum Moderator, 1805 Posts

1 June 2011 at 4:29am

I'd do a debug of $this and see what it's got.

I think I may have used the ID to do a DataObject::get_by_id of the very same object in an onAfterWrite to get the db contents... even though this might not be best... it might work....

Avatar
otherjohn

Community Member, 125 Posts

1 June 2011 at 6:06am

Very odd. I am not getting all the updated info when doing it the original nor DataObject::get_by_id
for example "title" stays New BlogEntry instead of the new title I wrote.

perhaps I need to call the write function first?

Avatar
HARVS1789UK

Community Member, 21 Posts

2 October 2012 at 1:16am

Edited: 02/10/2012 4:38am

Swaiba is correct that doing a DataObject::get_by_id('Some_Object', $this->ID, false); will solve the problem.

This is because not all database calculated values (e.g. LastEdited) are not actually returned to the current instance of our object ($this) until AFTER the onAfterWrite has finished.

For example:

- $this is our current instance of object_x
- In the onBeforeWrite() function our DB table column which represents object_x HAS been updated and things like the LastEdited field have been set
- However, these DB generated values (I have not tested it to be sure but id imagine Created, LastEdited and ClassName are the values in question) are not returned to our instance of objext_x ($this) until AFTER the onAfterWrite has finished.
- Therefore they cannot be used/are old data when used in the onBeforeWrite()

Using

$obj = DataObject::get_by_id('Some_Object', $this->ID, false);
if($obj->SomeField == 'Some Value') {
// Do Stuff
}

rather than

if($this->SomeField == 'Some Value') {
// Do Stuff
}

solves the issue as it effectivly manually refreshes/updates your current instance of object_x

EDIT: Having implemented my own fix and still having issues with my returned LastEdited DATETIME I have realised something very interesting. Many of you may well know (as it is in the docs) that DataObject::get_one has a cached query option which defaults to true. DataObject::get_by_id() has absolutely no mention of the caching option in the docs anywhere I can see, but guess what it uses to do its lookup...a modified get_one()! Meaning that DataObject::get_by_id also uses a cached query by default! There is an optional third parmeter to overwrite this and do a fresh query, however it doesn't seem to be documented anywhere. See my line above. The third parameter was integral to my code working as using a cached query returned me outdated data!