lunes, 27 de febrero de 2012

Prestashop y cache de página ZendFramework


En esta ocasión vamos a aplicar el cache de página que trae ZendFramework en Prestashop de una manera sencilla.

* Paso 0 : Preparativos

1. Debemos tener instaladas las librerías de ZendFramework dentro de Prestashop en
la carpeta: library/Zend

2. Habilitamos el cache de Prestashop:
config/settings.inc.php:
define('_PS_CACHING_SYSTEM_', 'CacheFS');
define('_PS_CACHE_ENABLED_', 1)
config/defines.inc.php:
define('_PS_CACHEFS_DIRECTORY_', dirname(__FILE__).'/../cache/');

Al estar utilizando Cache de Archivo tendremos que darle permisos a la carpeta indicada por la constante: _PS_CACHEFS_DIRECTORY_
chmod a+rw -Rf

* Paso 1 : Cache de Página

En este paso vamos a crear la lógica para el cache de archivos. Para esto creamos el archivo : config/cache.page.inc.php

<?php
if (function_exists('date_default_timezone_set'))
    @date_default_timezone_set('America/Lima') ;
define('APPLICATION_PATH', realpath(dirname(__FILE__)));
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/library'),
    get_include_path(),
)));
require_once('Zend/Cache.php');
if (_PS_CACHE_ENABLED_) {
    $frontendOpts = array(
    'lifetime' => 60*60*4,
    'debug_header' => false,
    'regexps' => array(
    '^/$' => array('cache' => true),
    '^/es/$' => array('cache' => true),
    '^/Myadmin/$' => array('cache' => false)               
    )
    );
    switch(_PS_CACHING_SYSTEM_){
    case 'MCached':
    $servers = MCachedCore::getMemcachedServers();
    if (!$servers) return false;
    foreach ($servers AS $server)
        $servidores[] = array('host' => $server['ip'], 'port' => $server['port']);   
    $backendOpts = array(
        'servers' => $servidores,
        'compression' => false
        );
    $cache = Zend_Cache::factory('Page', 'Memcached', $frontendOpts, $backendOpts);
    break;  
    default :
    $backendOpts = array(
        'cache_dir' => _PS_CACHEFS_DIRECTORY_,
         'hashed_directory_level' => 2
        );
    $cache = Zend_Cache::factory('Page', 'File', $frontendOpts, $backendOpts);
    break;
    }
    if (!isset($_GET['iso_lang'])){
    global $cookie;
    if (! isset($cookie)){
        $cookieLifetime = (time() + (((int) Configuration::get('PS_COOKIE_LIFETIME_FO') > 0 ? (int) Configuration::get('PS_COOKIE_LIFETIME_FO') : 1) * 3600));
        $cookie = new Cookie('ps', '', $cookieLifetime);
    }
    $lang = $cookie->id_lang;
    } else $lang = $_GET['iso_lang'];
    $cacheName = substr(str_replace('.','_',$_SERVER['SCRIPT_NAME']), 1) . '_' . $lang . '_'. md5($_SERVER['QUERY_STRING']);
    $cache->start($cacheName);
}


Como observamos el cache tiene un tiempo de (60*60*4) 4 horas y el nombre del mismo estará formado de la página visitada, el lenguaje y los valores enviados por $_GET.

* Paso 2: Aplicando el cache a la página principal, categorias y productos.

Este paso en realidad es muy sencillo, de incluir el archivo de cache.page.inc.php luego del archivo config.inc.php :
require(dirname(__FILE__) . '/config/config.inc.php');
require(dirname(__FILE__) . '/config/cache.page.inc.php');
Esto en los archivos:
index.php
category.php
product.php

* ¿No loguea al usuario?
Como veran en las secciones que indicamos ya se aplica cache de página; y probando la aplicación estas no cambiaran a pesar de que nos logueemos.

Una solución rápida para el caso de logueo es validar el uso de cache solo cuando no este logueado:

require(dirname(__FILE__) . '/config/config.inc.php');
global $cookie;
if (! isset($cookie)){
  $cookieLifetime = (time() + (((int) Configuration::get('PS_COOKIE_LIFETIME_FO') > 0 ? (int) Configuration::get('PS_COOKIE_LIFETIME_FO') : 1) * 3600));
  $cookie = new Cookie('ps', '', $cookieLifetime);
}
if(! $cookie->isLogged()){
   require(dirname(__FILE__) . '/config/cache.page.inc.php');
}

** Otra solución


Una solución compleja y recomendable sería (sin diferenciar el cache) mediante llamadas AJAX refrescar solo las secciones que estan relacionadas exclusivamente al Cliente (Login de usuario y Carrito de compras)
Enhanced by Zemanta

2 comentarios:

pelos dijo...

Muy buenas Juán. Se supone que esta solución es para la versión de PS 1.4. Hay alguna solución parecida para la 1.3??

Juan Carbajal Paxi dijo...

La implementación en 1.4 fue sencilla. No habría problema en que puedas modificar la versión 1.3. Suerte