Concrete5 (5.7) - Не кэшировать страницу или текущий блок при ошибке блока

У меня есть блок, который использует довольно нестабильный сторонний сервис для получения данных для рендеринга, поэтому, когда он сталкивается с проблемой, я бы хотел отобразить сообщение об ошибке, а не выдавать исключение и не отображать страницу.

Это достаточно просто сделать, пока вы не зайдете в блок / кеширование страниц Данные имеют длительный срок службы, поэтому, когда они найдены, все в порядке. Когда это не так, страница кэшируется с сообщением об ошибке на месте. Поэтому я должен сказать 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 не кэшировать что-либо по текущему запросу?

1 ответ

BlockController в конкретной папке имеет следующие стандартные защищенные переменные:

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

Так что если вы установите все это в свой block controller.php на false, он не должен кэшировать ваш блок.

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

Это отключит кеширование блока (даже если подключение стороннего производителя будет успешным).

Другое решение состоит в том, чтобы сохранить данные, полученные от третьей стороны, в базе данных (например, в виде строки json) и загрузить данные из базы данных в случае сбоя подключения третьей стороны... если подключение третьей стороны успешно, вы можете обновить запись в базе данных.

В зависимости от ответа сторонней службы вы можете установить условия. Пример:

//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');
       }
    }
}

(Код выше не был проверен)
Дополнительная информация о хранении значений конфигурации:
https://documentation.concrete5.org/developers/packages/storing-configuration-values

* Редактировать *

Третий вариант - очистить кеш для этой конкретной страницы в случае сбоя вызова.

В верхней части вашего blockcontroller:

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

В "если" при сбое вызова API:

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

Найдено по адресу: https://www.concrete5.org/community/forums/5-7-discussion/programmatically-expiring-pages-from-cache

Другие вопросы по тегам