Jump to content

How to add a value of a child page via hook after save to a field of the parent page


Recommended Posts

Posted

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 on

The 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

Posted

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.

Posted

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

Posted

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 :huh:

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 = "";
        }
    }

}
Posted

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.

  • Like 1
Posted

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.

Posted

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

Posted

@ 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.

Posted
$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();

  • Like 2
Posted

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

  • Like 1

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...