Skip to content
This repository was archived by the owner on May 16, 2018. It is now read-only.
This repository was archived by the owner on May 16, 2018. It is now read-only.

Zend_Cache_Frontend_Page . Whitelist for Superglobals to be used when making the cacheid. #14

Closed
@zfbot

Description

@zfbot

Jira Information

Original Issue:ZF-12411
Issue Type:Improvement
Reporter:Frank Ruske
Created:09/08/12
Assignee:Alexander Veremyev
Components:Zend_Cache

Description

Hi,

I had the following problem when working with Zend_Cache_Frontend_Page:

We have a multilingual webseite. The user gets the webseite displayed based on a language cookie set on his client.
For this reason we have to use the COOKIE values to generate the hash id else only one language version would be cached.

When using the Fullpage Cache it was not enough for us to generate the Key based on the _COOKIE superglobal using this options:

frontend.options.regexps.1.make_id_with_cookie_variables = true
frontend.options.default_options.cache_with_cookie_variables = true

The problem here is that there are also other COOKIES (or superglobals) which may change with every request but are totally irelevant for our full page cache.
For example Google Analytics changes it COOKIE values every request. Thus there was 0% Cache hits.

I have implemented a whitelist to use together with Zend_Cache_Frontend_Page.

Find below my adjustments. Maybe you can consider using it, if not maybe anyone else will run into the same problem.

In Zend_Cache_Frontend_Page:

    protected $_specificOptions = array(
        'http_conditional' => false,
        'debug_header' => false,
        'content_type_memorization' => false,
        'memorize_headers' => array(),
        'default_options' => array(
            'cache_with_get_variables' => false,
            'cache_with_post_variables' => false,
            'cache_with_session_variables' => false,
            'cache_with_files_variables' => false,
            'cache_with_cookie_variables' => false,
            'make_id_with_get_variables' => true,
            'make_id_with_get_whitelist' => false, //new option
            'make_id_with_post_variables' => true,
            'make_id_with_post_whitelist' => false, //new option
            'make_id_with_session_variables' => true,
            'make_id_with_session_whitelist' => false, //new option
            'make_id_with_files_variables' => true,
            'make_id_with_files_whitelist' => false,  //new option
            'make_id_with_cookie_variables' => true,
            'make_id_with_cookie_whitelist' => false, //new option
            'cache' => true,
            'specific_lifetime' => false,
            'tags' => array(),
            'priority' => null
        ),
        'regexps' => array()
    );

Zend_Cache_Frontend_Page::_makePartialId() got a new parameter $whitelist

    /**
     * Make a partial id depending on options
     *
     * @param  string $arrayName Superglobal array name
     * @param  bool   $bool1     If true, cache is still on even if there are some variables in the superglobal array
     * @param  bool   $bool2     If true, we have to use the content of the superglobal array to make a partial id
     * @param  mixed  $whitelist  If an array with more then one index then only use the defined indexes to create cache
     * @return string|false Partial id (string) or false if the cache should have not to be used
     */
    protected function _makePartialId($arrayName, $bool1, $bool2, $whitelist = false)
    {
        switch ($arrayName) {
            case 'Get':
                $var = $_GET;
                break;
            case 'Post':
                $var = $_POST;
                break;
            case 'Session':
                if (isset($_SESSION)) {
                    $var = $_SESSION;
                } else {
                    $var = null;
                }
                break;
            case 'Cookie':
                if (isset($_COOKIE)) {
                    $var = $_COOKIE;
                } else {
                    $var = null;
                }
                break;
            case 'Files':
                $var = $_FILES;
                break;
            default:
                return false;
        }
        if ($bool1) {
            if ($bool2) {
                // We have a whitelist so only return the defined indexes.
                if (true === is_array($whitelist) && count($whitelist) > 0) {
                    $tmpArray = array();

                    foreach ($whitelist as $index) {
                        if (true === isset($var[$index])) {
                            $tmpArray[$index] = $var[$index];
                        }
                    }

                    if (count($tmpArray) > 0) {
                        return serialize($tmpArray);
                    }
                    return '';
                }

                return serialize($var);
            }
            return '';
        }
        if (count($var) > 0) {
            return false;
        }
        return '';
    }

Zend_Cache_Frontend_Page::_makeId() calls self::_makePartialId() and thus has to be adjusted too

    protected function _makeId()
    {
        $tmp = $_SERVER['REQUEST_URI'];

        $array = explode('?', $tmp, 2);
        $tmp = $array[0];
        foreach (array('Get', 'Post', 'Session', 'Files', 'Cookie') as $arrayName) {

            $tmp2 = $this->_makePartialId(
                        $arrayName,
                        $this->_activeOptions['cache_with_' . strtolower($arrayName) . '_variables'],
                        $this->_activeOptions['make_id_with_' . strtolower($arrayName) . '_variables'],
                        $this->_activeOptions['make_id_with_' . strtolower($arrayName) . '_whitelist']
                    );

            if ($tmp2===false) {
                return false;
            }

            $tmp = $tmp . $tmp2;
        }

        return md5($tmp);
    }

Now you can easly define which GET, POST, COOKIE,SERVER or FILES indexes should be used to generate the Cache id.

   frontend.options.regexps.1.make_id_with_cookie_variables = true
    frontend.options.default_options.cache_with_cookie_variables = true
    frontend.options.regexps.1.make_id_with_cookie_whitelist[] = "languageCookie"
    frontend.options.regexps.1.make_id_with_cookie_whitelist[] = "usernameCookie"

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions