Juergen Posted September 22, 2015 Share Posted September 22, 2015 Hello at all,I want to use a Hook after page save of a child page to add a specific value to the parent page under a certain condition.Here is the scenario.Page structure:- productoverviewpage -product detail page - productprice page 1 - productprice page 2 - productprice page 3 and so onThe product overview page includes all product pages - so its the overview of all available products.The product page itself is the detailpage for the product.Every productpage consists of different sub pages with price information, because every product has more than 1 price (depending on size and amount).Examples:Productprice page 1 has the price of 5 Euro for a small bottle.Productprice page 2 has the price of 9 Euro for a big bottle.So every productprice page consists of a specific price for the same product.On the productprice page you can choose wheater this price is an offerprice or not (simple select form field)My Goal:I need to check all the productprice pages if there is an offer available or not. If there is an offerprice in one or more productprice pages than I want to add for example the value "1" to a text field of the parent page (product detail page) via a Hook after saving the productprice page.So this is what I have tried to add the value. //selectors $productpricepageselector = $page->template == "pricelistitem";//check if page is a productprice page $offerselector = 'pricetype *= "2"';//selector if any of the children contain an offervalue (value = 2 in pricetypefield) $productdetailpageselector = "template=products";//selector of the product detail page //condition if(($productpricepageselector) AND ($page->children($offerselector)) AND($page->parents(productdetailpageselector))){ $this->message("Produkt wurde auf Angebot gesetzt"); $page->parents->offercheck = "1";//this should add the value 1 to the field "offercheck" in the parent template } But nothing happens. Maybe this condition is not true : ($page->children($offerselector)) It should be like $parent ->children($offerselector) because it should check all the other children of the product detail page. Has anyone an idea? Best regards Link to comment Share on other sites More sharing options...
LostKobrakai Posted September 22, 2015 Share Posted September 22, 2015 You can't use spaces in selector pairs: $offerselector = 'pricetype=2'; // no need for *= except you're really searching a textfield Also for such things use not Pages::save, but rather the Pages::saved hook. Link to comment Share on other sites More sharing options...
Juergen Posted September 22, 2015 Author Share Posted September 22, 2015 Thanks KobraKai I guess I need a Hook because I run it from a Hook module in the backend after page save. Main problem at the moment is how to add a value from this page to the parent page. F.e. $page->parent->fieldname = "1" doesnt work Link to comment Share on other sites More sharing options...
LostKobrakai Posted September 22, 2015 Share Posted September 22, 2015 Are you sure this line is executed? Where is the parent page saved? Also make sure it does say parent as your first code does say parents. Link to comment Share on other sites More sharing options...
Juergen Posted September 22, 2015 Author Share Posted September 22, 2015 I use a Hook module from Soma which adds the save action: https://gist.github.com/somatonic/11206761 Sorry wrong link - I look for the right one Cant find the page but this is the code of the Hook module, where I have added all my Hook events. <?php /** * Hook the saving of pages to add own processes. * * ProcessWire 2.x * Copyright (C) 2014 by Ryan Cramer * Licensed under GNU/GPL v2, see LICENSE.TXT * * http://processwire.com * */ class HookAfterPagesSave extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'HookAfterPageSave', 'version' => 1, 'summary' => 'Delete offer price if standard price is selected.', 'singular' => true, // Limit the module to a single instance 'autoload' => true, // Load the module with every call to ProcessWire ); } public function init() { // init() is called when the module is loaded. // saveReady is a hook after processing the previous changes of the page, // but just before those changes are saved to the database. // It's called for each page that's being saved, no matter if it's in // the backend or in your templates via the api. $this->addHookAfter('Pages::saveReady', $this, 'afterSaveReady'); } public function afterSaveReady($event) { // 1) Get the soon to be saved page object from the given event $page = $event->arguments[0]; if(($page->template == "pricelistitem") AND ($page->parents("template=products"))){ $parentid = $page->parent_id; $parentpage = $pages->get($parentid); /* if(){ $this->message("Produkt wurde auf Angebot gesetzt"); $page->parents->offercheck = "1";//this should add the value 1 to the field "offercheck" in the parent template } else { */ $page->parent->offercheck = "1";//this should add the value 0 to the field "offercheck" in the parent template //} } // delete offerprice if standard price is choosen if(($page->template == "pricelistitem") AND ($page->pricetype == "1")){ $this->message("Angebotspreis wurde entfernt"); $page->offertprice = ""; } //delete all prices if pricekind is 3 or 4 if(($page->template == "pricelistitem") AND ($page->pricelistselect >= "3")){ $this->message("Standardpreis wurde entfernt"); $this->message("Angebotspreis wurde entfernt"); $page->offertprice = ""; $page->standardprice = ""; } //delete all dates if service is unlimited in time if(($page->template == "pricelistitem") AND ($page->timelimit >= "2")){ $this->message("Startdatum wurde auf jetzt geändert"); $this->message("Enddatum wurde entfernt"); $page->publish_from = $date = date('Y-m-d H:i'); $page->publish_until = ""; } // 2) delete event texts if event is cancelled or not //clean all up if event is cancelled if(($page->template == "events") AND ($page->cancelled == "1")){ $this->message("Folgende Felder wurden geleert: Einleitungssatz, Hauptteil, Preis, Preiszusatz, Veranstaltungsortname, Downloaddateien"); $page->body = ""; $page->introtext = ""; $page->eventprice = ""; $page->eventpriceadd = ""; $page->eventcosttype = "1"; /* foreach($page->downloadrepeater as $dp){ $dp->delete($p->downloadfield); $dp->downloadfieldtitle = ""; $dp->downloadfiledesc = ""; } */ $page->singleimage->deleteAll(); $page->editorimages->deleteAll(); } if(($page->template == "events") AND ($page->cancelled != "1")){ $this->message("Der Absagetext wurde entfernt"); $page->eventcancelledreason = ""; } } } Link to comment Share on other sites More sharing options...
LostKobrakai Posted September 22, 2015 Share Posted September 22, 2015 This does only save the page, that will be saved, but not the parent. That's why you should use Pages::saved for that case, as you shouldn't save other pages in the saveReady hook. 1 Link to comment Share on other sites More sharing options...
Juergen Posted September 22, 2015 Author Share Posted September 22, 2015 Ok that make sense. I was inspired by this topic https://processwire.com/talk/topic/2331-doing-additional-logic-after-saving-a-new-page/ So I will dive into it to solve it with Pages::saved. Link to comment Share on other sites More sharing options...
Juergen Posted September 24, 2015 Author Share Posted September 24, 2015 I stuck with Pages:saved. Nothing will be added and stored in the parent page. Here is the code that I call from the module: public function init() { $this->addHook('Pages::saved', $this, 'saved'); } public function saved($event) { $page = $event->arguments[0]; if($page->template == "productpricelistitem"){ //page which will be edited $parent = $page->parent_id;//grab the parent page id -> works //HERE STARTS THE PROBLEM $parent->offercheck = "2"; //example value to store in the parent page in the field "offercheck" $pages->save($parent); //save the parent page } } $parent->offercheck = "2": This line of code should add the value 2 in this case to the offercheck field of the parent page. $parent is the id of the parent page. $pages->save($parent): This line of code should save the parent page (identified by its id $parent). This 2 lines of code make troubles - Maybe its not the right syntax or way to store a value in another page. Link to comment Share on other sites More sharing options...
LostKobrakai Posted September 24, 2015 Share Posted September 24, 2015 Save the parent not the page, which hasn't changeds: $parent->save("offercheck"); Link to comment Share on other sites More sharing options...
Juergen Posted September 24, 2015 Author Share Posted September 24, 2015 Doesnt work Warning: Attempt to assign property of non-object in /home/.sites/24/site1275/web/site/modules/HookAfterPagesSave/HookAfterPagesSave.module on line 57 Fatal error: Call to a member function save() on integer in /home/.sites/24/site1275/web/site/modules/HookAfterPagesSave/HookAfterPagesSave.module on line 58 Line 57: $parent->offercheck = "2"; //example value to store in the parent page Line 58: $parent->save("offercheck"); //save the parent page Link to comment Share on other sites More sharing options...
LostKobrakai Posted September 24, 2015 Share Posted September 24, 2015 I think you missed $parent = $page->parent; 1 Link to comment Share on other sites More sharing options...
Martijn Geerts Posted September 24, 2015 Share Posted September 24, 2015 With an addHook you're defining a new method or property for a class, I don't think that is what you want. Link to comment Share on other sites More sharing options...
Juergen Posted September 24, 2015 Author Share Posted September 24, 2015 @ LostKobraKai: you are right - the error message is gone, but it will not store any value in the field of the parent page. @ Martijn: I dont know exactly what you mean, but my goal is to add a value to a field of a parent page if the child page has a specific value in a field. I can use a hook to populate the value of a field in the page, but I am not able to do the same in the parent page. Link to comment Share on other sites More sharing options...
Martijn Geerts Posted September 24, 2015 Share Posted September 24, 2015 $this->addHookAfter('Pages::saved', $this, 'saved'); After was missing in your example. That syntax is normally used for adding a new method to the class when that method don't exist. public function init() { $this->addHook('Page::trololo', $this, 'trololo'); } public function tralala($event) { $page = $event->object; // trololo $event->return = "https://www.youtube.com/watch?v=2Z4m4lnjxkY"; } // echo $page->trololo(); 2 Link to comment Share on other sites More sharing options...
LostKobrakai Posted September 24, 2015 Share Posted September 24, 2015 It shouldn't matter if one is using Before, Nothing or After for that Hook as the timing isn't relevant. 2 Link to comment Share on other sites More sharing options...
Martijn Geerts Posted September 24, 2015 Share Posted September 24, 2015 Oke, so $this->addHook('Pages::saved', $this, 'saved'); won't overwrite ?... It just confused me... sorry for the inconvenience. Link to comment Share on other sites More sharing options...
Juergen Posted September 24, 2015 Author Share Posted September 24, 2015 Thanks for your help LostKobraKai and Martijn, now the value will be added to the parent page. For all others who are interested in this, here is the complete code snippet: public function init() { $this->addHookAfter('Pages::saved', $this, 'saved'); } public function saved($event) { $page = $event->arguments[0]; if($page->template == "productpricelistitem"){ //run the hook under this condition - page which will be edited $parent = $page->parent;//get the parent page $parent->offercheck = "5"; //example value to store in the parent page in the field with the name offercheck $parent->save("offercheck"); //save the parent page } } If you use a pagetable field as in my case, dont forget to reload the parent page if you want to see the value in the field. Best regards 1 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