2017-02-02 9 views
1

データがレンダリングされるためにかなりフレークなサードパーティのサービスに依存するブロックがあります。問題が発生した場合、例外をスローしてページをレンダリングするのではなく、エラーメッセージを表示するのが好きです。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ブロック内では、Iは$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

*編集*

第三のオプションがパージであります呼び出しが失敗した場合はその特定のページのキャッシュ。

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

で発見:https://www.concrete5.org/community/forums/5-7-discussion/programmatically-expiring-pages-from-cache

+0

おかげで、それはdoesnのAPIへの呼び出しが失敗したときに 'あれば' で

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

:あなたのblockcontrollerの上部に

質問に答えない。このブロックは、フルページキャッシングが本当に必要な高トラフィックページで使用されます。私はすでに "高価な"(ディスク)キャッシュにデータを保存していますが、これは完璧ですが、ページキャッシュの問題には役立ちません。 –

+0

私の回答を編集しました.3番目のオプションを参照してください。ページがまだロードされているかどうかをテストしたので、コードは有効です。 – Jozzeh

+0

そのようなキャッシュからページをパージすると、現在レンダリングされている出力がキャッシュされなくなりますが、それは良いスタートですが、クイックテストから古いブロック出力が見えています。おそらく、これはブロック出力キャッシュから来て、エラー処理で関連するブロックオブジェクトのrefreshBlockOutputCacheメソッドを呼び出すことは役に立たないようです。ブロックのcacheSettingsオブジェクトをこの時点で手動で設定すると、時間がたつと後で再生する必要があります。 –

関連する問題