Skip to content
This repository has been 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 opened this issue Apr 5, 2013 · 2 comments

Comments

@zfbot
Copy link

zfbot commented Apr 5, 2013

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"
@zfbot
Copy link
Author

zfbot commented Apr 5, 2013

This issue was ported from the ZF2 Jira Issue Tracker at
http://framework.zend.com/issues/browse/ZF-12411

Known GitHub users mentioned in the original message or comment:

@froschdesign
Copy link
Member

We will not add any new features or functionality for ZF1.

joanhe referenced this issue in magento/zf1 Apr 6, 2018
MAGETWO-89875: null passed to count() call in Zend/Validate/File/Uplo…
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants