C5 5.6.0 issue with block controller and AJAX request

Permalink
I'm having some issues with the following steps:

1. Ajax request is handled by block's controller (action_add_to_favourites)
2. Method should return the contents of the default 'view' method.

This generates this fatal error since the upgrade to C5 5.6.0: Call to a member function getProxyBlock() on a non-object in /core/libraries/block_view.php on line 39.

The code is on pastebin:http://pastebin.com/GKPjW4Ei

 
andrew replied on at Permalink Reply
andrew
Can you post your entire block to download from here? Or link to it? I'd like to run it through a test.
peterrr replied on at Permalink Reply 1 Attachment
Hi Andrew, that's a bit complicated, because the block uses a lot of attributes and is tailored for one specific site. Just copying won't work, I think.

I'll send you the controller.php so you'll get an idea of the code being used. (see line 143).

The $bt->render('view') produces the error. My gut feeling is that the system doesn't load a certain file because it's requested by AJAX.

I think the solution could be really ease, but I just don't know how to fix it... :)
andrew replied on at Permalink Reply
andrew
I think I know what is happening. I believe your view is calling action() on a non-block object. This used to just fail silently but now it fails loudly. Try this. Open concrete/core/libraries/block_view.php and find these lines

if (is_object($this->block->getProxyBlock())) {
   $b = $this->block->getProxyBlock();
} else {
   $b = $this->block;
}
if (is_object($b)) {
   return $b->getBlockPassThruAction() . '&method=' . $task . $extraParams;
}


and change them to this:

if (is_object($this->block)) {
   if (is_object($this->block->getProxyBlock())) {
      $b = $this->block->getProxyBlock();
   } else {
      $b = $this->block;
   }
   if (is_object($b)) {
      return $b->getBlockPassThruAction() . '&method=' . $task . $extraParams;
   }
}


That should fix the error.
peterrr replied on at Permalink Reply
Thanks Andrew for your reply. Your suggestion only supresses the error, right?

1. I've tried to 'override' the file to /core/libraries/block_view.php, but it doesn't seem to work. Does the core folder work differently in c560?

2. I still don't know how to render a block's template from an action_method and couldn't find a working solution on the internet. Any ideas?

3. I now use:
public function action_add_to_favourites (){
   //code...
   $bt = BlockType::getByHandle('content_offerte');
   $bt->render('ajax_manage_favourites');
   exit;
}


This seems to work, but somehow this method executes the view-method. Should C5 behave like this? Now my code gets executed twice.

Thanks in advance for your help!
andrew replied on at Permalink Reply
andrew
I think you're doing it right. The problem is that the action() function requires a block to run against. When placed on a page, your view function works right, but since the block type object rendering the view in the ajax method isn't actually being run by a live block object, it doesn't return an action method. It's not really suppressing the error – it's just not returning an action if there's no block object available (as it did in 5.5.2.1 and earlier.)

Finally, I imagine you need to disable your "override cache" in 5.6. Go to Dashboard > Cache & Speed Settings and turn off the override cache. In 5.6 if this cache is enabled we no longer check for overrides on every page load (for performance improvements on hosts with slower disk IO)
peterrr replied on at Permalink Reply
Ok, this makes sense, thanks for your reply!

1. This thread helped me understand the new 'core' folder and how to override classes:http://www.concrete5.org/community/forums/customizing_c5/extending-...

3. Still not quite sure why 'view' is being executed if a call to 'action...' is requested, any ideas?