web-dev-qa-db-fra.com

Impossible d'activer le cache dans 3.4.4

J'ai une installation complexe de Joomla 3.4.4 avec jSeblod et de nombreuses autres extensions. Nous prévoyons d'utiliser Varnish4 devant le serveur Web et, par conséquent, nous devons activer les en-têtes Cache-Control appropriés.

Mais je n'arrive pas à activer la mise en cache. Voici ce que j'ai essayé:

1)

configuration.php

public $caching = '1';
public $cache_handler = 'file';
public $cachetime = '30';

2) Administrateur-> Extensions-> Plugins-> La mise en cache des pages est activée

Dans le plugin, la mise en cache du navigateur est activée

3) Avec un débogueur, le débogueur s’arrête dans n’importe quel plugin que j’essaie, mais pas dans le plugin cache

4) Sous Administrateur-> Extensions-> Gérer, je peux trouver le plug-in Cache installé

5) Sous Administrator-> Extensions-> Discover, il est maintenant trouvé.

6) Sur mon propre site Web en direct, j'obtiens les mêmes résultats, mais l'en-tête du cache est "Cache-Control: no-cache" au lieu de "Cache-Control: no-store, no-cache, must-revalidate, post-check = 0, pré-vérification = 0 "

7) J'ai construit un plugin qui active le cache juste avant l'envoi de la réponse:

class plgSystemGtnocachies extends JPlugin
{
    function plgSystemGtnocachies( &$subject, $config )
    {
        parent::__construct( $subject, $config );
    }

    function __destruct()
    {
        if (!headers_sent())
        {
            $this->setCacheHeaders();
        }
    }

    public function onAfterRender()
    {
        JApplicationWeb::allowCache( true );
        $this->setCacheHeaders();
    }

    private function setCacheHeaders()
    {
        JApplicationWeb::setHeader( 'Cache-Control', 'public, max-age=10800', true );
        JApplicationWeb::setHeader( 'Vary', 'Cookie', true );
        JApplicationWeb::setHeader( 'Pragma', '', true );
    }
}

Ce que je trouve cependant, c’est que lorsque l’appel de fonction revient à

class JEventDispatcher extends JObject
{
    public function trigger($event, $args = array())
    {
        $result = array();

        /*
         * If no arguments were passed, we still need to pass an empty array to
         * the call_user_func_array function.
         */
        $args = (array) $args;

        $event = strtolower($event);

        // Check if any plugins are attached to the event.
        if (!isset($this->_methods[$event]) || empty($this->_methods[$event]))
        {
            // No Plugins Associated To Event!
            return $result;
        }

        // Loop through all plugins having a method matching our event
        foreach ($this->_methods[$event] as $key)
        {
            // Check if the plugin is present.
            if (!isset($this->_observers[$key]))
            {
                continue;
            }

            // Fire the event for an object based observer.
            if (is_object($this->_observers[$key]))
            {
                $args['event'] = $event;
                $value = $this->_observers[$key]->update($args);
------->
            }
            // Fire the event for a function based observer.
            elseif (is_array($this->_observers[$key]))
            {
                $value = call_user_func_array($this->_observers[$key]['handler'], $args);
            }

            if (isset($value))
            {
                $result[] = $value;
            }
        }

        return $result;
    }

JApplicationWeb::getInstance->response->cacheable est à nouveau faux.

Une idée de ce qui se passe ici?

7
jdog

J'ai résolu ce problème en utilisant un wrapper de tampon de sortie pour toute l'installation de Joomla.

Quelques antécédents:

Sur ce site Web, nous utilisons jSeblod, RSForm, JCHOptimize, CDN et Joomla non numérotés, ainsi que AceSEF. Il y a aussi beaucoup de plugins. À partir d’une recherche de code, j’ai déterminé que la plupart des extensions semblaient émettre leurs propres en-têtes de cache, ce qui rendait tout contrôle impossible du point de vue de Joomla.

J'espérais pouvoir effacer tous les en-têtes dans OnAfterRender, mais comme vous pouvez le voir dans la question, cela ne fonctionne pas du tout.

Nous avions besoin de mettre toutes les pages en cache avec Varnish et, idéalement, de désactiver le cache dans Joomla, afin de faciliter les tests directs. Nous avions également besoin de désactiver la mise en cache pour les pages contenant RSForm que nous intégrons toujours dans le contenu contenu de la scène.

La solution consiste à définir un fichier de pré-ajout dans le VHost, un plug-in système permettant d'identifier les pages à ne pas mettre en cache et le contenu du fichier de pré-ajout.

Notre temps de cache est codé en dur à 1800 secondes:

VHost:

 php_value auto_prepend_file /path/to/my/webfolder/prepend.php

Plugin système personnalisé:

class plgSystemCacheOn extends JPlugin
{

    function plgSystemCacheOn(&$subject, $config)
    {
            parent::__construct($subject, $config);
    }

    private function getCleanRequestUri()
    {
        list($requestUri, $query) = explode('?', $_SERVER["REQUEST_URI"]);
        return $requestUri;
    }


    private function isHomepage()
    {
        return $this->getCleanRequestUri() === '/' && 
        (!isset($_GET['option']) || !$_GET['option']);
    }


    function onAfterRender()
    {
        $app = JFactory::getApplication();
        $jinput = $app->input;

        if ($app->getName() != 'site') {
            return true;
        }

        $buffer = JResponse::getBody();

        if ($this->isHomepage()){
            header('GTCacheOn: KeepOn');
        }
        if (strstr($buffer, '{rsform')){
            header('GTCacheOn: KeepOn');
        }

        if (JFactory::getUser()->id > 0){
            header('GTUser: Keep');
        }

        return true;
    }
}

prepend.php

function dontCache($headers){

    if ($headers && is_array($headers)){
        foreach($headers as $header){
            list ($headerName, $headerData) = explode( ':', $header);
            if ($headerName === 'GTCacheOn' && trim($headerData) == 'KeepOn') return true;
            if ($headerName === 'GTUser' && trim($headerData) == 'Keep') return true;
        }
    }
    return false;
}    

function only_greentree_headers_allowed( $buffer, $phase )
{
    header_remove( 'Pragma' );
    require (dirname( __FILE__ ). "/libraries/greentree/Helper.php");
    if (in_array($_SERVER['SCRIPT_NAME'], array(
        '/index.php',
        '/media/plg_jchoptimize/assets2/jscss.php'
    ))) {
        header_remove('Expires');
        header_remove('Set-Cookie');
        if (!GreentreeHelper::dontCache(headers_list())) {
            header('Cache-Control: public, max-age=1800', true);
            header('Vary: Cookie', true);
        } else {
            header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0', true);
        }
    }else{
        header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0', true);
    }

    return $buffer;
}

ob_start( 'only_my_headers_allowed' );
2
jdog

Il y a beaucoup d'informations sur ce site http://massivescale.net/varnish-joomla.html

Ils disent qu'un plugin ne peut pas résoudre ce problème en raison de la manière dont Joomla! le noyau est écrit. Ils offrent toutefois une sorte de bidouille sur leur site pour 70 £. Je serais fatigué de l'utiliser sur un site avec beaucoup d'ajouts.

SEBLOD est basé sur le composant de contenu principal, donc ça peut aller. Je vérifierais les autres plugins individuellement, et si vous avez des problèmes, désactivez-les un à la fois.

0
Eoin