2017-02-02 7 views
1

데이터를 렌더링하기 위해 제 3 자 서비스를 사용하는 블록이 있습니다. 문제가 발생하면, 예외를 던지거나 페이지를 렌더링하지 말고 오류 메시지를 표시하고 싶습니다.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가 아무 것도 캐시하지 않도록 지시하는 방법이 있습니까?

답변

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(){ 
    ..... 

이렇게하면 타사 연결이 성공하더라도 블록 캐싱이 비활성화됩니다.

다른 해결책은 데이터베이스에 제 3 자로부터받은 데이터를 저장하고 (예 : json 문자열), 제 3 자 연결이 실패한 경우 데이터베이스의 데이터를로드하는 것입니다. 제 3 자 연결이 성공하면 ... , 데이터베이스의 레코드를 갱신 할 수 있습니다.

타사 서비스의 응답에 따라 조건을 설정할 수 있습니다. 예 :

//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

감사합니다,하지만 그 아무튼 API에 대한 호출이 실패 할 때 '경우'는에서

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

: 당신의 blockcontroller의 상단에

그 질문에 대답하지 마라. 이 블록은 전체 페이지 캐싱이 실제로 필요한 높은 트래픽 페이지에서 사용됩니다. 이미 "비싼"(디스크) 캐시에 데이터를 저장하고 있는데,이 방법은 완벽하지만 페이지 캐싱 문제를 해결하는 데는 도움이되지 않습니다. –

+0

제 응답을 수정했습니다. '제 3의 옵션'을 참조하십시오. 페이지가 아직로드되어 있는지 테스트 했으므로 코드가 유효합니다. – Jozzeh

+0

캐시에서 페이지를 제거하면 렌더링 된 출력이 캐시되지 않으므로 좋은 시작이지만 빠른 테스트에서 오래된 블록 출력을 계속 볼 수 있습니다. 아마도 이것은 블록 출력 캐시에서 오는 것이고, 오류 처리에서 관련 블록 객체의 refreshBlockOutputCache 메소드를 호출하는 것이 도움이되지 않는 것 같습니다. 아마도이 시점에서 블록의 cacheSettings 객체를 수동으로 채우는 것이 도움이 될 것입니다. 시간이 지나면 나중에 재생해야합니다. –