Jump to content

Update another page on page save


joer80
 Share

Recommended Posts

I have a module that is not working and I cant figure out why.  When an admin page is saved, I want to update another page.  This is my code:

public function init() {
	   $this->pages->addHookAfter('save', $this, 'UpdateAnotherPage'); //save, saved, saveReady, saveFieldReady
}

public function UpdateAnotherPage($event) {

		$page = $event->arguments(0); 
				
		//Update Another page
		$OtherPage = wire('pages')->get('id=1240');
		$OtherPage->setOutputFormatting(false);
		$OtherPage->ThemeCachedCSS = '123';
		$OtherPage->save(); //this breaks it
		
}

It will save the data in the new page, but the admin page doesnt load, it tries to load my homepage.  If I comment out the ->save(); line, it stays on the admin page and says page saved, but just doesnt update the other page.

I am probably missing something simple!

Thanks!

Link to comment
Share on other sites

You are missing the crucial step in your hook where you check what page was saved and then decide if you want your page update code to run. You don't want that update to occur on any page save like it does now, because then it will trigger again when the updated page is saved in the hook, and so on until the cows come home.

  • Like 1
Link to comment
Share on other sites

If I run this, it only shows the message one time if I save one page.

public function UpdateAnotherPage($event) {
		//Show saved message
		$this->message("Save Ran");
	}

 

I know the code is bare min and doesnt look useful right now.  I did that to make it easier to figure out.  I can edit any page to see the bug.  Hope that makes sense and I am not misunderstanding.

Link to comment
Share on other sites

If you want your hook to fire on the saving of all pages but the one you are updating in your hook you would do:

public function UpdateAnotherPage($event) {
    $page = $event->arguments('page');
    if($page->id !== 1240) {
        // update page 1240
    }
}

 

  • Like 3
Link to comment
Share on other sites

9 minutes ago, Robin S said:

You misunderstand what I'm saying: you are hooking page save, but saving a page inside your hook - that recurs indefinitely.

Do you think this is a good way to approach the problem?  Or do you know of a better way?

 

public function init() {
		$this->pages->addHookAfter('save', $this, 'UpdateAnotherPage'); //save, saved, saveReady, saveFieldReady
	}

public function UpdateAnotherPage($event) {

		$page = $event->arguments(0); 
				
		//Update Another page
		$OtherPage = wire('pages')->get('id=1240');
		$OtherPage->setOutputFormatting(false);
		$OtherPage->ThemeCachedCSS = '123';
		
		if($OtherPage->ThemeCachedCSS != '123'){
		  $OtherPage->save();
		}
		
	}

 

Link to comment
Share on other sites

4 minutes ago, Robin S said:

If you want your hook to fire on the saving of all pages but the one you are updating in your hook you would do:


public function UpdateAnotherPage($event) {
    $page = $event->arguments('page');
    if($page->id !== 1240) {
        // update page 1240
    }
}

 

Ah, I see you posted before me!

Thank you for all of your help!

Link to comment
Share on other sites

I thought about doing this:

if($page->id == $_GET['id']){
	$OtherPage->save('ThemeCachedCSS'); //only save the one field instead of whole page
}

The admin page save click would work because the get var would be set to the page you are on, but it wouldn't loop because the api call page id would be different.  

It would still loop when editing the theme page though.  You would always need it to be a different page than the one you are on.

Link to comment
Share on other sites

The page tree would be something like:

Page 1

Page 2

Theme

The gist I was playing with was each page would have a ace rich text box with css in it.  

On page save it would grab all css from all pages and save to theme.  

The theme page may want to add to it also though.  May have to keep thinking this out.

I will make it spit out a css file from that cached field that holds the total output.  Add a timestamp for cache busting and have my Page template link the most recent file.

Link to comment
Share on other sites

Ok, I think I have it figured out.   I ended up putting the cached field in the page also and making 2 functions instead of one.   What do you think about this?

<?php

class CacheThemeCSS extends WireData implements Module {

	public function init() {
		$this->pages->addHookBefore('save', $this, 'updateMyCachedCSS'); 
		$this->pages->addHookAfter('save', $this, 'updateThemeCachedCSS'); 
	}

	//Update the Cached CSS of the page I am on.
	public function updateMyCachedCSS($event) {
		
		//ini
		$CachedCSS = '';
		
		//Update CSS Cache for page I am on
		$page = $event->arguments(0); 
		
		//Prepare CSS for this page
		$CachedCSS .= '/* ' . $page->title . ' CSS Start */' . "\n";
		
		//Load Item Styles if given
		if($page->Styles){
		  $CachedCSS .= '#' . $page->template . '-' . $page->id . '{ ' . $page->Styles . '}' . "\n";
		}
		
		//Load CSS File Additions if given
		if($page->CSSAdditions){
		  $CachedCSS .= $page->CSSAdditions . "\n";
		}
		
		//$CachedCSS .= '/* ' . $page->title . ' CSS End */' . "\n";
		
		if($CachedCSS){
		  $page->CachedCSS = $CachedCSS;
		}
		
	}
	
	//Update the Themes AllCachedCSS
	public function updateThemeCachedCSS($event) {
		
		//ini
		$CachedCSS = '';
		
		//Get all CachedCSS and add them to the active themes AllCachedCSS field
		$results = $this->wire('pages')->find("CachedCSS!=''");
		foreach($results as $result){
			$CachedCSS .= $result->CachedCSS;
		}
		
		//Get Active Theme
		$Settings = $this->wire('pages')->get("template=settings");
		
		//Update Active Themes Cached CSS
		$ActiveTheme = wire('pages')->get($Settings->ActiveTheme->id);
		$ActiveTheme->setOutputFormatting(false);
		$ActiveTheme->AllCachedCSS = $CachedCSS; //Set the new value
		$ActiveTheme->save('AllCachedCSS');
		
	}

} //end class

 

Link to comment
Share on other sites

Here is the version that drops the Themes All Merge field and makes a file instead. (Each page still has a css cache field.)

I am using a timestamp on the css filename for cache busting.  That way you can set a 6 month time frame on css files and bust out every page save.

<?php

class CacheThemeCSS extends WireData implements Module {

	public function init() {
		$this->pages->addHookBefore('save', $this, 'updateMyCachedCSS'); 
		$this->pages->addHookAfter('save', $this, 'updateThemeCachedCSS'); 
	}

	//Update the Cached CSS of the page I am on.
	public function updateMyCachedCSS($event) {
		
		//ini
		$CachedCSS = '';
		
		//Update CSS Cache for page I am on
		$page = $event->arguments(0); 
		
		//Prepare CSS for this page
		$CachedCSS .= '/* ' . $page->title . ' CSS Start */' . "\n";
		
		//Load Item Styles if given
		if($page->Styles){
		  $CachedCSS .= '#' . $page->template . '-' . $page->id . '{ ' . $page->Styles . '}' . "\n";
		}
		
		//Load CSS File Additions if given
		if($page->CSSAdditions){
		  $CachedCSS .= $page->CSSAdditions . "\n";
		}
		
		$CachedCSS .= "\n";
		
		if($CachedCSS){
		  $page->CachedCSS = $CachedCSS;
		}
		
	}
	
	//Update the Themes CachedCSSFilename and make file
	public function updateThemeCachedCSS($event) {
		
		//ini
		$CachedCSS = '';
		
		//Get all CachedCSS styles
		$results = $this->wire('pages')->find("CachedCSS!=''");
		foreach($results as $result){
			$CachedCSS .= $result->CachedCSS;
		}
		
		//Get Active Theme ID
		$Settings = $this->wire('pages')->get("template=settings");
		
		$FileNameFormat = 'merged_' . date("Y-m-d_H:i:s");
		
		//Get Active Theme so I can update its CachedCSSFilename
		$ActiveTheme = wire('pages')->get($Settings->ActiveTheme->id);
		
		$PreviousCachedCSSFilename = $ActiveTheme->CachedCSSFilename;
		
		$ActiveTheme->setOutputFormatting(false);
		$ActiveTheme->CachedCSSFilename = $FileNameFormat . '.css'; //Set the new value
		$ActiveTheme->save('CachedCSSFilename');
		
		//make a file with $CachedCSS
		$myfile = fopen('styles/' . $ActiveTheme->CachedCSSFilename, "w");
		fwrite($myfile, $CachedCSS);
		fclose($myfile);
		
		//Delete previous merge file.
		unlink('styles/' . $PreviousCachedCSSFilename);
		//$event->message("Old file: $PreviousCachedCSSFilename  deleted");
	}

} //end class

 

Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

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