Pete Posted March 29, 2012 Share Posted March 29, 2012 Hi folks I've got a hook that runs on page render: $this->addHookBefore('Page::render', $this, 'setCommonVars'); My function contains this code: public function setCommonVars(HookEvent $event) { $page->setOutputFormatting(false); $page = $event->object; $page->article_comments = $comments['total']; $page->save(); $page->setOutputFormatting(true); } $comments['total'] is from somewhere else - it's an integer and the field will accept an integer - I've removed a chunk of surrounding code for readability. Unfortunately when the hook runs, I get the following error, which makes little sense since I've already turned off outputformatting <b>Fatal error</b>: Exception: Can't save page 1414: /news/test/: Call $page->setOutputFormatting(false) before getting/setting values that will be modified and saved. [article_comments] Any ideas? Link to comment Share on other sites More sharing options...
apeisa Posted March 30, 2012 Share Posted March 30, 2012 Put your setoutputformattong false down one line. You don't have page object at that moment. (sorry for typos, I am on mobile). Link to comment Share on other sites More sharing options...
Pete Posted March 30, 2012 Author Share Posted March 30, 2012 Thanks for that - unfortunately that was my fault for copying and pasting incorrectly, and my code does have it in the correct order. Unfortunately it still doesn't work and shows me that error with setOutputFormatting in the correct place. I've upgraded to the latest version of PW but that doesn't help either unfortunately. Link to comment Share on other sites More sharing options...
Pete Posted March 30, 2012 Author Share Posted March 30, 2012 I decided to move it into a different module entirely without success either, then tried saving a page in the template code instead to rule out an issue with modules - no success on those either. Is there any reason why it would give that error with outputFormatting turned off? Link to comment Share on other sites More sharing options...
ryan Posted March 30, 2012 Share Posted March 30, 2012 I had a Page::render hook handy to test with, but can't duplicate this one. The code you originally posted wouldn't work because it was calling setOutputFormatting on a non-object (before you had $page), but you indicated that the order was corrected, so sounds like that's not it. Here is my working version if it helps: public function example2($event) { $page = $event->object; // make sure you exit if it's not the $page you want if($page->template != 'basic-page') return; $page->of(false); $page->summary .= " test"; $page->save(); $page->of(true); } Please paste in the full code to your function again if it still won't work and I can copy/paste into mine. Link to comment Share on other sites More sharing options...
ryan Posted March 30, 2012 Share Posted March 30, 2012 Forgot to add, of() is the same thing as setOutputFormatting(). I just added that as an alias recently because it's easier to type. Link to comment Share on other sites More sharing options...
Pete Posted March 30, 2012 Author Share Posted March 30, 2012 It's set to run after page render, but here's the latest version (probably not much use out of context though): public function checkCommentCounts() { if ($this->initializeIPB()) { $topics = array(); $commentPages = wire('pages')->find('template=news,forum_topic>0');//|article,forum_topic>0'); if ($commentPages->count()) { $topics = array(); foreach ($commentPages as $commentPage) { //echo $commentPage->title; $topics[$commentPage->forum_topic] = ''; } } $this->DB = $this->registry->DB(); $this->DB->build( array( 'select' => "tid, posts", 'from' => "topics", 'where' => "tid IN (" . implode(',', array_keys($topics)) . ")", 'order' => 'tid ASC', ) ); $this->DB->execute(); echo $this->DB->getTotalRows(); //exit; if ( $this->DB->getTotalRows() ) { // Iterate through each result while ($row = $this->DB->fetch()) { // If there is a result that doesn't have a corresponding page on the site, then add it if ($commentPages->get('id=1582')) {//,forum_topic=' . $row['tid'])->article_comments != ($row['posts']-1)) { //if ($commentPages = 1582) { $currPage = $commentPages->get('id=1582'); echo $currPage->title; //exit; //$currPage = wire('pages')->get(1582);//$commentPages->get('forum_topic=' . $row['tid']); $currPage->of(false); //echo $commentPages->find('forum_topic=' . $row['tid'])->count(); //exit; //echo is_string($currPage->article_comments) ? 1 : 0; //exit; $currPage->article_comments = 2; $currPage->save(); $currPage->of(true); } } } } } $topics is an array of post counts for the topic IDs searched for using the $this->DB. The DB functionality is from the forum software, so that can be safely ignored. The bit that's really confusing me is that at some point in the last 4 weeks this has worked (not this exact code, but one like it that I've also double checked and doesn't work ). Oh yeah, and it's very scrappy as I'm in the middle of trying half a dozen different things trying to fix it - sorry if that's making it less legible! Link to comment Share on other sites More sharing options...
ryan Posted March 30, 2012 Share Posted March 30, 2012 Thanks for posting the full thing. But I'm confused because I can't relate it back to the original post. There's no $event argument in the hook. To me this looks like something that would be suitable as a LazyCron hook? At least, if it's not using anything about the current $page from Page::render, then you may not want to saddle it with this on every request. What's the exact error message you are getting? And is it the $currPage->save(); line that is throwing it? You might want to enable debug mode to see the debug trace to be sure. Link to comment Share on other sites More sharing options...
Pete Posted March 30, 2012 Author Share Posted March 30, 2012 Hehe, yep - it was originally relating to the current page, hence the $event argument, then I thought I'd shift it to its own function and maybe do LazyCron to update all pages every 20 minutes or so rather than running it on every page load. Still, this version is still set to run after Page::render now so should still work, right? It's throwing me an identical error, though obviously different line numbers. The error is: <b>Fatal error</b>: Exception: Can't save page 1357: /articles/interviews/test/: Call $page->setOutputFormatting(false) before getting/setting values that will be modified and saved. [article_comments] (in C:\xampp\htdocs\test\wire\core\Pages.php line 457) #0 [internal function]: Pages->___save(Object(Page)) #1 C:\xampp\htdocs\test\wire\core\Wire.php(269): call_user_func_array(Array, Array) #2 C:\xampp\htdocs\test\wire\core\Wire.php(229): Wire->runHooks('save', Array) #3 C:\xampp\htdocs\test\wire\core\Page.php(800): Wire->__call('save', Array) #4 C:\xampp\htdocs\test\wire\core\Page.php(800): Pages->save(Object(Page)) #5 C:\xampp\htdocs\test\site\modules\ForumsIPB\ForumsIPB.module(319): Page->save() #6 C:\xampp\htdocs\test\wire\core\Wire.php(291): ForumsIPB->checkCommentCounts(Object(HookEvent)) #7 C:\xampp\htdocs\test\wire\core\Wire.php(229): Wire->runHooks('render', Array) #8 C:\xampp\htdocs\test\wire\modules\Process\ProcessPageView.module(82): Wire->__call('render', Array) #9 C:\xampp\htdocs\test in <b>C:\xampp\htdocs\test\index.php</b> on line <b>220</b><br /> <p class='error WireFatalError'><em>This error message was shown because site is in debug mode ($config->debug = true; in /site/config.php). Error has been logged. Administrator has been notified. </em></p> Link to comment Share on other sites More sharing options...
Pete Posted March 30, 2012 Author Share Posted March 30, 2012 Okay, so to add to the oddness, the hook runs without issue when I refresh an admin page and correctly updates the field. When refreshing a page on the front-end it fails with that error. Could something in one of my templates be causing the issue? Link to comment Share on other sites More sharing options...
Pete Posted April 3, 2012 Author Share Posted April 3, 2012 It turned out there was an error in another module I'd created. Well, not an error, but when I uncommented this line in the other module it worked: $mypage = wire('pages')->get($myid); Not sure why doing that in another module would cause outputformatting not to work though Still, I didn't need that line as it was only there for testing so it's no big deal. 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