Jump to content

Can't Save Page Using Hook


Pete
 Share

Recommended Posts

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

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

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

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

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

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

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

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

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

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