Jonathan Lahijani Posted April 22, 2015 Share Posted April 22, 2015 I'm having trouble figuring out how to do this correctly. Let's say I have a page with an ASM select field. Let's say this ASM select field has values A, B and C selected. Let's say the page is edited so that the ASM select field has C removed and then it is saved. How do I determine specifically if C was removed and also display a custom notification if C was removed (in addition PW's regular save page notification)? I've got my code to a point where it can determine if this field was changed, but not specifically what value were changed. Not sure how to do it. Thank you. 1 Link to comment Share on other sites More sharing options...
arjen Posted April 22, 2015 Share Posted April 22, 2015 Hi jlahijani, Do these posts from ryan and soma will work for you as a starting point? 2 Link to comment Share on other sites More sharing options...
horst Posted April 22, 2015 Share Posted April 22, 2015 a good one may also be this with track changes (see Somas post there) 2 Link to comment Share on other sites More sharing options...
Martijn Geerts Posted April 22, 2015 Share Posted April 22, 2015 (edited) Not tested but something simular would work I guess $this->addHookAfter('Pages::saveReady', $this, 'hookPagesSave'); public function hookPagesSave(HookEvent $event) { // Modified page, already contains changes in memory, not yet in DB $page = $event->arguments('page'); // If there is a change in your field if ($page->isChanged('name_of_you_field')) { // Page as it is in the DB $oldPage = $this->pages->get($page->id); // ... Now you could do your comparison old <-> new. } } Edited November 4, 2015 by Martijn Geerts code corrected, honour goes to gebeer! 6 Link to comment Share on other sites More sharing options...
gebeer Posted November 4, 2015 Share Posted November 4, 2015 Not tested but something simular would work I guess $this->addHookAfter('Pages::saveReady', $this, 'hookPagesSave'); public function hookPagesSave(HookEvent $event) { // Modified page, already contains changes in memory, not yet in DB $page = $event->arguments('page'); // If there is a change in your field if ($page->trackChange('name_of_you_field')) { // Page as it is in the DB $oldPage = $this->pages->get($page->id); // ... Now you could do your comparison old <-> new. } } if ($page->trackChange('name_of_you_field')) {...} got triggered for me on every page save, no matter if the value of my field had changed or not. Changing it to if ($page->isChanged('name_of_you_field')) {...} brought the desired result. See also $page->isChanged("field") in API cheat sheet 4 Link to comment Share on other sites More sharing options...
LostKobrakai Posted November 4, 2015 Share Posted November 4, 2015 The track change function is actually there to force the changed status for the field, which does explain why it always reportet a change. 2 Link to comment Share on other sites More sharing options...
Martijn Geerts Posted November 4, 2015 Share Posted November 4, 2015 Thanks @gebeer to correct it ! 2 Link to comment Share on other sites More sharing options...
ryan Posted November 5, 2015 Share Posted November 5, 2015 In Martijn's hook, the $oldPage retrieval will return the same exact copy as $page, so it won't be possible to compare them since you'll be comparing the same page instance. What you'd want to do instead is retrieve a fresh copy of the page, then you should have two different instances of the same page to compare: $oldPage = $this->wire('pages')->getById($page->id, array( 'cache' => false, // don't let it write to cache 'getFromCache' => false, // don't let it read from cache )); I think you'll need the dev branch for this, as the 'getFromCache' option is not in PW 2.6.1 if I recall correctly. In 2.6.1 or earlier, I think that the following would work, but is not quite as efficient: $this->wire('pages')->uncache($page); $oldPage = $this->wire('pages')->get($page->id); 2 Link to comment Share on other sites More sharing options...
Martijn Geerts Posted November 5, 2015 Share Posted November 5, 2015 I had the presumption that Pages::saveReady hold the values from the to be saved page (runtime) and not the value out of the database. 1 Link to comment Share on other sites More sharing options...
ryan Posted November 5, 2015 Share Posted November 5, 2015 I had the presumption that Pages::saveReady hold the values from the to be saved page (runtime) and not the value out of the database. That's correct. PW tries really hard not to keep multiple copies of the same page in memory at once, which is why you have to make it force-reload a fresh copy from the DB if you want to know what the page looked like before changes were made to it. Link to comment Share on other sites More sharing options...
Martijn Geerts Posted November 5, 2015 Share Posted November 5, 2015 Ok... so $oldPage = $this->pages->get($page->id); won't give you the old page? I have somewhere implemented that and it worked. (or I introduced a bug ) Link to comment Share on other sites More sharing options...
ryan Posted November 5, 2015 Share Posted November 5, 2015 Nope, it would give you the same copy that you already have. Unless something cleared the page cache between the time you loaded $page and the time you did your $pages->get(). PW clears the page cache after every save() or delete(), so if you found it was working in your case then chances are there was a save() that occurred after you loaded $page, but before you tried to retrieve $oldPage. 2 Link to comment Share on other sites More sharing options...
Martijn Geerts Posted November 5, 2015 Share Posted November 5, 2015 Thanks stepping in here Ryan! Link to comment Share on other sites More sharing options...
Ivan Gretsky Posted November 11, 2015 Share Posted November 11, 2015 In Martijn's hook, the $oldPage retrieval will return the same exact copy as $page, so it won't be possible to compare them since you'll be comparing the same page instance. What you'd want to do instead is retrieve a fresh copy of the page, then you should have two different instances of the same page to compare: $oldPage = $this->wire('pages')->getById($page->id, array( 'cache' => false, // don't let it write to cache 'getFromCache' => false, // don't let it read from cache )); I did try this and it did not work, because getById returns a PageArray, not a Page object in spite of the get part in the method name. Using something like first() on the returned result seems to give you the cashed (changed) version of the page. But there is a getOne option that managed to do the trick. So I could only get it to work like this: $oldPage = $this->wire('pages')->getById($page->id, array( 'cache' => false, // don't let it write to cache 'getFromCache' => false, // don't let it read from cache 'getOne' => true, // return a Page instead of a PageArray )); 6 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now