1

我有一个依赖于相当不稳定的第三方服务来获取数据以呈现的块,所以当它遇到问题时,我想显示一条错误消息,而不是抛出异常而不呈现页面。

很容易做到,直到你来块/页面缓存。数据的生命周期很长,因此,一旦找到,就可以缓存所有内容。但是,如果不是,则会缓存页面并显示错误消息。因此,我需要告诉 CMS 不要将块或页面输出保存到缓存中。

示例代码(在块控制器内):

public function view() {
    try {
        $this->set ('data', $this->getData());

    } catch (\Exception $e) {
        \Log::addError ('Blockname Error: '.$e->getMessage(), [$e]);
        $this->render ('error');
    }
}

在 catch 块中,我都尝试过$this->btCacheBlockOutput = true;\Cache::disableAll();但都不起作用。有没有办法告诉 C5 不要缓存当前请求中的任何内容?

4

1 回答 1

0

The BlockController in the concrete folder has these protected variables set as standard :

protected $btCacheBlockRecord = true;
protected $btCacheBlockOutput = false;
protected $btCacheBlockOutputOnPost = false;
protected $btCacheBlockOutputForRegisteredUsers = false;

So if you set all these on your block controller.php on false, it should not cache your block.

class Controller extends BlockController
{
  protected $btCacheBlockRecord = false;
  protected $btCacheBlockOutput = false;
  protected $btCacheBlockOutputOnPost = false;
  protected $btCacheBlockOutputForRegisteredUsers = false;
  public function view(){
    .....

This will disable the caching of the block (even if the third party connection succeeds).

A different solution is to save the data received from the third party in the database (for example as a json string) and load the data from the database if the third party connection fails... if the third party connection succeeds, you can update the record in the database.

Depending of the answer of the third party service you can set the conditions. Example:

//service returns on OK:
//array('status' => 'ok')
//service returns on NOT OK:
//array('status' => 'nok')

public function view() {
    $data = $this->getData();
    if($data['status'] == 'ok'){
       //save data to database in a config value using concrete Config class
       $configDatabase = \Core::make('config/database');
       $configDatabase->save('thirdpartyanswer', $data);
       $this->set('data', $data);
    }else{
       //getData function returned error or nok status
       //get data from concrete Config class
       $configDatabase = \Core::make('config/database');
       if($configDatabase->get('thirdpartyanswer')) != ''){
          //set data as "old" data from config
          $this->set('data', $configDatabase->get('thirdpartyanswer'));
       }else{
          //no data in config -> set error and nothing else
          $this->set('error', 'An error occured contacting the third party');
       }
    }
}

(The code above has not been tested)
More information on storing config values :
https://documentation.concrete5.org/developers/packages/storing-configuration-values

* Edit *

A third option is to purge the cache for that specific page if the call fails.

At the top of your blockcontroller :

use \Concrete\Core\Cache\Page\PageCache;
use Page;

In the 'if' when the call to the API fails :

$currentPage = Page::getCurrentPage();
$cache = PageCache::getLibrary();
$cache->purge($currentPage);

Found at : https://www.concrete5.org/community/forums/5-7-discussion/programmatically-expiring-pages-from-cache

于 2017-02-04T11:22:25.993 回答