2017-02-02 5 views
1

У меня есть блок, который опирается на довольно шелушащийся сторонний сервис для получения данных для рендеринга, поэтому, когда он сталкивается с проблемой, d хотел бы отобразить сообщение об ошибке, а не бросать исключение и не отображать страницу.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'); 
    } 
} 

В пределах блока улова я попытался как $this->btCacheBlockOutput = true; и \Cache::disableAll(); но ни работы. Есть ли способ сказать C5 не кэшировать что-либо в текущем запросе?

ответ

0

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

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

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

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

+0

Спасибо, но это Безразлично Ответ на вопрос. Блок используется на страницах с высоким трафиком, где действительно требуется полное кэширование страниц. Я уже сохраняю данные в «дорогом» (диске) кеше, что идеально подходит для этого, но не помогает проблему кэширования страниц. –

+0

Я отредактировал свой ответ, см. «Третий» вариант. Я тестировал, если страница все еще загружается, поэтому код действителен. – Jozzeh

+0

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