Pergunta

Eu me pergunto se existe uma prática recomendada para usar o cache de bloco para blocos que contêm um formulário com o form_key entrada (token CSRF).

Não estou falando de perfuração de cache de página inteira, mas do cache de bloco padrão do Magento CE.

Geralmente falado:Como você armazenaria em cache um bloco com uma pequena porção de conteúdo dinâmico ou um bloco filho que não está armazenado em cache?

Foi útil?

Solução

Foi assim que resolvi, adicionei os seguintes métodos ao bloco em questão:

const FORM_KEY_PLACEHOLDER = '{{FORM_KEY}}';

protected function _toHtml()
{
    return $this->_insertFormKeyPlaceholder(parent::_toHtml());
}

protected function _afterToHtml($html)
{
    return $this->_restoreFormKey(parent::_afterToHtml($html));
}

protected function _insertFormKeyPlaceholder($html)
{
    /** @var $session Mage_Core_Model_Session */
    $session = Mage::getSingleton('core/session');
    return str_replace($session->getFormKey(), self::FORM_KEY_PLACEHOLDER, $html);
}

protected function _restoreFormKey($html)
{
    /** @var $session Mage_Core_Model_Session */
    $session = Mage::getSingleton('core/session');
    return str_replace(self::FORM_KEY_PLACEHOLDER, $session->getFormKey(), $html);
}

Explicação:

Eu substituo a chave do formulário por um espaço reservado antes que o bloco renderizado seja armazenado em cache e substituo o espaço reservado pela chave do formulário atual novamente após o bloco ter sido carregado do cache.

eu uso _toHtml para inserir o espaço reservado porque o valor de retorno desse método é imediatamente gravado no cache.

eu uso _afterToHtml para restaurar a chave do formulário porque esse método é chamado imediatamente após o conteúdo ter sido carregado do cache (ou depois de ter sido salvo no cache, se ainda não tiver sido armazenado em cache).É garantido que esse método seja chamado, independentemente do cache do bloco.


Pensamentos adicionais

Parece que ainda não existe uma solução genérica, mas o método descrito acima funciona para qualquer conteúdo dinâmico e se você precisar dele em mais de um bloco ou com conteúdo diferente, deve ser fácil extrair a lógica do espaço reservado para um modelo separado.

Para substituir os espaços reservados, você também pode usar o core_block_abstract_to_html_after evento, mas infelizmente nenhum evento existe logo antes do bloco renderizado ser armazenado em cache, portanto, uma solução "somente observador" não é possível sem a introdução de novos eventos no núcleo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a magento.stackexchange
scroll top