[
  {
    "path": ".coveralls.yml",
    "content": "src_dir: app"
  },
  {
    "path": ".gitignore",
    "content": "/vendor\n/composer.lock\n.idea\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: php\n\nsudo: false\n\nphp:\n  - 5.5\n  - 5.6\n\nenv:\n  - MAGE=magento-1-9-1-0\n  - MAGE=magento-1-8-1-0\n  - MAGE=magento-1-7-0-2\n  - MAGE=magento-1-6-2-0\n  - MAGE=magento-1-5-1-0\n\ninstall:\n  - composer install --dev --prefer-dist --no-scripts\n  - curl https://gordonlesti.com/\"$MAGE\".tar.gz | tar xz\n  - mv $MAGE magento\n  - cd magento\n  - wget https://raw.githubusercontent.com/colinmollenhour/modman/master/modman\n  - chmod +x modman\n  - ./modman init\n  - cd ..\n\nbefore_script:\n  - mkdir -p build/logs\n  - mysql -e 'create database `magento`;'\n  - mysql -utravis magento < magento/var/magento.sql\n  - mysql -e 'create database `magento_test`;'\n  - mysql -utravis magento_test < magento/var/magento_test.sql\n  - cd magento\n  - ./modman link ./../../Lesti_Fpc\n  - ./modman clone https://github.com/EcomDev/EcomDev_PHPUnit.git\n  - cd ..\n\nscript:\n  - php vendor/bin/phpcs --standard=Zend -n app/\n  - php vendor/bin/phpmd app/ text codesize,design,unusedcode\n  - php vendor/bin/phpcpd app/\n  - cd magento && php ../vendor/bin/phpunit --coverage-clover ../build/logs/clover.xml && cd ..\n\nafter_script:\n  - php vendor/bin/coveralls\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\nAll Notable changes to `Lesti_Fpc` will be documented in this file.\n\nUpdates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles.\n\n## Unreleased\n\n### Added\n- Nothing\n\n### Deprecated\n- Nothing\n\n### Fixed\n- Nothing\n\n### Removed\n- Nothing\n\n### Security\n- Nothing\n\n## 1.4.8 - 2016-12-06\n\n### Added\n- [added utm_* parameters to uri params, fixes #274](https://github.com/GordonLesti/Lesti_Fpc/pull/275)\n\n## 1.4.7 - 2016-12-03\n\n### Added\n- [Invalidate cache after catalog rule apply](https://github.com/GordonLesti/Lesti_Fpc/pull/272)\n"
  },
  {
    "path": "CONDUCT.md",
    "content": "# Contributor Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, gender identity and expression, level of experience,\nnationality, personal appearance, race, religion, or sexual identity and\norientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or\nadvances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic\n  address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at `info@gordonlesti.com`. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at [http://contributor-covenant.org/version/1/4][version]\n\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "LICENSE.md",
    "content": "# Open Software License v. 3.0 (OSL-3.0)\n\n> This Open Software License (the \"License\") applies to any original work of authorship (the \"Original Work\") whose\n> owner (the \"Licensor\") has placed the following licensing notice adjacent to the copyright notice for the Original\n> Work:\n>\n> Licensed under the Open Software License version 3.0\n>\n> 1) **Grant of Copyright License**. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable\n> license, for > the duration of the copyright, to do the following:\n>\n> a) to reproduce the Original Work in copies, either alone or as part of a collective work;\n>\n> b) to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works\n> (\"Derivative Works\") based upon the Original Work;\n>\n> c) to distribute or communicate copies of the Original Work and Derivative Works to the public, *with the proviso that\n> copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open\n> Software License*;\n>\n> d) to perform the Original Work publicly; and\n>\n> e) to display the Original Work publicly.\n>\n> 2) **Grant** of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license,\n> under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the\n> Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work\n> and Derivative Works.\n>\n> 3) **Grant** of Source Code License. The term \"Source Code\" means the preferred form of the Original Work for making\n> modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to\n> provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that\n> Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the\n> Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for\n> as long as Licensor continues to distribute the Original Work.\n>\n> 4) **Exclusions From License Grant**. Neither the names of Licensor, nor the names of any contributors to the Original\n> Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this\n> Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this\n> License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual\n> property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any\n> patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor\n> even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit\n> Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a\n> right to license.\n>\n> 5) **External Deployment**. The term \"External Deployment\" means the use, distribution, or communication of the\n> Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone\n> other than You, whether those works are distributed or communicated to those persons or made available as an\n> application intended for use over a network. As an express condition for the grants of license hereunder, You must\n> treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c).\n>\n> 6) **Attribution Rights**. You must retain, in the Source Code of any Derivative Works that You create, all copyright,\n> patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any\n> descriptive text identified therein as an \"Attribution Notice.\" You must cause the Source Code for any Derivative\n> Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have\n> modified the Original Work.\n>\n> 7) **Warranty of Provenance and Disclaimer of Warranty**. Licensor warrants that the copyright in and to the Original\n> Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the\n> terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as\n> expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an \"AS IS\"\n> BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of\n> non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE\n> ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to\n> the Original Work is granted by this License except under this disclaimer.\n>\n> 8) **Limitation of Liability**. Under no circumstances and under no legal theory, whether in tort (including\n> negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or\n> consequential damages of any character arising as a result of this License or the use of the Original Work including,\n> without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other\n> commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such\n> limitation.\n>\n> 9) **Acceptance and Termination**. If, at any time, You expressly assented to this License, that assent indicates your\n> clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate\n> copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain\n> the express assent of recipients to the terms of this License. This License conditions your rights to undertake the\n> activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and\n> doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing\n> in this License is intended to affect copyright exceptions and limitations (including \"fair use\" or \"fair dealing\").\n> This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this\n> License upon your failure to honor the conditions in Section 1(c).\n>\n> 10) **Termination for Patent Action**. This License shall terminate automatically and You may no longer exercise any\n> of the rights granted to You by this License as of the date You commence an action, including a cross-claim or\n> counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination\n> provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other\n> software or hardware.\n>\n> 11) **Jurisdiction, Venue and Governing Law**. Any action or suit relating to this License may be brought only in the\n> courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under\n> the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations\n> Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work\n> outside the scope of this License or after its termination shall be subject to the requirements and penalties of\n> copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License.\n>\n> 12) **Attorneys' Fees**. In any action to enforce the terms of this License or seeking damages relating thereto, the\n> prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable\n> attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section\n> shall survive the termination of this License.\n>\n> 13) **Miscellaneous**. If any provision of this License is held to be unenforceable, such provision shall be reformed\n> only to the extent necessary to make it enforceable.\n>\n> 14) **Definition of \"You\" in This License**. \"You\" throughout this License, whether in upper or lower case, means an\n> individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal\n> entities, \"You\" includes any entity that controls, is controlled by, or is under common control with you. For purposes\n> of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such\n> entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares,\n> or (iii) beneficial ownership of such entity.\n>\n> 15) **Right to Use**. You may use the Original Work in all ways not otherwise restricted or conditioned by this\n> License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.\n>\n> 16) **Modification of This License**. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy,\n> distribute, or communicate this License without modification. Nothing in this License permits You to modify this\n> License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and\n> copy, distribute or communicate your modified version (the \"Modified License\") and apply it to other original works of\n> authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the\n> \"Open Software License\" or \"OSL\" and you may not use those names in the name of your Modified License; (ii) You must\n> replace the notice specified in the first paragraph above with the notice \"Licensed under &lt;insert your license name\n> here&gt;\" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may\n> not claim that your original works are open source software unless your Modified License has been approved by Open\n> Source Initiative (OSI) and You comply with its license review and certification process.\n"
  },
  {
    "path": "README.md",
    "content": "# Lesti_Fpc\n\n[![Latest Release][ico-version]][link-release]\n[![Software License][ico-license]](LICENSE.md)\n[![Build Status][ico-travis]][link-travis]\n[![Coverage Status][ico-coverall]][link-coveralls]\n\nSimple Magento Fullpagecache. The current documentation can be found\n[here](https://gordonlesti.com/lesti-fpc-documentationversion-1-4-5/).\n\n## Install\n\nSeveral quick start options are available:\n### Install manually\n  * [Download the latest release](https://github.com/GordonLesti/Lesti_Fpc/releases/latest)\n  * Unzip\n  * Copy `app` directory into Magento\n\n### Install with [modman](https://github.com/colinmollenhour/modman)\n\n```bash\nmodman clone https://github.com/GordonLesti/Lesti_Fpc.git\n```\n\n### Install with [Magento Composer Installer](https://github.com/Cotya/magento-composer-installer)\n  * add the requirement `gordonlesti/lesti_fpc`\n```json\n{\n    \"require\": {\n        \"gordonlesti/lesti_fpc\": \"*\"\n    }\n}\n```\n\n## Change log\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.\n\n## Contributing\n\nPlease see [CONTRIBUTING](CONTRIBUTING.md) and [CONDUCT](CONDUCT.md) for details.\n\n## Security\n\nIf you discover any security related issues, please email info@gordonlesti.com instead of using the issue tracker.\n\n## Credits\n\n- [Gordon Lesti][link-author]\n- [All Contributors][link-contributors]\n\n## License\n\nThe Open Software License v. 3.0 (OSL-3.0). Please see [License File](LICENSE.md) for more information.\n\n[ico-version]: https://img.shields.io/github/release/GordonLesti/Lesti_Fpc.svg?style=flat-square\n[ico-license]: https://img.shields.io/badge/license-OSL--3.0-brightgreen.svg?style=flat-square\n[ico-travis]: https://img.shields.io/travis/GordonLesti/Lesti_Fpc/master.svg?style=flat-square\n[ico-coverall]: https://img.shields.io/coveralls/GordonLesti/Lesti_Fpc/master.svg?style=flat-square\n\n[link-release]: https://github.com/GordonLesti/Lesti_Fpc/releases/latest\n[link-travis]: https://travis-ci.org/GordonLesti/Lesti_Fpc\n[link-coveralls]: https://coveralls.io/r/GordonLesti/Lesti_Fpc\n[link-author]: https://gordonlesti.com/\n[link-contributors]: ../../contributors\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Block/Catalog/Product/View/Ajax.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Block_Catalog_Product_View_Ajax\n */\nclass Lesti_Fpc_Block_Catalog_Product_View_Ajax extends Mage_Core_Block_Template\n{\n    /**\n     * @return bool|string\n     */\n    public function getAjaxUrl()\n    {\n        $id = $this->_getProductId();\n        if (Mage::getSingleton('fpc/fpc')->isActive() &&\n            in_array(\n                'catalog_product_view',\n                Mage::helper('fpc')->getCacheableActions()\n            ) &&\n            Mage::helper('fpc/block')->useRecentlyViewedProducts() &&\n            $id\n        ) {\n            return $this->getUrl(\n                'fpc/catalog_product/view',\n                array(\n                    'id' => $id,\n                    '_secure' => Mage::app()->getStore()->isCurrentlySecure()\n                )\n            );\n        }\n        return false;\n    }\n\n    /**\n     * @return bool\n     */\n    protected function _getProductId()\n    {\n        $product = Mage::registry('current_product');\n        if ($product) {\n            return $product->getId();\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Core/Block/Messages.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Core_Block_Messages\n */\nclass Lesti_Fpc_Core_Block_Messages extends Mage_Core_Block_Messages\n{\n    /**\n     * Retrieve messages in HTML format grouped by type\n     *\n     * @param   string $type\n     * @return  string\n     */\n    public function getGroupedHtml()\n    {\n        $html = parent::getGroupedHtml();\n\n        /**\n         * Use single transport object instance for all blocks\n         */\n\n        $_transportObject = new Varien_Object;\n        $_transportObject->setHtml($html);\n        Mage::dispatchEvent(\n            'core_block_messages_get_grouped_html_after',\n            array('block' => $this, 'transport' => $_transportObject)\n        );\n        $html = $_transportObject->getHtml();\n\n        return $html;\n    }\n}"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Helper/Abstract.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Helper_Abstract\n */\nabstract class Lesti_Fpc_Helper_Abstract extends Mage_Core_Helper_Abstract\n{\n    /**\n     * Returns comma seperated store configs as array\n     *\n     * @param $path\n     * @param null $store\n     * @return array\n     */\n    public function getCSStoreConfigs($path, $store = null)\n    {\n        $configs = trim(Mage::getStoreConfig($path, $store));\n\n        if ($configs) {\n            return array_unique(array_map('trim', explode(',', $configs)));\n        }\n\n        return array();\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Helper/Block/Messages.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Helper_Block_Messages\n */\nclass Lesti_Fpc_Helper_Block_Messages extends Mage_Core_Helper_Abstract\n{\n    /**\n     * @param $layout\n     * @return mixed\n     */\n    public function initLayoutMessages(\n        Mage_Core_Model_Layout $layout,\n        $messagesStorage =\n        array('catalog/session', 'tag/session', 'checkout/session', 'customer/session')\n    )\n    {\n        $block = $layout->getMessagesBlock();\n        if ($block) {\n            foreach ($messagesStorage as $storageName) {\n                $storage = Mage::getSingleton($storageName);\n                if ($storage) {\n                    $block->addMessages($storage->getMessages(true));\n                    $block->setEscapeMessageFlag(\n                        $storage->getEscapeMessages(true)\n                    );\n                } else {\n                    Mage::throwException(\n                        Mage::helper('core')->__(\n                            'Invalid messages storage \"%s\" for layout '.\n                            'messages initialization',\n                            (string)$storageName\n                        )\n                    );\n                }\n            }\n        }\n        return $layout;\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Helper/Block.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Helper_Block\n */\nclass Lesti_Fpc_Helper_Block extends Lesti_Fpc_Helper_Abstract\n{\n    const DYNAMIC_BLOCKS_XML_PATH = 'system/fpc/dynamic_blocks';\n    const LAZY_BLOCKS_XML_PATH = 'system/fpc/lazy_blocks';\n    const LAZY_BLOCKS_VALID_SESSION_PARAM = 'fpc_lazy_blocks_valid';\n    const USE_RECENTLY_VIEWED_PRODUCTS_XML_PATH =\n        'system/fpc/use_recently_viewed_products';\n\n    /**\n     * @return array\n     */\n    public function getDynamicBlocks()\n    {\n        return $this->getCSStoreConfigs(self::DYNAMIC_BLOCKS_XML_PATH);\n    }\n\n    /**\n     * @return array\n     */\n    public function getLazyBlocks()\n    {\n        return $this->getCSStoreConfigs(self::LAZY_BLOCKS_XML_PATH);\n    }\n\n    /**\n     * @return bool\n     */\n    public function areLazyBlocksValid()\n    {\n        $hash = $this->_getLazyBlocksValidHash();\n        $session = Mage::getSingleton('customer/session');\n        $sessionHash = $session->getData(self::LAZY_BLOCKS_VALID_SESSION_PARAM);\n        if ($sessionHash === false || $hash != $sessionHash) {\n            $session->setData(self::LAZY_BLOCKS_VALID_SESSION_PARAM, $hash);\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * @return string\n     */\n    protected function _getLazyBlocksValidHash()\n    {\n        $params = array();\n        $request = Mage::app()->getRequest();\n        $params['host'] = $request->getServer('HTTP_HOST');\n        $params['port'] = $request->getServer('SERVER_PORT');\n        // store\n        $storeCode = Mage::app()->getStore()->getCode();\n        if ($storeCode) {\n            $params['store'] = $storeCode;\n        }\n        // currency\n        $currencyCode = Mage::app()->getStore()->getCurrentCurrencyCode();\n        if ($currencyCode) {\n            $params['currency'] = $currencyCode;\n        }\n        $customerSession = Mage::getSingleton('customer/session');\n        $params['customer_group_id'] = $customerSession->getCustomerGroupId();\n        $design = Mage::getDesign();\n        $params['design'] = $design->getPackageName().'_'.\n            $design->getTheme('template');\n\n        $params['blocks'] = implode(',', $this->getLazyBlocks());\n\n        return sha1(serialize($params));\n    }\n\n    /**\n     * @param $blockName\n     * @return string\n     */\n    public function getPlaceholderHtml($blockName)\n    {\n        return '<!-- fpc ' . sha1($blockName) . ' -->';\n    }\n\n    /**\n     * @param $blockName\n     * @return string\n     */\n    public function getKey($blockName)\n    {\n        return sha1($blockName) . '_block';\n    }\n\n    /**\n     * @return mixed\n     */\n    public function useRecentlyViewedProducts()\n    {\n        return (bool)Mage::getStoreConfig(\n            self::USE_RECENTLY_VIEWED_PRODUCTS_XML_PATH\n        );\n    }\n\n    /**\n     * @param $block\n     * @return array\n     */\n    public function getCacheTags($block)\n    {\n        $cacheTags = array();\n        $blockName = $block->getNameInLayout();\n        if ($blockName == 'product_list') {\n            $cacheTags[] = sha1('product');\n            foreach ($block->getLoadedProductCollection() as $product) {\n                $cacheTags[] = sha1('product_' . $product->getId());\n            }\n        } else if ($block instanceof Mage_Cms_Block_Block ||\n        is_subclass_of($block, 'Mage_Cms_Block_Block')) {\n            $cacheTags[] = sha1('cmsblock');\n            $cacheTags[] = sha1('cmsblock_' . $block->getBlockId());\n        }\n        return $cacheTags;\n    }\n\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Helper/Data.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Helper_Data\n */\nclass Lesti_Fpc_Helper_Data extends Lesti_Fpc_Helper_Abstract\n{\n    const XML_PATH_CACHEABLE_ACTIONS = 'system/fpc/cache_actions';\n    const XML_PATH_BYPASS_HANDLES = 'system/fpc/bypass_handles';\n    const XML_PATH_URI_PARAMS = 'system/fpc/uri_params';\n    const XML_PATH_URI_PARAMS_LAYERED_NAVIGATION = 'system/fpc/uri_params_layered_navigation';\n    const XML_PATH_CUSTOMER_GROUPS = 'system/fpc/customer_groups';\n    const XML_PATH_REFRESH_ACTIONS = 'system/fpc/refresh_actions';\n    const XML_PATH_MISS_URI_PARAMS = 'system/fpc/miss_uri_params';\n    const LAYOUT_ELEMENT_CLASS = 'Mage_Core_Model_Layout_Element';\n    const CACHE_KEY_LAYERED_NAVIGATION_ATTRIBUTES = 'layeredNavigationAttributes';\n\n    const REGISTRY_KEY_PARAMS = 'fpc_params';\n\n    // List of pages that contain layered navigation\n    static protected $_pagesWithLayeredNavigation = array(\n        'catalogsearch_result_index',\n        'catalog_category_layered',\n        'catalog_category_view'\n    );\n\n    /**\n     * @return array\n     */\n    public function getCacheableActions()\n    {\n        return $this->getCSStoreConfigs(self::XML_PATH_CACHEABLE_ACTIONS);\n    }\n\n    /**\n     * @return array\n     */\n    public function getBypassHandles()\n    {\n        return $this->getCSStoreConfigs(self::XML_PATH_BYPASS_HANDLES);\n    }\n\n    /**\n     * @return array\n     */\n    public function getRefreshActions()\n    {\n        return $this->getCSStoreConfigs(self::XML_PATH_REFRESH_ACTIONS);\n    }\n\n    /**\n     * @param string $postfix\n     * @return string\n     */\n    public function getKey($postfix = '_page')\n    {\n        return sha1($this->_getParams()) . $postfix;\n    }\n\n    /**\n     * @return mixed\n     */\n    protected function _getParams()\n    {\n        if (!Mage::registry(self::REGISTRY_KEY_PARAMS)) {\n            $request = Mage::app()->getRequest();\n            $params = array('host' => $request->getServer('HTTP_HOST'),\n                'port' => $request->getServer('SERVER_PORT'),\n                'secure' => Mage::app()->getStore()->isCurrentlySecure(),\n                'full_action_name' => $this->getFullActionName(),\n                'ajax' => $request->isAjax(),\n              );\n            $uriParams = $this->_getUriParams();\n            foreach ($request->getParams() as $requestParam =>\n                     $requestParamValue) {\n                if (!$requestParamValue) {\n                    continue;\n                }\n                foreach ($uriParams as $uriParam) {\n                    if ($this->_matchUriParam($uriParam, $requestParam)) {\n                        $params['uri_' . $requestParam] = $requestParamValue;\n                        break;\n                    }\n                }\n            }\n            if (Mage::getStoreConfig(self::XML_PATH_CUSTOMER_GROUPS)) {\n                $customerSession = Mage::getSingleton('customer/session');\n                $params['customer_group_id'] = $customerSession\n                    ->getCustomerGroupId();\n            }\n\n            // edit parameters via event\n            $parameters = new Varien_Object();\n            $parameters->setValue($params);\n            Mage::dispatchEvent(\n                'fpc_helper_collect_params',\n                array('parameters' => $parameters)\n            );\n            $params = $parameters->getValue();\n\n\n            Mage::register(self::REGISTRY_KEY_PARAMS, serialize($params));\n        }\n        return Mage::registry(self::REGISTRY_KEY_PARAMS);\n    }\n\n    /**\n     * Matches URI param against expression\n     * (string comparison or regular expression)\n     *\n     * @param string $expression\n     * @param string $param\n     * @return boolean\n     */\n    protected function _matchUriParam($expression, $param)\n    {\n        if (substr($expression, 0, 1) === '/' &&\n            substr($expression, -1, 1) === '/') {\n            return (bool) preg_match($expression, $param);\n        } else {\n            return $expression === $param;\n        }\n    }\n\n    /**\n     * @return array\n     */\n    public function _getUriParams()\n    {\n        $configParams = $this->getCSStoreConfigs(self::XML_PATH_URI_PARAMS);\n\n        if (Mage::getStoreConfig(self::XML_PATH_URI_PARAMS_LAYERED_NAVIGATION)) {\n            $layeredNavigationParams = $this->_getLayeredNavigationAttributes();\n        } else {\n            $layeredNavigationParams = array();\n        }\n\n        return array_merge($configParams, $layeredNavigationParams);\n    }\n\n    /**\n     * If on a page that contains a layered navigation block, load all attributes that are supposed to show\n     *\n     * @return array\n     */\n    protected function _getLayeredNavigationAttributes()\n    {\n        // List of attributes that are used in layered navigation\n        $layeredNavigationAttributes = array();\n\n        $currentFullActionName = $this->getFullActionName();\n        if (in_array($currentFullActionName, self::$_pagesWithLayeredNavigation)) {\n            /** @var Mage_Catalog_Model_Resource_Product_Attribute_Collection $attributeCollection */\n            $attributeCollection = Mage::getResourceModel('catalog/product_attribute_collection');\n\n            // The category and search pages may have different filterable attributes, based on how the attributes\n            // are configured\n            switch ($currentFullActionName) {\n                case 'catalogsearch_result_index':\n                    $filterableField = 'is_filterable_in_search';\n                    break;\n                case 'catalog_category_layered':\n                case 'catalog_category_view':\n                default:\n                    $filterableField = 'is_filterable';\n            }\n\n            $cache = Mage::app()->getCache();\n            $cacheId = self::CACHE_KEY_LAYERED_NAVIGATION_ATTRIBUTES.'_'.$filterableField;\n            $cacheTags = array('FPC', self::CACHE_KEY_LAYERED_NAVIGATION_ATTRIBUTES);\n            $layeredNavigationAttributesCache = $cache->load($cacheId);\n\n            if (!$layeredNavigationAttributesCache) {\n                $attributeCollection->addFieldToFilter($filterableField, array('in' => array(1,2)));\n                foreach ($attributeCollection as $attribute) {\n                    $layeredNavigationAttributes[] = $attribute->getAttributeCode();\n                }\n                $cache->save(serialize($layeredNavigationAttributes), $cacheId, $cacheTags);\n            } else {\n                $layeredNavigationAttributes = unserialize($layeredNavigationAttributesCache);\n            }\n        }\n\n        return $layeredNavigationAttributes;\n    }\n\n    /**\n     * @return array\n     */\n    protected function _getMissUriParams()\n    {\n        return $this->getCSStoreConfigs(self::XML_PATH_MISS_URI_PARAMS);\n    }\n\n    /**\n     * @return bool\n     */\n    public function canCacheRequest()\n    {\n        $request = Mage::app()->getRequest();\n        if (strtoupper($request->getMethod()) != 'GET') {\n            return false;\n        }\n        $missParams = $this->_getMissUriParams();\n        foreach ($missParams as $missParam) {\n            $pair = array_map('trim', explode('=', $missParam));\n            $key = $pair[0];\n            $param = $request->getParam($key);\n            if ($param && isset($pair[1]) && preg_match($pair[1], $param)) {\n                return false;\n            }\n        }\n\n        $handles = Mage::app()->getLayout()->getUpdate()->getHandles();\n        foreach ($this->getBypassHandles() as $handle) {\n            if (in_array($handle, $handles)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * @return string\n     */\n    public function getFullActionName()\n    {\n        $delimiter = '_';\n        $request = Mage::app()->getRequest();\n        return $request->getRequestedRouteName() . $delimiter .\n        $request->getRequestedControllerName() . $delimiter .\n        $request->getRequestedActionName();\n    }\n\n    /**\n     * @param Mage_Core_Controller_Response_Http $response\n     * @return string\n     */\n    public function getContentType(\\Mage_Core_Controller_Response_Http $response)\n    {\n        foreach ($response->getHeaders() as $header) {\n            if (isset($header['name']) && $header['name'] === 'Content-Type' && isset($header['value'])) {\n                return $header['value'];\n            }\n        }\n\n        return 'text/html; charset=UTF-8';\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Model/Adminhtml/System/Config/Source/Gzcompress.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Model_Adminhtml_System_Config_Source_Gzcompress\n */\nclass Lesti_Fpc_Model_Adminhtml_System_Config_Source_Gzcompress\n{\n    /**\n     * @return array\n     */\n    public function toOptionArray()\n    {\n        $options = array();\n        foreach ($this->toArray() as $key => $value) {\n            $options[] = array('value' => $key, 'label' => $value);\n        }\n\n        return $options;\n    }\n\n    /**\n     * @return array\n     */\n    public function toArray()\n    {\n        $options = array(-2 => Mage::helper('fpc')->__('No'));\n        for ($i=0; $i <10; $i++) {\n            $options[$i] = $i;\n        }\n\n        return $options;\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Model/Fpc/CacheItem.php",
    "content": "<?php\n\n/**\n * Class Lesti_Fpc_Model_Fpc_CacheItem\n */\nclass Lesti_Fpc_Model_Fpc_CacheItem\n{\n    /**\n     * @var string\n     */\n    private $_content;\n\n    /**\n     * @var int\n     */\n    private $_time;\n\n    /**\n     * @var string\n     */\n    private $_contentType;\n\n    /**\n     * @param string $content\n     * @param int    $time\n     * @param string $contentType\n     */\n    public function __construct($content, $time, $contentType)\n    {\n        $this->_content = $content;\n        $this->_time = $time;\n        $this->_contentType = $contentType;\n    }\n\n    /**\n     * @return string\n     */\n    public function getContent()\n    {\n        return $this->_content;\n    }\n\n    /**\n     * @return int\n     */\n    public function getTime()\n    {\n        return $this->_time;\n    }\n\n    /**\n     * @return string\n     */\n    public function getContentType()\n    {\n        return $this->_contentType;\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Model/Fpc.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Model_Fpc\n */\nclass Lesti_Fpc_Model_Fpc extends Mage_Core_Model_Cache\n{\n    const GZCOMPRESS_LEVEL_XML_PATH = 'system/fpc/gzcompress_level';\n    const CACHE_TAG = 'FPC';\n\n    /**\n     * Default options for default backend\n     *\n     * @var array\n     */\n    protected $_defaultBackendOptions = array(\n        'hashed_directory_level'    => 6,\n        'hashed_directory_perm'    => 0777,\n        'file_name_prefix'          => 'fpc',\n    );\n\n    /**\n     * Default options for default backend used by Zend Framework versions\n     * older than 1.12.0\n     *\n     * @var array\n     */\n    protected $_legacyDefaultBackendOptions = array(\n        'hashed_directory_level'    => 6,\n        'hashed_directory_umask'    => 0777,\n        'file_name_prefix'          => 'fpc',\n    );\n\n    public function __construct()\n    {\n        /*\n         * If the version of Zend Framework is older than 1.12, fallback to the\n         * legacy cache settings.\n         * See http://framework.zend.com/issues/browse/ZF-12047\n         */\n        if (Zend_Version::compareVersion('1.12.0') > 0) {\n            $this->_defaultBackendOptions = $this->_legacyDefaultBackendOptions;\n        }\n        $node = Mage::getConfig()->getNode('global/fpc');\n        $options = array();\n        if ($node) {\n            $options = $node->asArray();\n        }\n        parent::__construct($options);\n    }\n\n    /**\n     * Save data\n     *\n     * @param mixed $item\n     * @param string $id\n     * @param array $tags\n     * @param int $lifeTime\n     * @return bool\n     */\n    public function save($item, $id, $tags=array(), $lifeTime=null)\n    {\n        if (!in_array(self::CACHE_TAG, $tags)) {\n            $tags[] = self::CACHE_TAG;\n        }\n        if (is_null($lifeTime)) {\n            $lifeTime = (int) $this->getFrontend()->getOption('lifetime');\n        }\n        $data = array(\n            $item->getContent(),\n            $item->getTime(),\n            $item->getContentType(),\n        );\n        // edit cached object\n        $cacheData = new Varien_Object();\n        $cacheData->setCachedata($data);\n        $cacheData->setCacheId($id);\n        $cacheData->setTags($tags);\n        $cacheData->setLifeTime($lifeTime);\n        Mage::dispatchEvent(\n            'fpc_save_data_before',\n            array('cache_data' => $cacheData)\n        );\n        $data = $cacheData->getCachedata();\n        $id = $cacheData->getCacheId();\n        $tags = $cacheData->getTags();\n        $lifeTime = $cacheData->getLifeTime();\n\n        $compressLevel = Mage::getStoreConfig(self::GZCOMPRESS_LEVEL_XML_PATH);\n        $data = serialize($data);\n        if ($compressLevel != -2) {\n            $data = gzcompress($data, $compressLevel);\n        }\n\n        return $this->_frontend->save(\n            $data,\n            $this->_id($id),\n            $this->_tags($tags),\n            $lifeTime\n        );\n    }\n\n    /**\n     * @param string $id\n     * @return boolean|\\Lesti_Fpc_Model_Fpc_CacheItem\n     */\n    public function load($id)\n    {\n        $data = parent::load($id);\n        if ($data === false) {\n            return false;\n        }\n        $compressLevel = Mage::getStoreConfig(self::GZCOMPRESS_LEVEL_XML_PATH);\n        if ($data !== false && $compressLevel != -2) {\n            $data = gzuncompress($data);\n        }\n\n        $data = unserialize($data);\n\n        return new Lesti_Fpc_Model_Fpc_CacheItem($data[0], $data[1], $data[2]);\n    }\n\n    /**\n     * Clean cached data by specific tag\n     *\n     * @param   array $tags\n     * @return  bool\n     */\n    public function clean($tags=array())\n    {\n        $mode = Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG;\n        if (!empty($tags)) {\n            if (!is_array($tags)) {\n                $tags = array($tags);\n            }\n            $res = $this->_frontend->clean($mode, $this->_tags($tags));\n        } else {\n            $res = $this->_frontend->clean($mode, array(self::CACHE_TAG));\n            $res = $res &&\n                $this->_frontend->clean(\n                    $mode,\n                    array(Mage_Core_Model_Config::CACHE_TAG)\n                );\n        }\n        return $res;\n    }\n\n    /**\n     * @return bool\n     */\n    public function isActive()\n    {\n        return Mage::app()->useCache('fpc');\n    }\n\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Model/Observer/Clean.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\nclass Lesti_Fpc_Model_Observer_Clean\n{\n    const CACHE_TYPE = 'fpc';\n\n    /**\n     * Cron job method to clean old cache resources\n     */\n    public function coreCleanCache()\n    {\n        $this->_getFpc()->getFrontend()->clean(Zend_Cache::CLEANING_MODE_OLD);\n    }\n\n    public function adminhtmlCacheFlushAll()\n    {\n        $this->_getFpc()->clean();\n    }\n\n    public function controllerActionPredispatchAdminhtmlCacheMassRefresh()\n    {\n        $types = Mage::app()->getRequest()->getParam('types');\n        if ($this->_getFpc()->isActive()) {\n            if ((is_array($types) && in_array(self::CACHE_TYPE, $types)) ||\n                $types == self::CACHE_TYPE) {\n                $this->_getFpc()->clean();\n            }\n        }\n    }\n\n    /**\n     * @return Lesti_Fpc_Model_Fpc\n     */\n    protected function _getFpc()\n    {\n        return Mage::getSingleton('fpc/fpc');\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Model/Observer/Parameters.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Model_Observer_Parameters\n */\nclass Lesti_Fpc_Model_Observer_Parameters\n{\n    const XML_PATH_SESSION_PARAMS = 'system/fpc/session_params';\n\n    /**\n     * @param $observer\n     */\n    public function fpcHelperCollectParams($observer)\n    {\n        $params = array();\n        // store\n        $storeCode = Mage::app()->getStore(true)->getCode();\n        if ($storeCode) {\n            $params['store'] = $storeCode;\n        }\n        // currency\n        $currencyCode = Mage::app()->getStore()->getCurrentCurrencyCode();\n        if ($currencyCode) {\n            $params['currency'] = $currencyCode;\n        }\n        // design\n        $design = Mage::getDesign();\n        $params['design'] = $design->getPackageName().'_'.\n            $design->getTheme('template');\n        // session paramaters\n        /** @var Lesti_Fpc_Helper_Data $helper */\n        $helper = Mage::helper('fpc');\n        if ($helper->getFullActionName() === 'catalog_category_view') {\n            $sessionParams = $this->_getSessionParams();\n            $catalogSession = Mage::getSingleton('catalog/session');\n            foreach ($sessionParams as $param) {\n                if ($data = $catalogSession->getData($param)) {\n                    $params['session_' . $param] = $data;\n                }\n            }\n        }\n\n        $parameters = $observer->getEvent()->getParameters();\n        $additionalParams = $parameters->getValue();\n        $additionalParams = array_merge($additionalParams, $params);\n        $parameters->setValue($additionalParams);\n    }\n\n    /**\n     * @return array\n     */\n    protected function _getSessionParams()\n    {\n        $helper = Mage::helper('fpc');\n        return $helper->getCSStoreConfigs(self::XML_PATH_SESSION_PARAMS);\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Model/Observer/Save.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Model_Observer_Save\n */\nclass Lesti_Fpc_Model_Observer_Save\n{\n    const PRODUCT_IDS_MASS_ACTION_KEY = 'fpc_product_ids_mass_action';\n\n    /**\n     * @param $observer\n     */\n    public function catalogProductSaveAfter($observer)\n    {\n        if ($this->_getFpc()->isActive()) {\n            $product = $observer->getEvent()->getProduct();\n            if ($product->getId()) {\n                $this->_getFpc()->clean(sha1('product_' . $product->getId()));\n\n                $origData = $product->getOrigData();\n                if (empty($origData)\n                    || (!empty($origData) && $product->dataHasChangedFor('status'))\n                ) {\n                    $categories = $product->getCategoryIds();\n                    foreach ($categories as $categoryId) {\n                        $this->_getFpc()->clean(\n                            sha1('category_' . $categoryId)\n                        );\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * @param $observer\n     */\n    public function catalogCategorySaveAfter($observer)\n    {\n        if ($this->_getFpc()->isActive()) {\n            $category = $observer->getEvent()->getCategory();\n            if ($category->getId()) {\n                $this->_getFpc()->clean(sha1('category_' . $category->getId()));\n            }\n        }\n    }\n\n    /**\n     * @param $observer\n     */\n    public function cmsPageSaveAfter($observer)\n    {\n        if ($this->_getFpc()->isActive()) {\n            $page = $observer->getEvent()->getObject();\n            if ($page->getId()) {\n                $tags = array(sha1('cms_' . $page->getId()),\n                    sha1('cms_' . $page->getIdentifier()));\n                $this->_getFpc()\n                    ->clean($tags, Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG);\n            }\n        }\n    }\n\n    /**\n     * @param $observer\n     */\n    public function modelSaveAfter($observer)\n    {\n        if ($this->_getFpc()->isActive()) {\n            $object = $observer->getEvent()->getObject();\n            if ($object instanceof Mage_Cms_Model_Block) {\n                $this->_cmsBlockSaveAfter($object);\n            } elseif ($object instanceof Mage_Index_Model_Event) {\n                $dataObject = $object->getDataObject();\n                if ($object->getType() === 'mass_action' &&\n                    $object->getEntity() === 'catalog_product' &&\n                    $dataObject instanceof Mage_Catalog_Model_Product_Action) {\n                    $this->_catalogProductSaveAfterMassAction(\n                        $dataObject->getProductIds()\n                    );\n                }\n            }\n        }\n    }\n\n    /**\n     * @param $observer\n     */\n    public function reviewDeleteAfter($observer)\n    {\n        if ($this->_getFpc()->isActive()) {\n            $object = $observer->getEvent()->getObject();\n            $this->_getFpc()->clean(sha1('product_' . $object->getEntityPkValue()));\n        }\n    }\n\n    /**\n     * @param $observer\n     */\n    public function reviewSaveAfter($observer)\n    {\n        if ($this->_getFpc()->isActive()) {\n            $object = $observer->getEvent()->getObject();\n            $this->_getFpc()->clean(sha1('product_' . $object->getEntityPkValue()));\n        }\n    }\n\n    /**\n     * @param $observer\n     */\n    public function cataloginventoryStockItemSaveAfter($observer)\n    {\n        $item = $observer->getEvent()->getItem();\n        if ($item->getStockStatusChangedAuto()) {\n            $this->_getFpc()->clean(sha1('product_' . $item->getProductId()));\n        }\n    }\n\n    /**\n     * @return Lesti_Fpc_Model_Fpc\n     */\n    protected function _getFpc()\n    {\n        return Mage::getSingleton('fpc/fpc');\n    }\n\n    /**\n     * @param Mage_Cms_Model_Block $block\n     */\n    protected function _cmsBlockSaveAfter(Mage_Cms_Model_Block $block)\n    {\n        $this->_getFpc()->clean(sha1('cmsblock_'.$block->getIdentifier()));\n    }\n\n    /**\n     * @param array $productIds\n     */\n    protected function _catalogProductSaveAfterMassAction(array $productIds)\n    {\n        if (!empty($productIds)) {\n            $tags = array();\n            foreach ($productIds as $productId) {\n                $tags[] = sha1('product_' . $productId);\n            }\n            $this->_getFpc()->clean($tags);\n        }\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Model/Observer/Tags.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Model_Observer_Tags\n */\nclass Lesti_Fpc_Model_Observer_Tags\n{\n    /**\n     * @param $observer\n     */\n    public function fpcObserverCollectCacheTags($observer)\n    {\n        /** @var Lesti_Fpc_Helper_Data $helper */\n        $helper = Mage::helper('fpc');\n        $fullActionName = $helper->getFullActionName();\n        $cacheTags = array();\n        $request = Mage::app()->getRequest();\n        switch ($fullActionName) {\n            case 'cms_index_index' :\n                $cacheTags = $this->getCmsIndexIndexCacheTags();\n                break;\n            case 'cms_page_view' :\n                $cacheTags = $this->getCmsPageViewCacheTags($request);\n                break;\n            case 'catalog_product_view' :\n                $cacheTags = $this->getCatalogProductViewCacheTags($request);\n                break;\n            case 'catalog_category_view' :\n                $cacheTags = $this->getCatalogCategoryViewCacheTags($request);\n                break;\n        }\n\n        $cacheTagObject = $observer->getEvent()->getCacheTags();\n        $additionalCacheTags = $cacheTagObject->getValue();\n        $additionalCacheTags = array_merge($additionalCacheTags, $cacheTags);\n        $cacheTagObject->setValue($additionalCacheTags);\n    }\n\n    /**\n     * @return array\n     */\n    protected function getCmsIndexIndexCacheTags()\n    {\n        $cacheTags = array();\n        $cacheTags[] = sha1('cms');\n        $pageId = Mage::getStoreConfig(\n            Mage_Cms_Helper_Page::XML_PATH_HOME_PAGE\n        );\n        if ($pageId) {\n            $cacheTags[] = sha1('cms_' . $pageId);\n        }\n        return $cacheTags;\n    }\n\n    /**\n     * @param Mage_Core_Controller_Request_Http $request\n     * @return array\n     */\n    protected function getCmsPageViewCacheTags(\n        Mage_Core_Controller_Request_Http $request\n    )\n    {\n        $cacheTags = array();\n        $cacheTags[] = sha1('cms');\n        $pageId = $request->getParam(\n            'page_id',\n            $request->getParam('id', false)\n        );\n        if ($pageId) {\n            $cacheTags[] = sha1('cms_' . $pageId);\n        }\n        return $cacheTags;\n    }\n\n    /**\n     * @param Mage_Core_Controller_Request_Http $request\n     * @return array\n     */\n    protected function getCatalogProductViewCacheTags(\n        Mage_Core_Controller_Request_Http $request\n    )\n    {\n        $cacheTags = array();\n        $cacheTags[] = sha1('product');\n        $productId = (int)$request->getParam('id');\n        if ($productId) {\n            $cacheTags[] = sha1('product_' . $productId);\n\n            // configurable product\n            $configurableProduct = Mage::getModel(\n                'catalog/product_type_configurable'\n            );\n            // get all childs of this product and add the cache tag\n            $childIds = $configurableProduct->getChildrenIds($productId);\n            foreach ($childIds as $childIdGroup) {\n                foreach ($childIdGroup as $childId) {\n                    $cacheTags[] = sha1('product_' . $childId);\n                }\n            }\n            // get all parents of this product and add the cache tag\n            $parentIds = $configurableProduct\n                ->getParentIdsByChild($productId);\n            foreach ($parentIds as $parentId) {\n                $cacheTags[] = sha1('product_' . $parentId);\n            }\n\n            // grouped product\n            $groupedProduct = Mage::getModel('catalog/product_type_grouped');\n            // get all childs of this product and add the cache tag\n            $childIds = $groupedProduct->getChildrenIds($productId);\n            foreach ($childIds as $childIdGroup) {\n                foreach ($childIdGroup as $childId) {\n                    $cacheTags[] = sha1('product_' . $childId);\n                }\n            }\n            // get all parents of this product and add the cache tag\n            $parentIds = $groupedProduct->getParentIdsByChild($productId);\n            foreach ($parentIds as $parentId) {\n                $cacheTags[] = sha1('product_' . $parentId);\n            }\n\n            $categoryId = (int)$request->getParam('category', false);\n            if ($categoryId) {\n                $cacheTags[] = sha1('category');\n                $cacheTags[] = sha1('category_' . $categoryId);\n            }\n        }\n        return $cacheTags;\n    }\n\n    /**\n     * @param Mage_Core_Controller_Request_Http $request\n     * @return array\n     */\n    protected function getCatalogCategoryViewCacheTags(\n        Mage_Core_Controller_Request_Http $request\n    )\n    {\n        $cacheTags = array();\n        $cacheTags[] = sha1('category');\n        $categoryId = (int)$request->getParam('id', false);\n        if ($categoryId) {\n            $cacheTags[] = sha1('category_' . $categoryId);\n        }\n        return $cacheTags;\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Model/Observer.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Model_Observer\n */\nclass Lesti_Fpc_Model_Observer\n{\n    const CUSTOMER_SESSION_REGISTRY_KEY = 'fpc_customer_session';\n    const SHOW_AGE_XML_PATH = 'system/fpc/show_age';\n    const FORM_KEY_PLACEHOLDER = '<!-- fpc form_key_placeholder -->';\n    const SESSION_ID_PLACEHOLDER = '<!-- fpc session_id_placeholder -->';\n\n    protected $_cached = false;\n    protected $_html = array();\n    protected $_placeholder = array();\n    protected $_cacheTags = array();\n\n    /**\n     * @param $observer\n     * @SuppressWarnings(PHPMD.ExitExpression)\n     */\n    public function controllerActionLayoutGenerateBlocksBefore($observer)\n    {\n        if ($this->_getFpc()->isActive() &&\n            !$this->_cached &&\n            Mage::helper('fpc')->canCacheRequest()) {\n            $key = Mage::helper('fpc')->getKey();\n            if ($object = $this->_getFpc()->load($key)) {\n                $time = $object->getTime();\n                $body = $object->getContent();\n                $this->_cached = true;\n                $session = Mage::getSingleton('customer/session');\n                $lazyBlocks = Mage::helper('fpc/block')->getLazyBlocks();\n                $dynamicBlocks = Mage::helper('fpc/block')->getDynamicBlocks();\n                $blockHelper = Mage::helper('fpc/block');\n                if ($blockHelper->areLazyBlocksValid()) {\n                    foreach ($lazyBlocks as $blockName) {\n                        $this->_placeholder[] = $blockHelper\n                            ->getPlaceholderHtml($blockName);\n                        $this->_html[] = $session\n                            ->getData('fpc_lazy_block_' . $blockName);\n                    }\n                } else {\n                    $dynamicBlocks = array_merge($dynamicBlocks, $lazyBlocks);\n                }\n                // prepare Layout\n                $layout = $this->_prepareLayout(\n                    $observer->getEvent()->getLayout(),\n                    $dynamicBlocks\n                );\n                // insert dynamic blocks\n                $this->_insertDynamicBlocks(\n                    $layout,\n                    $session,\n                    $dynamicBlocks,\n                    $lazyBlocks\n                );\n                $this->_placeholder[] = self::SESSION_ID_PLACEHOLDER;\n                $this->_html[] = $session->getEncryptedSessionId();\n                $this->_replaceFormKey();\n                $body = str_replace($this->_placeholder, $this->_html, $body);\n                if (Mage::getStoreConfig(self::SHOW_AGE_XML_PATH)) {\n                    Mage::app()->getResponse()->setHeader('Age', time() - $time);\n                }\n                Mage::app()->getResponse()->setHeader('Content-Type', $object->getContentType(), true);\n                $response = Mage::app()->getResponse();\n                $response->setBody($body);\n                Mage::dispatchEvent(\n                    'fpc_http_response_send_before',\n                    array('response' => $response)\n                );\n                $response->sendResponse();\n                exit;\n            }\n            if (Mage::getStoreConfig(self::SHOW_AGE_XML_PATH)) {\n                Mage::app()->getResponse()->setHeader('Age', 0);\n            }\n        }\n    }\n\n    /**\n     * @param $observer\n     */\n    public function httpResponseSendBefore($observer)\n    {\n        $response = $observer->getEvent()->getResponse();\n        if ($this->_getFpc()->isActive() &&\n            !$this->_cached &&\n            Mage::helper('fpc')->canCacheRequest() &&\n            $response->getHttpResponseCode() == 200) {\n            $fullActionName = Mage::helper('fpc')->getFullActionName();\n            $cacheableActions = Mage::helper('fpc')->getCacheableActions();\n            if (in_array($fullActionName, $cacheableActions)) {\n                $key = Mage::helper('fpc')->getKey();\n                $body = $observer->getEvent()->getResponse()->getBody();\n                $session = Mage::getSingleton('core/session');\n                $formKey = $session->getFormKey();\n                if ($formKey) {\n                    $body = str_replace(\n                        $formKey,\n                        self::FORM_KEY_PLACEHOLDER,\n                        $body\n                    );\n                    $this->_placeholder[] = self::FORM_KEY_PLACEHOLDER;\n                    $this->_html[] = $formKey;\n                }\n                $sid = $session->getEncryptedSessionId();\n                if ($sid) {\n                    $body = str_replace(\n                        $sid,\n                        self::SESSION_ID_PLACEHOLDER,\n                        $body\n                    );\n                    $this->_placeholder[] = self::SESSION_ID_PLACEHOLDER;\n                    $this->_html[] = $sid;\n                }\n                // edit cacheTags via event\n                $cacheTags = new Varien_Object();\n                $cacheTags->setValue($this->_cacheTags);\n                Mage::dispatchEvent(\n                    'fpc_observer_collect_cache_tags',\n                    array('cache_tags' => $cacheTags)\n                );\n                $this->_cacheTags = $cacheTags->getValue();\n                $this->_getFpc()->save(\n                    new Lesti_Fpc_Model_Fpc_CacheItem($body, time(), Mage::helper('fpc')->getContentType($response)),\n                    $key,\n                    $this->_cacheTags\n                );\n                $this->_cached = true;\n                $body = str_replace($this->_placeholder, $this->_html, $body);\n                $observer->getEvent()->getResponse()->setBody($body);\n            }\n        }\n    }\n\n    /**\n     * @param $observer\n     */\n    public function coreBlockAbstractToHtmlAfter($observer)\n    {\n        if ($this->_getFpc()->isActive() &&\n            !$this->_cached &&\n            Mage::helper('fpc')->canCacheRequest()) {\n            $fullActionName = Mage::helper('fpc')->getFullActionName();\n            $block = $observer->getEvent()->getBlock();\n            $blockName = $block->getNameInLayout();\n            $dynamicBlocks = Mage::helper('fpc/block')->getDynamicBlocks();\n            $lazyBlocks = Mage::helper('fpc/block')->getLazyBlocks();\n            $dynamicBlocks = array_merge($dynamicBlocks, $lazyBlocks);\n            $cacheableActions = Mage::helper('fpc')->getCacheableActions();\n            if (in_array($fullActionName, $cacheableActions)) {\n                $this->_cacheTags = array_merge(\n                    Mage::helper('fpc/block')->getCacheTags($block),\n                    $this->_cacheTags\n                );\n                if (in_array($blockName, $dynamicBlocks)) {\n                    $placeholder = Mage::helper('fpc/block')\n                        ->getPlaceholderHtml($blockName);\n                    $html = $observer->getTransport()->getHtml();\n                    $this->_html[] = $html;\n                    $this->_placeholder[] = $placeholder;\n                    $observer->getTransport()->setHtml($placeholder);\n                }\n            }\n        }\n    }\n\n    public function controllerActionPostdispatch()\n    {\n        if ($this->_getFpc()->isActive()) {\n            $fullActionName = Mage::helper('fpc')->getFullActionName();\n            if (in_array(\n                $fullActionName,\n                Mage::helper('fpc')->getRefreshActions()\n            )) {\n                $session = Mage::getSingleton('customer/session');\n                $session->setData(\n                    Lesti_Fpc_Helper_Block::LAZY_BLOCKS_VALID_SESSION_PARAM,\n                    false\n                );\n            }\n        }\n    }\n\n    /**\n     * @return Lesti_Fpc_Model_Fpc\n     */\n    protected function _getFpc()\n    {\n        return Mage::getSingleton('fpc/fpc');\n    }\n\n    /**\n     * @param Mage_Core_Model_Layout $layout\n     * @param array $dynamicBlocks\n     * @return Mage_Core_Model_Layout\n     */\n    protected function _prepareLayout(\n        Mage_Core_Model_Layout $layout,\n        array $dynamicBlocks\n    )\n    {\n        $xml = $layout->getNode();\n        $cleanXml = simplexml_load_string(\n            '<layout/>',\n            Lesti_Fpc_Helper_Data::LAYOUT_ELEMENT_CLASS\n        );\n        $types = array('block', 'reference', 'action');\n        foreach ($dynamicBlocks as $blockName) {\n            foreach ($types as $type) {\n                $xPath = $xml->xpath(\n                    \"//\" . $type . \"[@name='\" . $blockName . \"']\"\n                );\n                foreach ($xPath as $child) {\n                    $cleanXml->appendChild($child);\n                }\n            }\n        }\n        $layout->setXml($cleanXml);\n        $layout->generateBlocks();\n        return Mage::helper('fpc/block_messages')\n            ->initLayoutMessages($layout);\n    }\n\n    protected function _replaceFormKey()\n    {\n        $coreSession = Mage::getSingleton('core/session');\n        $formKey = $coreSession->getFormKey();\n        if ($formKey) {\n            $this->_placeholder[] = self::FORM_KEY_PLACEHOLDER;\n            $this->_html[] = $formKey;\n        }\n    }\n\n    /**\n     * @param Mage_Core_Model_Layout $layout\n     * @param Mage_Customer_Model_Session $session\n     * @param array $dynamicBlocks\n     * @param array $lazyBlocks\n     */\n    protected function _insertDynamicBlocks(\n        Mage_Core_Model_Layout &$layout,\n        Mage_Customer_Model_Session &$session,\n        array &$dynamicBlocks,\n        array &$lazyBlocks\n    )\n    {\n        foreach ($dynamicBlocks as $blockName) {\n            $block = $layout->getBlock($blockName);\n            if ($block) {\n                $this->_placeholder[] = Mage::helper('fpc/block')\n                    ->getPlaceholderHtml($blockName);\n                $html = $block->toHtml();\n                if (in_array($blockName, $lazyBlocks)) {\n                    $session->setData('fpc_lazy_block_' . $blockName, $html);\n                }\n                $this->_html[] = $html;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax/fixtures/get_ajax_url.yaml",
    "content": "config:\n    default/system/fpc/cache_actions: catalog_product_view\n    default/system/fpc/use_recently_viewed_products: 1\n    default/web/unsecure/base_link_url: http://magento.dev/\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax/fixtures/get_ajax_url_disabled_recently_viewed_products.yaml",
    "content": "config:\n    default/system/fpc/cache_actions: catalog_product_view\n    default/system/fpc/use_recently_viewed_products: 0\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax/fixtures/get_ajax_url_fpc_inactive.yaml",
    "content": "config:\n    default/system/fpc/cache_actions: catalog_product_view\n    default/system/fpc/use_recently_viewed_products: 1\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax/fixtures/get_ajax_url_miss_cache_able_action.yaml",
    "content": "config:\n    default/system/fpc/cache_actions:\n    default/system/fpc/use_recently_viewed_products: 1\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax/fixtures/get_ajax_url_no_current_product.yaml",
    "content": "config:\n    default/system/fpc/cache_actions: catalog_product_view\n    default/system/fpc/use_recently_viewed_products: 1\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Test_Block_Catalog_Product_View_Ajax\n */\nclass Lesti_Fpc_Test_Block_Catalog_Product_View_Ajax extends\n    Lesti_Fpc_Test_TestCase\n{\n    /**\n     * @var Lesti_Fpc_Block_Catalog_Product_View_Ajax\n     */\n    protected $_catalogProductViewAjaxBlock;\n\n    protected function setUp()\n    {\n        parent::setUp();\n        $this->_catalogProductViewAjaxBlock =\n            new Lesti_Fpc_Block_Catalog_Product_View_Ajax();\n        // register a product\n        $product = new Mage_Catalog_Model_Product();\n        $product->setId(5);\n        Mage::register('current_product', $product);\n    }\n\n    protected function tearDown()\n    {\n        parent::tearDown();\n        Mage::unregister('current_product');\n    }\n\n    /**\n     * @test\n     * @loadFixture get_ajax_url_fpc_inactive.yaml\n     */\n    public function testGetAjaxUrlFpcInactive()\n    {\n        Mage::app()->getCacheInstance()->banUse('fpc');\n        $this->assertFalse($this->_catalogProductViewAjaxBlock->getAjaxUrl());\n    }\n\n    /**\n     * @test\n     * @loadFixture get_ajax_url_miss_cache_able_action.yaml\n     */\n    public function testGetAjaxUrlMissCacheAbleAction()\n    {\n        $this->assertFalse($this->_catalogProductViewAjaxBlock->getAjaxUrl());\n    }\n\n    /**\n     * @test\n     * @loadFixture get_ajax_url_disabled_recently_viewed_products.yaml\n     */\n    public function testGetAjaxUrlDisabledRecentlyViewedProducts()\n    {\n        $this->assertFalse($this->_catalogProductViewAjaxBlock->getAjaxUrl());\n    }\n\n    /**\n     * @test\n     * @loadFixture get_ajax_url_no_current_product.yaml\n     */\n    public function testGetAjaxUrlNoCurrentProduct()\n    {\n        Mage::unregister('current_product');\n        $this->assertFalse($this->_catalogProductViewAjaxBlock->getAjaxUrl());\n    }\n\n    /**\n     * @test\n     * @loadFixture get_ajax_url.yaml\n     */\n    public function testGetAjaxUrl()\n    {\n        // clean baseUrlCache of Model/Store\n        $this->clearBaseUrlProperty();\n        $session = Mage::getSingleton('core/session');\n        $sid = $session->getEncryptedSessionId();\n        $expectedUrl = 'http://magento.dev/fpc/catalog_product/view/id/5/';\n        if ($sid) {\n            $expectedUrl .= '?'.$session->getSessionIdQueryParam().'='.$sid;\n        }\n\n        $this->assertEquals(\n            $expectedUrl,\n            $this->_catalogProductViewAjaxBlock->getAjaxUrl()\n        );\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Block/Core/Messages.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Test_Block_Core_Messages\n */\nclass Lesti_Fpc_Test_Block_Core_Messages extends Lesti_Fpc_Test_TestCase\n{\n    /**\n     * @var Lesti_Fpc_Core_Block_Messages\n     */\n    protected $_messagesBlock;\n\n    protected function setUp()\n    {\n        parent::setUp();\n        $this->_messagesBlock = Mage::app()->getLayout()\n            ->createBlock('core/messages');\n    }\n\n    /**\n     * @test\n     */\n    public function testGetGroupedHtml()\n    {\n        $this->assertInstanceOf(\n            'Lesti_Fpc_Core_Block_Messages',\n            $this->_messagesBlock\n        );\n        $parentClass = get_parent_class($this->_messagesBlock);\n        /** @var Mage_Core_Block_Messages $coreMessagesBlock */\n        $coreMessagesBlock = new $parentClass;\n        $this->assertInstanceOf(\n            'Mage_Core_Block_Messages',\n            $coreMessagesBlock\n        );\n        $expectedGroupHtml = $coreMessagesBlock->getGroupedHtml();\n        $this->assertEquals(\n            $expectedGroupHtml,\n            $this->_messagesBlock->getGroupedHtml()\n        );\n        $this->assertEventDispatched(\n            'core_block_messages_get_grouped_html_after'\n        );\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Controller/Catalog/ProductController/fixtures/view_action_with_product.yaml",
    "content": "tables:\n  eav_attribute_set:\n    - attribute_set_id: 13\n      entity_type_id: 4\n  catalog_product_entity:\n    - entity_id: 5\n      entity_type_id: 4\n      attribute_set_id: 13\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Controller/Catalog/ProductController.php",
    "content": "<?php\n/**\n * Created by JetBrains PhpStorm.\n * User: gordon\n * Date: 10/19/14\n * Time: 1:56 PM\n * To change this template use File | Settings | File Templates.\n */\n\n/**\n * Class Lesti_Fpc_Test_Controller_Catalog_ProductController\n */\nclass Lesti_Fpc_Test_Controller_Catalog_ProductController extends\n    Lesti_Fpc_Test_TestCase\n{\n    /**\n     * @test\n     */\n    public function testViewActionWithoutProduct()\n    {\n        $this->dispatch('fpc/catalog_product/view');\n        $this->assertEventNotDispatched('catalog_controller_product_view');\n    }\n\n    /**\n     * @test\n     * @loadFixture view_action_with_product.yaml\n     */\n    public function testViewActionWithProduct()\n    {\n        Mage::app()->getRequest()->setParam('id', 5);\n        $this->dispatch('fpc/catalog_product/view');\n        $this->assertEventDispatched('catalog_controller_product_view');\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Block/Messages.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Test_Helper_Block_Messages\n */\nclass Lesti_Fpc_Test_Helper_Block_Messages extends Lesti_Fpc_Test_TestCase\n{\n    /**\n     * @var Lesti_Fpc_Helper_Block_Messages\n     */\n    protected $_messagesHelper;\n\n    protected function setUp()\n    {\n        parent::setUp();\n        $this->_messagesHelper = Mage::helper('fpc/block_messages');\n    }\n\n    /**\n     * @test\n     */\n    public function testInitLayoutMessagesEmpty()\n    {\n        $layout = Mage::app()->getLayout();\n        $this->_messagesHelper->initLayoutMessages($layout);\n        $this->assertEmpty($layout->getMessagesBlock()->getMessages());\n    }\n\n    /**\n     * @test\n     */\n    public function testInitLayoutMessagesCatalog()\n    {\n        $layout = Mage::app()->getLayout();\n        /** @var Mage_Catalog_Model_Session $catalogStorage */\n        $catalogStorage = Mage::getSingleton('catalog/session');\n        $catalogStorage->addSuccess('Fpc is cool.');\n        $catalogStorage->addError('Fpc has no errors.');\n        $this->assertInstanceOf(\n            'Mage_Core_Model_Layout',\n            $this->_messagesHelper->initLayoutMessages($layout)\n        );\n\n        // test if session is now empty\n        $this->assertEquals(0, $catalogStorage->getMessages()->count());\n        $messages = $layout->getMessagesBlock()->getMessages();\n        $this->assertCount(2, $messages);\n    }\n\n    /**\n     * @test\n     */\n    public function testInitLayoutMessagesTag()\n    {\n        $layout = Mage::app()->getLayout();\n        /** @var Mage_Tag_Model_Session $tagStorage */\n        $tagStorage = Mage::getSingleton('tag/session');\n        $tagStorage->addSuccess('Fpc is cool.');\n        $tagStorage->addError('Fpc has no errors.');\n        $this->assertInstanceOf(\n            'Mage_Core_Model_Layout',\n            $this->_messagesHelper->initLayoutMessages($layout)\n        );\n\n        // test if session is now empty\n        $this->assertEquals(0, $tagStorage->getMessages()->count());\n        $messages = $layout->getMessagesBlock()->getMessages();\n        $this->assertCount(2, $messages);\n    }\n\n    /**\n     * @test\n     */\n    public function testInitLayoutMessagesCheckout()\n    {\n        $layout = Mage::app()->getLayout();\n        /** @var Mage_Checkout_Model_Session $checkoutStorage */\n        $checkoutStorage = Mage::getSingleton('checkout/session');\n        $checkoutStorage->addSuccess('Fpc is cool.');\n        $checkoutStorage->addError('Fpc has no errors.');\n        $this->assertInstanceOf(\n            'Mage_Core_Model_Layout',\n            $this->_messagesHelper->initLayoutMessages($layout)\n        );\n\n        // test if session is now empty\n        $this->assertEquals(0, $checkoutStorage->getMessages()->count());\n        $messages = $layout->getMessagesBlock()->getMessages();\n        $this->assertCount(2, $messages);\n    }\n\n    /**\n     * @test\n     */\n    public function testInitLayoutMessagesCustomer()\n    {\n        $layout = Mage::app()->getLayout();\n        /** @var Mage_Customer_Model_Session $customerStorage */\n        $customerStorage = Mage::getSingleton('customer/session');\n        $customerStorage->addSuccess('Fpc is cool.');\n        $customerStorage->addError('Fpc has no errors.');\n        $this->assertInstanceOf(\n            'Mage_Core_Model_Layout',\n            $this->_messagesHelper->initLayoutMessages($layout)\n        );\n\n        // test if session is now empty\n        $this->assertEquals(0, $customerStorage->getMessages()->count());\n        $messages = $layout->getMessagesBlock()->getMessages();\n        $this->assertCount(2, $messages);\n    }\n\n    /**\n     * @test\n     * @expectedException Mage_Core_exception\n     * @expectedExceptionMessage Invalid messages storage \"fpc/session\"\n     * for layout messages initialization\n     */\n    public function testInitLayoutInvalidStorage()\n    {\n        $layout = Mage::app()->getLayout();\n        $this->_messagesHelper\n            ->initLayoutMessages($layout, array('fpc/session'));\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/are_lazy_blocks_valid.yaml",
    "content": "tables:\n  customer_entity:\n    - entity_id: 1\n    - group_id: 78\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/get_dynamic_blocks.yaml",
    "content": "config:\n    default/system/fpc/dynamic_blocks: >\n     messages,\n     global_messages, global_notices\n      , global_messages\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/get_dynamic_blocks_empty.yaml",
    "content": "config:\n    default/system/fpc/dynamic_blocks: \" \"\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/get_lazy_blocks.yaml",
    "content": "config:\n    default/system/fpc/lazy_blocks: >\n     top.links,\n     cart_sidebar, catalog.compare.sidebar\n      , cart_sidebar\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/get_lazy_blocks_empty.yaml",
    "content": "config:\n    default/system/fpc/lazy_blocks: \" \"\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/use_recently_viewed_products_false.yaml",
    "content": "config:\n    default/system/fpc/use_recently_viewed_products: 0"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/use_recently_viewed_products_true.yaml",
    "content": "config:\n    default/system/fpc/use_recently_viewed_products: 1"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Block.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Test_Helper_Block\n *\n * @SuppressWarnings(PHPMD.TooManyPublicMethods)\n */\nclass Lesti_Fpc_Test_Helper_Block extends Lesti_Fpc_Test_TestCase\n{\n    /**\n     * @var Lesti_Fpc_Helper_Block\n     */\n    protected $_blockHelper;\n\n    protected function setUp()\n    {\n        parent::setUp();\n        $this->_blockHelper = Mage::helper('fpc/block');\n    }\n\n    /**\n     * @test\n     * @loadFixture get_dynamic_blocks.yaml\n     */\n    public function testGetDynamicBlocks()\n    {\n        $this->assertEquals(\n            array('messages', 'global_messages', 'global_notices'),\n            $this->_blockHelper->getDynamicBlocks()\n        );\n    }\n\n    /**\n     * @test\n     * @loadFixture get_dynamic_blocks_empty.yaml\n     */\n    public function testGetDynamicBlocksEmpty()\n    {\n        $this->assertEquals(array(), $this->_blockHelper->getDynamicBlocks());\n    }\n\n    /**\n     * @test\n     * @loadFixture get_lazy_blocks.yaml\n     */\n    public function testGetLazyBlocks()\n    {\n        $this->assertEquals(\n            array('top.links', 'cart_sidebar', 'catalog.compare.sidebar'),\n            $this->_blockHelper->getLazyBlocks()\n        );\n    }\n\n    /**\n     * @test\n     * @loadFixture get_lazy_blocks_empty.yaml\n     */\n    public function testGetLazyBlocksEmpty()\n    {\n        $this->assertEquals(array(), $this->_blockHelper->getLazyBlocks());\n    }\n\n    /**\n     * @test\n     * @loadFixture are_lazy_blocks_valid.yaml\n     */\n    public function testAreLazyBlocksValid()\n    {\n        // initial should return false\n        $this->assertFalse($this->_blockHelper->areLazyBlocksValid());\n        // hash should be set and return true\n        $this->assertTrue($this->_blockHelper->areLazyBlocksValid());\n\n        // edit host\n        $_SERVER['HTTP_HOST'] = 'fpc.dev';\n        $this->assertFalse($this->_blockHelper->areLazyBlocksValid());\n        $this->assertTrue($this->_blockHelper->areLazyBlocksValid());\n\n        // edit port\n        $_SERVER['SERVER_PORT'] = '80';\n        $this->assertFalse($this->_blockHelper->areLazyBlocksValid());\n        $this->assertTrue($this->_blockHelper->areLazyBlocksValid());\n\n        // edit store code\n        $storeCode = Mage::app()->getStore()->getCode();\n        Mage::app()->getStore()->setCode('fpc');\n        $this->assertFalse($this->_blockHelper->areLazyBlocksValid());\n        $this->assertTrue($this->_blockHelper->areLazyBlocksValid());\n        Mage::app()->getStore()->setCode($storeCode);\n\n        // edit currency\n        Mage::app()->getStore()->setCurrentCurrencyCode('FPC');\n        $this->assertFalse($this->_blockHelper->areLazyBlocksValid());\n        $this->assertTrue($this->_blockHelper->areLazyBlocksValid());\n\n        // edit customer session\n        /** @var Mage_Customer_Model_Session $customerSession */\n        $customerSession = Mage::getSingleton('customer/session');\n        if (version_compare(Mage::getVersion(), '1.6.0.0', '<')) {\n            $customer = Mage::getModel('customer/customer')->load(1);\n            $customerSession->setCustomerAsLoggedIn($customer);\n        } else {\n            $customerSession->setCustomerGroupId(78);\n        }\n        $this->assertFalse($this->_blockHelper->areLazyBlocksValid());\n        $this->assertTrue($this->_blockHelper->areLazyBlocksValid());\n\n        // edit design package name\n        Mage::getDesign()->setPackageName('base');\n        $this->assertFalse($this->_blockHelper->areLazyBlocksValid());\n        $this->assertTrue($this->_blockHelper->areLazyBlocksValid());\n\n        // edit design theme\n        Mage::getDesign()->setTheme('template', 'FPC');\n        $this->assertFalse($this->_blockHelper->areLazyBlocksValid());\n        $this->assertTrue($this->_blockHelper->areLazyBlocksValid());\n    }\n\n    /**\n     * @test\n     */\n    public function testGetPlaceholderHtml()\n    {\n        $this->assertEquals(\n            '<!-- fpc 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 -->',\n            $this->_blockHelper->getPlaceholderHtml('foo')\n        );\n    }\n\n    /**\n     * @test\n     */\n    public function testGetKey()\n    {\n        $this->assertEquals(\n            '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33_block',\n            $this->_blockHelper->getKey('foo')\n        );\n    }\n\n    /**\n     * @test\n     * @loadFixture use_recently_viewed_products_true.yaml\n     */\n    public function testUseRecentlyViewedProductsTrue()\n    {\n        $this->assertTrue($this->_blockHelper->useRecentlyViewedProducts());\n    }\n\n    /**\n     * @test\n     * @loadFixture use_recently_viewed_products_false.yaml\n     */\n    public function testUseRecentlyViewedProductsFalse()\n    {\n        $this->assertFalse($this->_blockHelper->useRecentlyViewedProducts());\n    }\n\n    /**\n     * @test\n     */\n    public function testGetCacheTagsEmpty()\n    {\n        $block = new Mage_Core_Block_Template();\n        $block->setNameInLayout('foo');\n        $this->assertEquals(array(), $this->_blockHelper->getCacheTags($block));\n    }\n\n    /**\n     * @test\n     */\n    public function testGetCacheTagsProductList()\n    {\n        $productOne = new Mage_Catalog_Model_Product();\n        $productOne->setId(1);\n        $productTwo = new Mage_Catalog_Model_Product();\n        $productTwo->setId(2);\n        $block = new Mage_Core_Block_Template();\n        $block->setNameInLayout('product_list');\n        $block->setLoadedProductCollection(array($productOne, $productTwo));\n        $this->assertEquals(\n            array(\n                '38a007151abe87cc01a5b6e9cc418e85286e2087', // sha1('product')\n                '65dd4967fe508e9ebad619a8c976beabf46588fe', // sha1('product_1')\n                '499ed21cb19c984d31e23b94a60730520afa8181' // sha1('product_2')\n            ),\n            $this->_blockHelper->getCacheTags($block)\n        );\n    }\n\n    /**\n     * @test\n     */\n    public function testGetCacheTagsCmsBlock()\n    {\n        $block = new Mage_Cms_Block_Block();\n        $block->setNameInLayout('foo');\n        $block->setId(5);\n        $this->assertEquals(\n            array(\n                '74709cfbbdffe24885db05ff5d08ea9c13663422',\n                'ba750b74090c01fda30a383d301af7e15b340928'\n            ),\n            $this->_blockHelper->getCacheTags($block)\n        );\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/can_cache_request.yaml",
    "content": "config:\n    default/system/fpc/miss_uri_params: >\n     no_cache=/^1$/,\n     limit=/^([0-9]+)|(all)$/, dir=/^[0-9a-z_]+$/\n      , limit=/^([0-9]+)|(all)$/,\n     order\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/get_bypass_handles.yaml",
    "content": "config:\n    default/system/fpc/bypass_handles: >\n     some_handle,\n     logged_in, CATEGORY_25\n      , some_handle\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/get_bypass_handles_empty.yaml",
    "content": "config:\n    default/system/fpc/bypass_handles: \" \"\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/get_cacheable_actions.yaml",
    "content": "config:\n    default/system/fpc/cache_actions: >\n     cms_index_index,\n     cms_page_view, catalog_product_view\n      , cms_page_view\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/get_cacheable_actions_empty.yaml",
    "content": "config:\n    default/system/fpc/cache_actions: \" \"\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/get_refresh_actions.yaml",
    "content": "config:\n    default/system/fpc/refresh_actions: >\n     checkout_cart_add,\n     checkout_cart_delete, checkout_cart_updatePost\n      , checkout_cart_delete\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/get_refresh_actions_empty.yaml",
    "content": "config:\n    default/system/fpc/refresh_actions: \" \"\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/regex_uri_params.yaml",
    "content": "config:\n    default/system/fpc/uri_params: id,/^filter_\\w+/,order"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/providers/testCanCacheRequest.yaml",
    "content": "test_post:\n  method: POST\n  expected: 0\ntest_no_cache_1:\n  method: GET\n  expected: 0\n  params:\n    no_cache: 1\ntest_limit_digit:\n  method: GET\n  expected: 0\n  params:\n    limit: 55\ntest_limit_all:\n  method: GET\n  expected: 0\n  params:\n    limit: all\ntest_success:\n  method: get\n  expected: 1\n  params:\n    no_cache: 12\n    order: 4\n    limit: Fpc\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/providers/testRegexUriParams.yaml",
    "content": "test_matched_param:\n  uri_params:\n    -\n      id: 1\n    -\n      id: 1\n      filter_1_attribute: filter_1_value_1\n    -\n      id: 1\n      filter_1_attribute: filter_1_value_2\n  expected_count: 3\ntest_not_matched_param:\n  uri_params:\n    -\n      id: 1\n    -\n      id: 1\n      no_filter_1_attribute: filter_1_value_1\n    -\n      id: 1\n      no_filter_1_attribute: filter_1_value_2\n  expected_count: 1\ntest_multiple_matched_params:\n  uri_params:\n    -\n      id: 1\n    -\n      id: 1\n      filter_1_attribute: filter_1_value_1\n    -\n      id: 1\n      filter_2_attribute: filter_2_value_1\n    -\n      id: 1\n      filter_1_attribute: filter_1_value_1\n      filter_2_attribute: filter_2_value_1\n    -\n      id: 1\n      filter_1_attribute: filter_1_value_1\n      filter_2_attribute: filter_2_value_2\n    -\n      id: 1\n      filter_1_attribute: filter_1_value_2\n      filter_2_attribute: filter_2_value_1\n    -\n      id: 1\n      filter_1_attribute: filter_1_value_2\n      filter_2_attribute: filter_2_value_2\n  expected_count: 7\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Test case for Lesti_Fpc_Helper_Data\n */\nclass Lesti_Fpc_Test_Helper_Data extends Lesti_Fpc_Test_TestCase\n{\n    /**\n     * @var Lesti_Fpc_Helper_Data\n     */\n    protected $_helper;\n\n    protected function setUp()\n    {\n        parent::setUp();\n        $this->_helper = Mage::helper('fpc');\n    }\n\n    /**\n     * @test\n     * @loadFixture get_cacheable_actions.yaml\n     */\n    public function testGetCacheableActions()\n    {\n        $this->assertEquals(\n            array('cms_index_index', 'cms_page_view', 'catalog_product_view'),\n            $this->_helper->getCacheableActions()\n        );\n    }\n\n    /**\n     * @test\n     * @loadFixture get_cacheable_actions_empty.yaml\n     */\n    public function testGetCacheableActionsEmpty()\n    {\n        $this->assertEquals(array(), $this->_helper->getCacheableActions());\n    }\n\n    /**\n     * @test\n     * @loadFixture get_bypass_handles.yaml\n     */\n    public function testGetBypassHandles()\n    {\n        $this->assertEquals(\n            array('some_handle', 'logged_in', 'CATEGORY_25'),\n            $this->_helper->getBypassHandles()\n        );\n    }\n\n    /**\n     * @test\n     * @loadFixture get_bypass_handles_empty.yaml\n     */\n    public function testGetBypassHandlesEmpty()\n    {\n        $this->assertEquals(array(), $this->_helper->getBypassHandles());\n    }\n\n    /**\n     * @test\n     * @loadFixture get_refresh_actions.yaml\n     */\n    public function testGetRefreshActions()\n    {\n        $this->assertEquals(\n            array(\n                'checkout_cart_add',\n                'checkout_cart_delete',\n                'checkout_cart_updatePost'\n            ),\n            $this->_helper->getRefreshActions()\n        );\n    }\n\n    /**\n     * @test\n     * @loadFixture get_refresh_actions_empty.yaml\n     */\n    public function testGetRefreshActionsEmpty()\n    {\n        $this->assertEquals(array(), $this->_helper->getRefreshActions());\n    }\n\n    /**\n     * Test that URI params can be matched by RegEx\n     *\n     * @test\n     * @loadFixture regex_uri_params.yaml\n     * @dataProvider dataProvider\n     */\n    public function testRegexUriParams(\n        $uriParamSets = array(),\n        $expectedCount = 0\n    )\n    {\n        $actualKeys = array();\n        foreach ($uriParamSets as $uriParams) {\n            $this->_resetParams();\n            Mage::app()->getRequest()->setParams($uriParams);\n            $actualKeys[] = $this->_helper->getKey();\n        }\n        $this->assertCount(\n            $expectedCount,\n            array_unique($actualKeys),\n            sprintf('%d different keys expected', $expectedCount)\n        );\n    }\n\n    /**\n     * @test\n     * @loadFixture can_cache_request.yaml\n     * @dataProvider dataProvider\n     */\n    public function testCanCacheRequest($method, $expected, $params = array())\n    {\n        Mage::app()->getRequest()->clearParams();\n        Mage::app()->getRequest()->setMethod($method);\n        Mage::app()->getRequest()->setParams($params);\n        $this->assertEquals(\n            (bool) $expected,\n            $this->_helper->canCacheRequest()\n        );\n    }\n\n    /**\n     * @test\n     */\n    public function getFullActionName()\n    {\n        Mage::app()->getRequest()->setRouteName('f');\n        Mage::app()->getRequest()->setControllerName('p');\n        Mage::app()->getRequest()->setActionName('c');\n        $this->assertEquals('f_p_c', $this->_helper->getFullActionName());\n    }\n\n    /**\n     * Reset parameters in Magento request and FPC\n     */\n    protected function _resetParams()\n    {\n        if (Mage::registry(Lesti_Fpc_Helper_Data::REGISTRY_KEY_PARAMS)) {\n            Mage::unregister(Lesti_Fpc_Helper_Data::REGISTRY_KEY_PARAMS);\n        }\n        Mage::app()->getRequest()->clearParams();\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Fpc/fixtures/save_load_clean.yaml",
    "content": "config:\n    default/system/fpc/gzcompress_level: 3"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Fpc.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Test_Model_Fpc\n */\nclass Lesti_Fpc_Test_Model_Fpc extends Lesti_Fpc_Test_TestCase\n{\n    /**\n     * @var Lesti_Fpc_Model_Fpc\n     */\n    protected $_fpc;\n\n    protected function setUp()\n    {\n        parent::setUp();\n        $this->_fpc = Mage::getSingleton('fpc/fpc');\n    }\n\n    /**\n     * @test\n     * @loadFixture save_load_clean.yaml\n     */\n    public function saveLoadClean()\n    {\n        $data = new \\Lesti_Fpc_Model_Fpc_CacheItem('fpc_data', time(), 'text/html');\n        $id = 'fpc_id';\n        $tag = 'tag1';\n\n        // check if tag tag1 (clean without array)\n        $this->_fpc->save($data, $id, array($tag));\n        $this->assertEquals($data, $this->_fpc->load($id));\n        $this->_fpc->clean($tag);\n        $this->assertFalse($this->_fpc->load($id));\n\n        // check global tag FPC (clean with array)\n        $this->_fpc->save($data, $id, array($tag));\n        $this->assertEquals($data, $this->_fpc->load($id));\n        $this->_fpc->clean(array(Lesti_Fpc_Model_Fpc::CACHE_TAG));\n        $this->assertFalse($this->_fpc->load($id));\n\n        // (global clean)\n        $this->_fpc->save($data, $id, array($tag));\n        $this->assertEquals($data, $this->_fpc->load($id));\n        $this->_fpc->clean();\n        $this->assertFalse($this->_fpc->load($id));\n\n        // check timeout\n        $this->_fpc->save($data, $id, array($tag), 2);\n        $this->assertEquals($data, $this->_fpc->load($id));\n        sleep(3);\n        $this->assertFalse($this->_fpc->load($id));\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Clean.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Test_Model_Observer_Clean\n */\nclass Lesti_Fpc_Test_Model_Observer_Clean extends Lesti_Fpc_Test_TestCase\n{\n    /**\n     * @var Lesti_Fpc_Model_Observer_Clean\n     */\n    protected $_cleanObserver;\n\n    protected function setUp()\n    {\n        parent::setUp();\n        $this->_cleanObserver = Mage::getSingleton('fpc/observer_clean');\n    }\n\n    protected function tearDown()\n    {\n        parent::tearDown();\n        Mage::unregister('_singleton/fpc/observer_clean');\n    }\n\n    /**\n     * @test\n     */\n    public function testCoreCleanCache()\n    {\n        $data = new \\Lesti_Fpc_Model_Fpc_CacheItem('fpc_old_data', time(), 'text/html');\n        $this->_fpc->save($data, 'fpc_old_id', array('fpc'), 1);\n        sleep(2);\n        $this->_cleanObserver->coreCleanCache();\n        $this->assertFalse($this->_fpc->remove('fpc_old_id'));\n    }\n\n    /**\n     * @test\n     */\n    public function testAdminhtmlCacheFlushAll()\n    {\n        $data = new \\Lesti_Fpc_Model_Fpc_CacheItem('fpc_old_data', time(), 'text/html');\n        $this->_fpc->save($data, 'fpc_id');\n        Mage::dispatchEvent('adminhtml_cache_flush_all');\n        $this->assertFalse($this->_fpc->remove('fpc_id'));\n    }\n\n    /**\n     * @test\n     */\n    public function testControllerActionPredispatchAdminhtmlCacheMassRefresh()\n    {\n        $data = new \\Lesti_Fpc_Model_Fpc_CacheItem('test_data', time(), 'text/html');\n        $this->_fpc->save($data, 'test_id');\n        Mage::app()->getRequest()->setParam('types', array('core'));\n        $this->_cleanObserver->\n            controllerActionPredispatchAdminhtmlCacheMassRefresh();\n        $this->assertEquals($data, $this->_fpc->load('test_id'));\n\n        $this->_fpc->clean();\n        $this->_fpc->save($data, 'test_id');\n        Mage::app()->getRequest()->setParam(\n            'types',\n            array('core', Lesti_Fpc_Model_Observer_Clean::CACHE_TYPE)\n        );\n        $this->_cleanObserver->\n            controllerActionPredispatchAdminhtmlCacheMassRefresh();\n        $this->assertFalse($this->_fpc->load('test_id'));\n\n        $this->_fpc->clean();\n        $this->_fpc->save($data, 'test_id');\n        Mage::app()->getRequest()->setParam(\n            'types',\n            array('core', Lesti_Fpc_Model_Observer_Clean::CACHE_TYPE)\n        );\n        Mage::app()->getCacheInstance()->banUse('fpc');\n        $this->_cleanObserver->\n            controllerActionPredispatchAdminhtmlCacheMassRefresh();\n        $this->assertEquals($data, $this->_fpc->load('test_id'));\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Parameters/fixtures/fpc_helper_collect_params.yaml",
    "content": "config:\n  default/system/fpc/session_params: >\n    magento,\n    fpc\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Parameters.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Test_Model_Observer_Parameters\n */\nclass Lesti_Fpc_Test_Model_Observer_Parameters extends Lesti_Fpc_Test_TestCase\n{\n    /**\n     * @test\n     * @loadFixture fpc_helper_collect_params.yaml\n     */\n    public function testFpcHelperCollectParams()\n    {\n        Mage::app()->getRequest()->setRouteName('catalog');\n        Mage::app()->getRequest()->setControllerName('category');\n        Mage::app()->getRequest()->setActionName('view');\n\n        /** @var Mage_Catalog_Model_Session $catalogSession */\n        $catalogSession = Mage::getSingleton('catalog/session');\n        $catalogSession->setData('fpc', 'cool');\n\n        $expectedResult = array(\n            'fpc' => 'cool',\n            'store' => Mage::app()->getStore(true)->getCode(),\n            'currency' => Mage::app()->getStore()->getCurrentCurrencyCode(),\n            'design' => Mage::getDesign()->getPackageName().'_'.\n                Mage::getDesign()->getTheme('template'),\n            'session_fpc' => 'cool',\n        );\n        $params = array('fpc' => 'cool');\n        $object = new Varien_Object();\n        $object->setValue($params);\n        Mage::dispatchEvent(\n            'fpc_helper_collect_params',\n            array('parameters' => $object)\n        );\n        $this->assertEquals($expectedResult, $object->getValue());\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Save.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Test_Model_Observer_Save\n */\nclass Lesti_Fpc_Test_Model_Observer_Save extends Lesti_Fpc_Test_TestCase\n{\n    /**\n     * @test\n     */\n    public function testCalaogProductSaveAfter()\n    {\n        $product1Data = new \\Lesti_Fpc_Model_Fpc_CacheItem('product1', time(), 'text/html');\n        $this->_fpc->save(\n            $product1Data,\n            'product1_cache_id',\n            array(sha1('product_1'))\n        );\n        $category1Data = new \\Lesti_Fpc_Model_Fpc_CacheItem('category1', time(), 'text/html');\n        $this->_fpc->save(\n            $category1Data,\n            'category1_cache_id',\n            array(sha1('category_1'))\n        );\n        $category2Data = new \\Lesti_Fpc_Model_Fpc_CacheItem('category2', time(), 'text/html');\n        $this->_fpc->save(\n            $category2Data,\n            'category2_cache_id',\n            array(sha1('category_2'))\n        );\n\n        $product = new Mage_Catalog_Model_Product();\n        $product->setOrigData(array());\n        $product->setCategoryIds(array(1));\n        $product->setId(1);\n        Mage::dispatchEvent(\n            'catalog_product_save_after',\n            array('product' => $product)\n        );\n\n        $this->assertFalse($this->_fpc->load('product1_cache_id'));\n        $this->assertFalse($this->_fpc->load('category1_cache_id'));\n        $this->assertEquals(\n            $category2Data,\n            $this->_fpc->load('category2_cache_id')\n        );\n    }\n\n    /**\n     * @test\n     */\n    public function testCatalogCategorySaveAfter()\n    {\n        $category1Data = new \\Lesti_Fpc_Model_Fpc_CacheItem('category1', time(), 'text/html');\n        $this->_fpc->save(\n            $category1Data,\n            'category1_cache_id',\n            array(sha1('category_1'))\n        );\n        $category2Data = new \\Lesti_Fpc_Model_Fpc_CacheItem('category2', time(), 'text/html');\n        $this->_fpc->save(\n            $category2Data,\n            'category2_cache_id',\n            array(sha1('category_2'))\n        );\n\n        $category = new Mage_Catalog_Model_Category();\n        $category->setId(1);\n        Mage::dispatchEvent(\n            'catalog_category_save_after',\n            array('category' => $category)\n        );\n\n        $this->assertFalse($this->_fpc->load('category1_cache_id'));\n        $this->assertEquals(\n            $category2Data,\n            $this->_fpc->load('category2_cache_id')\n        );\n    }\n\n    /**\n     * @test\n     */\n    public function testCmsPageSaveAfter()\n    {\n        $page1Data = new \\Lesti_Fpc_Model_Fpc_CacheItem('page1', time(), 'text/html');\n        $this->_fpc->save($page1Data, 'page1_cache_id', array(sha1('cms_1')));\n        $page2Data = new \\Lesti_Fpc_Model_Fpc_CacheItem('page2', time(), 'text/html');\n        $this->_fpc->save($page2Data, 'page2_cache_id', array(sha1('cms_2')));\n        $page3Data = new \\Lesti_Fpc_Model_Fpc_CacheItem('page3', time(), 'text/html');\n        $this->_fpc->save($page3Data, 'page3_cache_id', array(sha1('cms_3')));\n\n        $page = new Mage_Cms_Model_Page();\n        $page->setId(1);\n        $page->setIdentifier('3');\n        Mage::dispatchEvent('cms_page_save_after', array('object' => $page));\n\n        $this->assertFalse($this->_fpc->load('page1_cache_id'));\n        $this->assertFalse($this->_fpc->load('page3_cache_id'));\n        $this->assertEquals($page2Data, $this->_fpc->load('page2_cache_id'));\n    }\n\n    /**\n     * @test\n     */\n    public function testCmsBlockSaveAfter()\n    {\n        $page1Data = new \\Lesti_Fpc_Model_Fpc_CacheItem('page1', time(), 'text/html');\n        $this->_fpc->save(\n            $page1Data,\n            'page1_cache_id',\n            array(sha1('cmsblock_1'))\n        );\n        $page2Data = new \\Lesti_Fpc_Model_Fpc_CacheItem('page2', time(), 'text/html');\n        $this->_fpc->save(\n            $page2Data,\n            'page2_cache_id',\n            array(sha1('cmsblock_2'))\n        );\n\n        $cmsBlock = new Mage_Cms_Model_Block();\n        $cmsBlock->setIdentifier('1');\n        Mage::dispatchEvent('model_save_after', array('object' => $cmsBlock));\n\n        $this->assertFalse($this->_fpc->load('page1_cache_id'));\n        $this->assertEquals($page2Data, $this->_fpc->load('page2_cache_id'));\n    }\n\n    /**\n     * @test\n     */\n    public function testCatalogProductSaveAfterMassAction()\n    {\n        $product1Data = new \\Lesti_Fpc_Model_Fpc_CacheItem('product1', time(), 'text/html');\n        $this->_fpc->save(\n            $product1Data,\n            'product1_cache_id',\n            array(sha1('product_1'))\n        );\n        $product2Data = new \\Lesti_Fpc_Model_Fpc_CacheItem('product2', time(), 'text/html');\n        $this->_fpc->save(\n            $product2Data,\n            'product2_cache_id',\n            array(sha1('product_2'))\n        );\n        $product3Data = new \\Lesti_Fpc_Model_Fpc_CacheItem('product3', time(), 'text/html');\n        $this->_fpc->save(\n            $product3Data,\n            'product3_cache_id',\n            array(sha1('product_3'))\n        );\n\n        $event = new Mage_Index_Model_Event();\n        $productAction = new Mage_Catalog_Model_Product_Action();\n        $productAction->setProductIds(array(2, 3));\n        $event->setType('mass_action');\n        $event->setEntity('catalog_product');\n        $event->setDataObject($productAction);\n        Mage::dispatchEvent('model_save_after', array('object' => $event));\n\n        $this->assertEquals($product1Data, $this->_fpc->load('product1_cache_id'));\n        $this->assertFalse($this->_fpc->load('product2_cache_id'));\n        $this->assertFalse($this->_fpc->load('product3_cache_id'));\n    }\n\n    /**\n     * @test\n     */\n    public function testCataloginventoryStockItemSaveAfter()\n    {\n        $product1Data = new \\Lesti_Fpc_Model_Fpc_CacheItem('product1', time(), 'text/html');\n        $this->_fpc->save(\n            $product1Data,\n            'product1_cache_id',\n            array(sha1('product_1'))\n        );\n        $product2Data = new \\Lesti_Fpc_Model_Fpc_CacheItem('product2', time(), 'text/html');\n        $this->_fpc->save(\n            $product2Data,\n            'product2_cache_id',\n            array(sha1('product_2'))\n        );\n\n        $item = new Mage_CatalogInventory_Model_Stock_Item();\n        $item->setStockStatusChangedAuto(true);\n        $item->setProductId(1);\n        Mage::dispatchEvent(\n            'cataloginventory_stock_item_save_after',\n            array('item' => $item)\n        );\n\n        $this->assertFalse($this->_fpc->load('product1_cache_id'));\n        $this->assertEquals(\n            $product2Data,\n            $this->_fpc->load('product2_cache_id')\n        );\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Tags/fixtures/fpc_observer_collect_cache_tags.yaml",
    "content": "config:\n    default/web/default/cms_home_page: 5\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Tags/fixtures/get_catalog_product_view_cache_tags_configurable_prod.yaml",
    "content": "tables:\n  eav_attribute_set:\n    - attribute_set_id: 13\n      entity_type_id: 4\n  catalog_product_entity:\n    - entity_id: 5\n      entity_type_id: 4\n      attribute_set_id: 13\n    - entity_id: 6\n      entity_type_id: 4\n      attribute_set_id: 13\n  catalog_product_super_link:\n    - product_id: 5\n      parent_id: 6\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Tags/fixtures/get_catalog_product_view_cache_tags_grouped_product.yaml",
    "content": "tables:\n  eav_attribute_set:\n    - attribute_set_id: 13\n      entity_type_id: 4\n  catalog_product_entity:\n    - entity_id: 5\n      entity_type_id: 4\n      attribute_set_id: 13\n    - entity_id: 6\n      entity_type_id: 4\n      attribute_set_id: 13\n  catalog_product_link:\n    - product_id: 5\n      linked_product_id: 6\n      link_type_id: 3\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Tags/fixtures/get_cms_index_index_cache_tags.yaml",
    "content": "config:\n    default/web/default/cms_home_page: 5\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Tags/fixtures/get_cms_index_index_cache_tags_zero.yaml",
    "content": "config:\n    default/web/default/cms_home_page: 0\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Tags/providers/testFpcObserverCollectCacheTags.yaml",
    "content": "test_cms_index_index:\n  route_name: cms\n  controller_name: index\n  action_name: index\n  expected_cache_tags:\n    # sha1('cms')\n    293ae992f45cff1d17d3e83eefd2285d47f7c997\n    # sha1('cms_5')\n    133a307e26568a3c9c93e60b0e314945b91d446f\ntest_cms_page_view:\n  route_name: cms\n  controller_name: page\n  action_name: view\n  expected_cache_tags:\n    # sha1('cms')\n    293ae992f45cff1d17d3e83eefd2285d47f7c997\n    # sha1('cms_5')\n    133a307e26568a3c9c93e60b0e314945b91d446f\n  params:\n    id: 5\n\ntest_catalog_product_view:\n  route_name: catalog\n  controller_name: product\n  action_name: view\n  expected_cache_tags:\n    # sha1('product')\n    38a007151abe87cc01a5b6e9cc418e85286e2087\n    # sha1('product_5')\n    01337f5c00647634e8cef67064d9c4fd4fa0290e\n  params:\n    id: 5\ntest_catalog_category_view:\n  route_name: catalog\n  controller_name: category\n  action_name: view\n  expected_cache_tags:\n    # sha1('category')\n    5ccbf9c9c5fc1bc34df8238a97094968f38f5165\n    # sha1('category_5')\n    813322a624dfadc4b560f8ebdf2215e6a32c338c\n  params:\n    id: 5\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Tags.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Test_Model_Observer_Tags\n *\n * @SuppressWarnings(PHPMD.TooManyPublicMethods)\n */\nclass Lesti_Fpc_Test_Model_Observer_Tags extends Lesti_Fpc_Test_TestCase\n{\n    /**\n     * @test\n     * @loadFixture fpc_observer_collect_cache_tags.yaml\n     * @dataProvider dataProvider\n     */\n    public function testFpcObserverCollectCacheTags(\n        $routeName,\n        $controllerName,\n        $actionName,\n        $expectedCacheTags,\n        $params = array()\n    )\n    {\n        $this->setFullActionName($routeName, $controllerName, $actionName);\n        Mage::app()->getRequest()->setParams($params);\n\n        $tags = array('fpc_tag');\n        $cacheTags = $this->dispatchCollectTagsEvent($tags);\n        $expectedCacheTags = array_merge($tags, $expectedCacheTags);\n        $this->assertEquals($expectedCacheTags, $cacheTags);\n    }\n\n    /**\n     * @test\n     * @loadFixture get_cms_index_index_cache_tags_zero.yaml\n     */\n    public function testGetCmsIndexIndexCacheTagsZero()\n    {\n        $expectedCacheTags = array(\n            '293ae992f45cff1d17d3e83eefd2285d47f7c997', // sha1('cms')\n        );\n        $this->setFullActionName('cms', 'index', 'index');\n        $cacheTags = $this->dispatchCollectTagsEvent(array());\n        $this->assertEquals($expectedCacheTags, $cacheTags);\n    }\n\n    /**\n     * @test\n     * @loadFixture get_cms_index_index_cache_tags.yaml\n     */\n    public function testGetCmsIndexIndexCacheTags()\n    {\n        $expectedCacheTags = array(\n            '293ae992f45cff1d17d3e83eefd2285d47f7c997', // sha1('cms')\n            '133a307e26568a3c9c93e60b0e314945b91d446f', // sha1('cms_5')\n        );\n        $this->setFullActionName('cms', 'index', 'index');\n        $cacheTags = $this->dispatchCollectTagsEvent(array());\n        $this->assertEquals($expectedCacheTags, $cacheTags);\n    }\n\n    /**\n     * @test\n     */\n    public function testGetCmsPageViewCacheTagsEmpty()\n    {\n        $expectedCacheTags = array(\n            '293ae992f45cff1d17d3e83eefd2285d47f7c997', // sha1('cms')\n        );\n        $this->setFullActionName('cms', 'page', 'view');\n        $cacheTags = $this->dispatchCollectTagsEvent(array());\n        $this->assertEquals($expectedCacheTags, $cacheTags);\n    }\n\n    /**\n     * @test\n     */\n    public function testGetCmsPageViewCacheTagsPageId()\n    {\n        $expectedCacheTags = array(\n            '293ae992f45cff1d17d3e83eefd2285d47f7c997', // sha1('cms')\n            '133a307e26568a3c9c93e60b0e314945b91d446f', // sha1('cms_5')\n        );\n        $request = Mage::app()->getRequest();\n        $request->setParam('page_id', 5);\n        $this->setFullActionName('cms', 'page', 'view');\n        $cacheTags = $this->dispatchCollectTagsEvent(array());\n        $this->assertEquals($expectedCacheTags, $cacheTags);\n    }\n\n    /**\n     * @test\n     */\n    public function testGetCmsPageViewCacheTagsId()\n    {\n        $expectedCacheTags = array(\n            '293ae992f45cff1d17d3e83eefd2285d47f7c997', // sha1('cms')\n            '133a307e26568a3c9c93e60b0e314945b91d446f', // sha1('cms_5')\n        );\n        $request = Mage::app()->getRequest();\n        $request->setParam('id', 5);\n        $this->setFullActionName('cms', 'page', 'view');\n        $cacheTags = $this->dispatchCollectTagsEvent(array());\n        $this->assertEquals($expectedCacheTags, $cacheTags);\n    }\n\n    /**\n     * @test\n     */\n    public function testGetCatalogProductViewCacheTagsZero()\n    {\n        $expectedCacheTags = array(\n            '38a007151abe87cc01a5b6e9cc418e85286e2087', // sha1('product')\n        );\n        $this->setFullActionName('catalog', 'product', 'view');\n        $cacheTags = $this->dispatchCollectTagsEvent(array());\n        $this->assertEquals($expectedCacheTags, $cacheTags);\n    }\n\n    /**\n     * @test\n     */\n    public function testGetCatalogProductViewCacheTagsSimpleProduct()\n    {\n        $expectedCacheTags = array(\n            '38a007151abe87cc01a5b6e9cc418e85286e2087', // sha1('product')\n            '01337f5c00647634e8cef67064d9c4fd4fa0290e', // sha1('product_5')\n        );\n        $request = Mage::app()->getRequest();\n        $request->setParam('id', 5);\n        $this->setFullActionName('catalog', 'product', 'view');\n        $cacheTags = $this->dispatchCollectTagsEvent(array());\n        $this->assertEquals($expectedCacheTags, $cacheTags);\n    }\n\n    /**\n     * @test\n     */\n    public function testGetCatalogProductViewCacheTagsWithCategory()\n    {\n        $expectedCacheTags = array(\n            '38a007151abe87cc01a5b6e9cc418e85286e2087', // sha1('product')\n            '01337f5c00647634e8cef67064d9c4fd4fa0290e', // sha1('product_5')\n            '5ccbf9c9c5fc1bc34df8238a97094968f38f5165', // sha1('category')\n            '48ce6d1a1ef87339c758621f81e33b02f9d1cb72', // sha1('category_7')\n        );\n        $request = Mage::app()->getRequest();\n        $request->setParam('id', 5);\n        $request->setParam('category', 7);\n        $this->setFullActionName('catalog', 'product', 'view');\n        $cacheTags = $this->dispatchCollectTagsEvent(array());\n        $this->assertEquals($expectedCacheTags, $cacheTags);\n    }\n\n    /**\n     * @test\n     * @loadFixture get_catalog_product_view_cache_tags_configurable_prod.yaml\n     */\n    public function testGetCatalogProductViewCacheTagsConfigurableProduct()\n    {\n        $expectedCacheTags = array(\n            '38a007151abe87cc01a5b6e9cc418e85286e2087', // sha1('product')\n            '01337f5c00647634e8cef67064d9c4fd4fa0290e', // sha1('product_5')\n            'cfe471971355a3a3d4311e12813f7fa689cf5199', // sha1('product_6')\n        );\n        $request = Mage::app()->getRequest();\n        $request->setParam('id', 5);\n        $this->setFullActionName('catalog', 'product', 'view');\n        $cacheTags = $this->dispatchCollectTagsEvent(array());\n        $this->assertEquals($expectedCacheTags, $cacheTags);\n\n        $expectedCacheTags = array(\n            '38a007151abe87cc01a5b6e9cc418e85286e2087', // sha1('product')\n            'cfe471971355a3a3d4311e12813f7fa689cf5199', // sha1('product_6')\n            '01337f5c00647634e8cef67064d9c4fd4fa0290e', // sha1('product_5')\n        );\n        $request->setParam('id', 6);\n        $this->setFullActionName('catalog', 'product', 'view');\n        $cacheTags = $this->dispatchCollectTagsEvent(array());\n        $this->assertEquals($expectedCacheTags, $cacheTags);\n    }\n\n    /**\n     * @test\n     * @loadFixture get_catalog_product_view_cache_tags_grouped_product.yaml\n     */\n    public function testGetCatalogProductViewCacheTagsGroupedProduct()\n    {\n        $expectedCacheTags = array(\n            '38a007151abe87cc01a5b6e9cc418e85286e2087', // sha1('product')\n            '01337f5c00647634e8cef67064d9c4fd4fa0290e', // sha1('product_5')\n            'cfe471971355a3a3d4311e12813f7fa689cf5199', // sha1('product_6')\n        );\n        $request = Mage::app()->getRequest();\n        $request->setParam('id', 5);\n        $this->setFullActionName('catalog', 'product', 'view');\n        $cacheTags = $this->dispatchCollectTagsEvent(array());\n        $this->assertEquals($expectedCacheTags, $cacheTags);\n\n        $expectedCacheTags = array(\n            '38a007151abe87cc01a5b6e9cc418e85286e2087', // sha1('product')\n            'cfe471971355a3a3d4311e12813f7fa689cf5199', // sha1('product_6')\n            '01337f5c00647634e8cef67064d9c4fd4fa0290e', // sha1('product_5')\n        );\n        $request->setParam('id', 6);\n        $this->setFullActionName('catalog', 'product', 'view');\n        $cacheTags = $this->dispatchCollectTagsEvent(array());\n        $this->assertEquals($expectedCacheTags, $cacheTags);\n    }\n\n    /**\n     * @test\n     */\n    public function testGetCatalogCategoryViewCacheTagsEmpty()\n    {\n        $expectedCacheTags = array(\n            '5ccbf9c9c5fc1bc34df8238a97094968f38f5165', // sha1('category')\n        );\n        $this->setFullActionName('catalog', 'category', 'view');\n        $cacheTags = $this->dispatchCollectTagsEvent(array());\n        $this->assertEquals($expectedCacheTags, $cacheTags);\n    }\n\n    /**\n     * @test\n     */\n    public function testGetCatalogCategoryViewCacheTags()\n    {\n        $expectedCacheTags = array(\n            '5ccbf9c9c5fc1bc34df8238a97094968f38f5165', // sha1('category')\n            '48ce6d1a1ef87339c758621f81e33b02f9d1cb72', // sha1('category_7')\n        );\n        $request = Mage::app()->getRequest();\n        $request->setParam('id', 7);\n        $this->setFullActionName('catalog', 'category', 'view');\n        $cacheTags = $this->dispatchCollectTagsEvent(array());\n        $this->assertEquals($expectedCacheTags, $cacheTags);\n    }\n\n    /**\n     * @param array $tags\n     * @return mixed\n     */\n    protected function dispatchCollectTagsEvent(array $tags)\n    {\n        $cacheTags = new Varien_Object();\n        $cacheTags->setValue($tags);\n        Mage::dispatchEvent(\n            'fpc_observer_collect_cache_tags',\n            array('cache_tags' => $cacheTags)\n        );\n        return $cacheTags->getValue();\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/fixtures/controller_action_postdispatch.yaml",
    "content": "config:\n    default/system/fpc/refresh_actions: >\n     checkout_cart_add,\n     checkout_cart_delete, checkout_cart_updatePost\n      , checkout_cart_delete\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/providers/controllerActionPostdispatch.yaml",
    "content": "test_false:\n  route: checkout\n  controller: cart\n  action: add\n  expected: 0\ntest_true:\n  route: catalog\n  controller: product\n  action: view\n  expected: 1\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Test_Model_Observer\n */\nclass Lesti_Fpc_Test_Model_Observer extends Lesti_Fpc_Test_TestCase\n{\n    /**\n     * @var Lesti_Fpc_Model_Observer\n     */\n    protected $_observer;\n\n    protected function setUp()\n    {\n        parent::setUp();\n        $this->_observer = Mage::getSingleton('fpc/observer');\n    }\n\n    protected function tearDown()\n    {\n        parent::tearDown();\n        // unregister observer\n        Mage::unregister('_singleton/fpc/observer');\n        Mage::getSingleton('customer/session')->setData(\n            Lesti_Fpc_Helper_Block::LAZY_BLOCKS_VALID_SESSION_PARAM,\n            false\n        );\n    }\n\n    /**\n     * @test\n     * @loadFixture controller_action_postdispatch.yaml\n     * @dataProvider dataProvider\n     */\n    public function controllerActionPostdispatch(\n        $route,\n        $controller,\n        $action,\n        $expected\n    )\n    {\n        Mage::app()->getRequest()->setRouteName($route);\n        Mage::app()->getRequest()->setControllerName($controller);\n        Mage::app()->getRequest()->setActionName($action);\n        Mage::getSingleton('customer/session')->setData(\n            Lesti_Fpc_Helper_Block::LAZY_BLOCKS_VALID_SESSION_PARAM,\n            true\n        );\n\n        $this->_observer->controllerActionPostdispatch();\n        $this->assertEquals(\n            (bool) $expected,\n            Mage::getSingleton('customer/session')->getData(\n                Lesti_Fpc_Helper_Block::LAZY_BLOCKS_VALID_SESSION_PARAM\n            )\n        );\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/TestCase.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Test_TestCase\n */\nabstract class Lesti_Fpc_Test_TestCase extends\n    EcomDev_PHPUnit_Test_Case_Controller\n{\n    /**\n     * @var Lesti_Fpc_Model_Fpc\n     */\n    protected $_fpc;\n\n    protected $_cacheOptions;\n\n    protected $_cache;\n\n    protected function setUp()\n    {\n        parent::setUp();\n        $this->_fpc = Mage::getSingleton('fpc/fpc');\n        $this->_fpc->clean();\n        // disable all caches expected fpc\n        $this->_cache = Mage::app()->getCacheInstance();\n        $this->_cacheOptions = Mage::getResourceSingleton('core/cache')\n            ->getAllOptions();\n        $cacheOptions = $this->_cacheOptions;\n        foreach (array_keys($cacheOptions) as $cache) {\n            $cacheOptions[$cache] = $cache == 'fpc' ? 1 : 0;\n        }\n        if (!array_key_exists('fpc', $cacheOptions)) {\n            $cacheOptions['fpc'] = 1;\n        }\n        $this->_cache->saveOptions($cacheOptions);\n        $cacheReflector = new ReflectionClass('Mage_Core_Model_Cache');\n        $initOptionsMethod = $cacheReflector->getMethod('_initOptions');\n        $initOptionsMethod->setAccessible(true);\n        $initOptionsMethod->invokeArgs($this->_cache, array());\n    }\n\n    protected function tearDown()\n    {\n        parent::tearDown();\n        $this->_cache->saveOptions($this->_cacheOptions);\n        // unregister fpc\n        Mage::unregister('_singleton/fpc/fpc');\n        Mage::getSingleton('customer/session')->logout();\n    }\n\n    protected function clearBaseUrlProperty()\n    {\n        $storeReflector = new ReflectionClass('Mage_Core_Model_Store');\n        $baseUrlCacheProperty = $storeReflector->getProperty('_baseUrlCache');\n        $baseUrlCacheProperty->setAccessible(true);\n        $baseUrlCacheProperty->setValue(Mage::app()->getStore(), array());\n    }\n\n    /**\n     * @param $routeName\n     * @param $controllerName\n     * @param $actionName\n     */\n    protected function setFullActionName(\n        $routeName,\n        $controllerName,\n        $actionName\n    )\n    {\n        Mage::app()->getRequest()->setRouteName($routeName);\n        Mage::app()->getRequest()->setControllerName($controllerName);\n        Mage::app()->getRequest()->setActionName($actionName);\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/controllers/Catalog/ProductController.php",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\n/**\n * Class Lesti_Fpc_Catalog_ProductController\n */\nclass Lesti_Fpc_Catalog_ProductController extends\n    Mage_Core_Controller_Front_Action\n{\n    public function viewAction()\n    {\n        $productId = (int)Mage::app()->getRequest()->getParam('id');\n        $product = Mage::getModel('catalog/product')->load($productId);\n        if ($product->getId()) {\n            Mage::dispatchEvent(\n                'catalog_controller_product_view',\n                array('product' => $product)\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/etc/config.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n-->\n<config>\n    <modules>\n        <Lesti_Fpc>\n            <version>1.4.8</version>\n        </Lesti_Fpc>\n    </modules>\n    <global>\n        <blocks>\n            <fpc>\n                <class>Lesti_Fpc_Block</class>\n            </fpc>\n            <core>\n                <rewrite>\n                    <messages>Lesti_Fpc_Core_Block_Messages</messages>\n                </rewrite>\n            </core>\n        </blocks>\n        <helpers>\n            <fpc>\n                <class>Lesti_Fpc_Helper</class>\n            </fpc>\n        </helpers>\n        <models>\n            <fpc>\n                <class>Lesti_Fpc_Model</class>\n            </fpc>\n        </models>\n        <cache>\n            <types>\n                <fpc translate=\"label,description\" module=\"fpc\">\n                    <label><![CDATA[Fpc]]></label>\n                    <description><![CDATA[Full Page Cache]]></description>\n                    <tags><![CDATA[FPC]]></tags>\n                </fpc>\n            </types>\n        </cache>\n        <events>\n            <catalog_product_save_after>\n                <observers>\n                    <fpc_catalog_product_save_after>\n                        <class>fpc/observer_save</class>\n                        <type>singleton</type>\n                        <method>catalogProductSaveAfter</method>\n                    </fpc_catalog_product_save_after>\n                </observers>\n            </catalog_product_save_after>\n            <catalog_category_save_after>\n                <observers>\n                    <fpc_catalog_category_save_after>\n                        <class>fpc/observer_save</class>\n                        <type>singleton</type>\n                        <method>catalogCategorySaveAfter</method>\n                    </fpc_catalog_category_save_after>\n                </observers>\n            </catalog_category_save_after>\n            <cms_page_save_after>\n                <observers>\n                    <fpc_cms_page_save_after>\n                        <class>fpc/observer_save</class>\n                        <type>singleton</type>\n                        <method>cmsPageSaveAfter</method>\n                    </fpc_cms_page_save_after>\n                </observers>\n            </cms_page_save_after>\n            <model_save_after>\n                <observers>\n                    <fpc_model_save_after>\n                        <class>fpc/observer_save</class>\n                        <type>singleton</type>\n                        <method>modelSaveAfter</method>\n                    </fpc_model_save_after>\n                </observers>\n            </model_save_after>\n            <review_delete_after>\n                <observers>\n                    <fpc_review_delete_after>\n                        <class>fpc/observer_save</class>\n                        <type>singleton</type>\n                        <method>reviewDeleteAfter</method>\n                    </fpc_review_delete_after>\n                </observers>\n            </review_delete_after>\n            <review_save_after>\n                <observers>\n                    <fpc_review_save_after>\n                        <class>fpc/observer_save</class>\n                        <type>singleton</type>\n                        <method>reviewSaveAfter</method>\n                    </fpc_review_save_after>\n                </observers>\n            </review_save_after>\n            <core_clean_cache>\n                <observers>\n                    <fpc_core_clean_cache>\n                        <class>fpc/observer_clean</class>\n                        <type>singleton</type>\n                        <method>coreCleanCache</method>\n                    </fpc_core_clean_cache>\n                </observers>\n            </core_clean_cache>\n            <adminhtml_cache_flush_all>\n                <observers>\n                    <fpc_adminhtml_cache_flush_all>\n                        <class>fpc/observer_clean</class>\n                        <type>singleton</type>\n                        <method>adminhtmlCacheFlushAll</method>\n                    </fpc_adminhtml_cache_flush_all>\n                </observers>\n            </adminhtml_cache_flush_all>\n            <cataloginventory_stock_item_save_after>\n                <observers>\n                    <fpc_cataloginventory_stock_item_save_after>\n                        <class>fpc/observer_save</class>\n                        <type>singleton</type>\n                        <method>cataloginventoryStockItemSaveAfter</method>\n                    </fpc_cataloginventory_stock_item_save_after>\n                </observers>\n            </cataloginventory_stock_item_save_after>\n            <fpc_helper_collect_params>\n                <observers>\n                    <fpc_fpc_helper_collect_params>\n                        <class>fpc/observer_parameters</class>\n                        <type>singleton</type>\n                        <method>fpcHelperCollectParams</method>\n                    </fpc_fpc_helper_collect_params>\n                </observers>\n            </fpc_helper_collect_params>\n            <fpc_observer_collect_cache_tags>\n                <observers>\n                    <fpc_fpc_observer_collect_cache_tags>\n                        <class>fpc/observer_tags</class>\n                        <type>singleton</type>\n                        <method>fpcObserverCollectCacheTags</method>\n                    </fpc_fpc_observer_collect_cache_tags>\n                </observers>\n            </fpc_observer_collect_cache_tags>\n        </events>\n        <catalogrule>\n            <related_cache_types>\n                <fpc />\n            </related_cache_types>\n        </catalogrule>\n    </global>\n    <frontend>\n        <routers>\n            <fpc>\n                <use>standard</use>\n                <args>\n                    <module>Lesti_Fpc</module>\n                    <frontName>fpc</frontName>\n                </args>\n            </fpc>\n        </routers>\n        <events>\n            <controller_action_postdispatch>\n                <observers>\n                    <fpc_controller_action_postdispatch>\n                        <class>fpc/observer</class>\n                        <type>singleton</type>\n                        <method>controllerActionPostdispatch</method>\n                    </fpc_controller_action_postdispatch>\n                </observers>\n            </controller_action_postdispatch>\n            <controller_action_layout_generate_blocks_before>\n                <observers>\n                    <fpc_controller_action_layout_generate_blocks_before>\n                        <class>fpc/observer</class>\n                        <type>singleton</type>\n                        <method>controllerActionLayoutGenerateBlocksBefore</method>\n                    </fpc_controller_action_layout_generate_blocks_before>\n                </observers>\n            </controller_action_layout_generate_blocks_before>\n            <http_response_send_before>\n                <observers>\n                    <fpc_http_response_send_before>\n                        <class>fpc/observer</class>\n                        <type>singleton</type>\n                        <method>httpResponseSendBefore</method>\n                    </fpc_http_response_send_before>\n                </observers>\n            </http_response_send_before>\n            <core_block_abstract_to_html_after>\n                <observers>\n                    <fpc_core_block_abstract_to_html_after>\n                        <class>fpc/observer</class>\n                        <type>singleton</type>\n                        <method>coreBlockAbstractToHtmlAfter</method>\n                    </fpc_core_block_abstract_to_html_after>\n                </observers>\n            </core_block_abstract_to_html_after>\n            <core_block_messages_get_grouped_html_after>\n                <observers>\n                    <fpc_core_block_messages_get_grouped_html_after>\n                        <class>fpc/observer</class>\n                        <type>singleton</type>\n                        <method>coreBlockAbstractToHtmlAfter</method>\n                    </fpc_core_block_messages_get_grouped_html_after>\n                </observers>\n            </core_block_messages_get_grouped_html_after>\n        </events>\n        <layout>\n            <updates>\n                <fpc>\n                    <file>fpc.xml</file>\n                </fpc>\n            </updates>\n        </layout>\n    </frontend>\n    <adminhtml>\n        <events>\n            <controller_action_predispatch_adminhtml_cache_massRefresh>\n                <observers>\n                    <fpc_controller_action_predispatch_adminhtml_cache_massRefresh>\n                        <class>fpc/observer_clean</class>\n                        <type>singleton</type>\n                        <method>controllerActionPredispatchAdminhtmlCacheMassRefresh</method>\n                    </fpc_controller_action_predispatch_adminhtml_cache_massRefresh>\n                </observers>\n            </controller_action_predispatch_adminhtml_cache_massRefresh>\n        </events>\n    </adminhtml>\n    <default>\n        <system>\n            <fpc>\n                <cache_actions><![CDATA[cms_index_index,\ncms_page_view,\ncatalog_product_view,\ncatalog_category_view]]></cache_actions>\n                <dynamic_blocks><![CDATA[global_messages,\nmessages,\nglobal_notices,\nglobal_cookie_notice,\nright.reports.product.viewed]]></dynamic_blocks>\n                <refresh_actions><![CDATA[checkout_cart_add,\ncheckout_cart_delete,\ncheckout_cart_updatePost,\ncheckout_cart_ajaxDelete,\ncheckout_cart_ajaxUpdate,\ncheckout_cart_updateItemOptions,\ncatalog_product_compare_add,\ncatalog_product_compare_clear,\ncatalog_product_compare_remove,\nwishlist_index_add,\nwishlist_index_remove,\nwishlist_index_update,\nwishlist_index_allcart,\nwishlist_index_configure,\ncheckout_onepage_success,\ncustomer_account_login,\npoll_vote_add]]></refresh_actions>\n                <lazy_blocks><![CDATA[top.links,\ncart_sidebar,\ncatalog.compare.sidebar,\nright.reports.product.compared,\nwishlist_sidebar,\nwelcome,\nminicart_head,\nright.poll]]></lazy_blocks>\n                <uri_params><![CDATA[id,\ncategory,\ncat,\npage_id,\np,\nlimit,\ndir,\norder,\nmode,\n/utm_.*/,\ngclid,\ngclsrc]]></uri_params>\n                <uri_params_layered_navigation>1</uri_params_layered_navigation>\n                <miss_uri_params><![CDATA[no_cache=/^1$/,\nlimit=/^([0-9]+)|(all)$/,\ndir=/^[0-9a-z_]+$/,\norder=/^[0-9a-z_]+$/,\nmode=/^[0-9a-z_]+$/,\n___store=/^[a-z]{1}[0-9a-z_]*$/]]></miss_uri_params>\n                <session_params><![CDATA[limit_page,\nsort_order,\nsort_direction,\ndisplay_mode]]></session_params>\n                <customer_groups>0</customer_groups>\n                <use_recently_viewed_products>0</use_recently_viewed_products>\n                <show_age>1</show_age>\n                <gzcompress_level>-2</gzcompress_level>\n            </fpc>\n        </system>\n    </default>\n    <phpunit>\n        <suite>\n            <modules>\n                <Lesti_Fpc/>\n            </modules>\n        </suite>\n    </phpunit>\n</config>\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/etc/system.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n-->\n<config>\n    <sections>\n        <system>\n            <groups>\n                <fpc>\n                    <label>Lesti FPC</label>\n                    <frontend_type>text</frontend_type>\n                    <sort_order>200</sort_order>\n                    <show_in_default>1</show_in_default>\n                    <show_in_website>1</show_in_website>\n                    <show_in_store>1</show_in_store>\n                    <fields>\n                        <cache_actions>\n                            <label>Cachable actions</label>\n                            <frontend_type>textarea</frontend_type>\n                            <comment>All cachable Actions, separated with Comma</comment>\n                            <sort_order>10</sort_order>\n                            <show_in_default>1</show_in_default>\n                            <show_in_website>1</show_in_website>\n                            <show_in_store>1</show_in_store>\n                        </cache_actions>\n                        <dynamic_blocks>\n                            <label>Dynamic Blocks</label>\n                            <frontend_type>textarea</frontend_type>\n                            <comment>All dynamic Blocks, separated with Comma</comment>\n                            <sort_order>20</sort_order>\n                            <show_in_default>1</show_in_default>\n                            <show_in_website>1</show_in_website>\n                            <show_in_store>1</show_in_store>\n                        </dynamic_blocks>\n                        <refresh_actions>\n                            <label>Refresh Actions</label>\n                            <frontend_type>textarea</frontend_type>\n                            <comment>All Action to refresh lazy blocks, separated with Comma</comment>\n                            <sort_order>30</sort_order>\n                            <show_in_default>1</show_in_default>\n                            <show_in_website>1</show_in_website>\n                            <show_in_store>1</show_in_store>\n                        </refresh_actions>\n                        <bypass_handles>\n                            <label>Bypass Handles</label>\n                            <frontend_type>textarea</frontend_type>\n                            <comment>All layout handles to bypass FPC, separated with Comma</comment>\n                            <sort_order>35</sort_order>\n                            <show_in_default>1</show_in_default>\n                            <show_in_website>1</show_in_website>\n                            <show_in_store>1</show_in_store>\n                        </bypass_handles>\n                        <lazy_blocks>\n                            <label>Lazy Blocks</label>\n                            <frontend_type>textarea</frontend_type>\n                            <comment>All lazy Blocks, separated with Comma</comment>\n                            <sort_order>40</sort_order>\n                            <show_in_default>1</show_in_default>\n                            <show_in_website>1</show_in_website>\n                            <show_in_store>1</show_in_store>\n                        </lazy_blocks>\n                        <uri_params>\n                            <label>Uri Params</label>\n                            <frontend_type>textarea</frontend_type>\n                            <comment>All Uri Params, separated with Comma. Params enclosed with \"/\" are treated as regular expression.</comment>\n                            <sort_order>50</sort_order>\n                            <show_in_default>1</show_in_default>\n                            <show_in_website>1</show_in_website>\n                            <show_in_store>1</show_in_store>\n                        </uri_params>\n                        <uri_params_layered_navigation>\n                            <label>Add Layered Navigation Attributes To Uri Params</label>\n                            <frontend_type>select</frontend_type>\n                            <source_model>adminhtml/system_config_source_yesno</source_model>\n                            <comment>If set to yes, all attributes that are set to show in the layered navigation will automatically get added to the list of Uri Params.</comment>\n                            <sort_order>52</sort_order>\n                            <show_in_default>1</show_in_default>\n                            <show_in_website>1</show_in_website>\n                            <show_in_store>1</show_in_store>\n                        </uri_params_layered_navigation>\n                        <miss_uri_params>\n                            <label>Miss Uri Params</label>\n                            <frontend_type>textarea</frontend_type>\n                            <comment>Ignore Requests with this parameters. Regex separated with comma.</comment>\n                            <sort_order>55</sort_order>\n                            <show_in_default>1</show_in_default>\n                            <show_in_website>1</show_in_website>\n                            <show_in_store>1</show_in_store>\n                        </miss_uri_params>\n                        <session_params>\n                            <label>Category Session Params</label>\n                            <frontend_type>textarea</frontend_type>\n                            <comment>All Session Params, separated with comma. Works only on category pages.</comment>\n                            <sort_order>60</sort_order>\n                            <show_in_default>1</show_in_default>\n                            <show_in_website>1</show_in_website>\n                            <show_in_store>1</show_in_store>\n                        </session_params>\n                        <customer_groups>\n                            <label>Customer Group Caching</label>\n                            <frontend_type>select</frontend_type>\n                            <comment>Only enable if you have different price or layout for different customer groups.</comment>\n                            <source_model>adminhtml/system_config_source_yesno</source_model>\n                            <sort_order>70</sort_order>\n                            <show_in_default>1</show_in_default>\n                            <show_in_website>0</show_in_website>\n                            <show_in_store>0</show_in_store>\n                        </customer_groups>\n                        <use_recently_viewed_products>\n                            <label>Use Recently Viewed Products</label>\n                            <frontend_type>select</frontend_type>\n                            <source_model>adminhtml/system_config_source_yesno</source_model>\n                            <sort_order>80</sort_order>\n                            <show_in_default>1</show_in_default>\n                            <show_in_website>1</show_in_website>\n                            <show_in_store>1</show_in_store>\n                        </use_recently_viewed_products>\n                        <show_age>\n                            <label>Show Age</label>\n                            <frontend_type>select</frontend_type>\n                            <comment>Show the age of a page in header</comment>\n                            <source_model>adminhtml/system_config_source_yesno</source_model>\n                            <sort_order>90</sort_order>\n                            <show_in_default>1</show_in_default>\n                            <show_in_website>1</show_in_website>\n                            <show_in_store>1</show_in_store>\n                        </show_age>\n                        <gzcompress_level>\n                            <label>gzcompress Level</label>\n                            <frontend_type>select</frontend_type>\n                            <comment>Compress the cache (only for filecache, flush Lesti_Fpc after changing value)</comment>\n                            <source_model>fpc/adminhtml_system_config_source_gzcompress</source_model>\n                            <sort_order>100</sort_order>\n                            <show_in_default>1</show_in_default>\n                            <show_in_website>1</show_in_website>\n                            <show_in_store>1</show_in_store>\n                        </gzcompress_level>\n                    </fields>\n                </fpc>\n            </groups>\n        </system>\n    </sections>\n</config>"
  },
  {
    "path": "app/design/frontend/base/default/layout/fpc.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n-->\n<layout version=\"0.1.0\">\n    <catalog_product_view>\n        <reference name=\"after_body_start\">\n            <block type=\"fpc/catalog_product_view_ajax\" name=\"fpc.catalog.product.view.ajax\" template=\"fpc/catalog/product/view/ajax.phtml\"/>\n        </reference>\n    </catalog_product_view>\n</layout>"
  },
  {
    "path": "app/design/frontend/base/default/template/fpc/catalog/product/view/ajax.phtml",
    "content": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n\nif($url = $this->getAjaxUrl()): ?>\n    <script type=\"text/javascript\">\n        new Ajax.Request(<?php echo '\"' . $url . '\"'; ?>);\n    </script>\n<?php endif;"
  },
  {
    "path": "app/etc/fpc.xml.sample",
    "content": "<?xml version=\"1.0\"?>\n<!--\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n-->\n<config>\n    <global>\n        <fpc>\n            <lifetime>86400</lifetime>\n\n            <!-- example for redis -->\n            <!-- please read https://github.com/colinmollenhour/Cm_Cache_Backend_Redis for more informations -->\n\n            <!--backend>Cm_Cache_Backend_Redis</backend>\n            <backend_options>\n                <server>127.0.0.1</server>\n                <port>6379</port>\n                <persistent>cache-fpc</persistent>\n                <database>1</database>\n                <password></password>\n                <force_standalone>1</force_standalone>\n                <connect_retries>1</connect_retries>\n                <lifetimelimit>86400</lifetimelimit>\n                <read_timeout>10</read_timeout>\n                <compress_data>1</compress_data>\n                <compress_tags>1</compress_tags>\n                <compress_data>gzip</compress_data>\n            </backend_options-->\n\n            <!-- example for apc -->\n\n            <!--backend>apc</backend>\n            <prefix>LESTI_FPC_</prefix-->\n\n            <!-- example for memcached -->\n\n            <!--backend>memcached</backend>\n            <memcached>\n                <servers>\n                    <server>\n                        <host><![CDATA[127.0.0.1]]></host>\n                        <port><![CDATA[11211]]></port>\n                        <persistent><![CDATA[1]]></persistent>\n                    </server>\n                </servers>\n                <compression><![CDATA[0]]></compression>\n                <cache_dir><![CDATA[]]></cache_dir>\n                <hashed_directory_level><![CDATA[]]></hashed_directory_level>\n                <hashed_directory_umask><![CDATA[]]></hashed_directory_umask>\n                <file_name_prefix><![CDATA[]]></file_name_prefix>\n            </memcached-->\n        </fpc>\n    </global>\n</config>\n"
  },
  {
    "path": "app/etc/modules/Lesti_Fpc.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLesti/Lesti_Fpc\n * @package   Lesti_Fpc\n * @author    Gordon Lesti <info@gordonlesti.com>\n * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)\n * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)\n */\n-->\n<config>\n    <modules>\n        <Lesti_Fpc>\n            <active>true</active>\n            <codePool>community</codePool>\n            <depends>\n                <Mage_Catalog/>\n                <Mage_Cms/>\n                <Mage_Core/>\n            </depends>\n        </Lesti_Fpc>\n    </modules>\n</config>"
  },
  {
    "path": "composer.json",
    "content": "{\n    \"name\": \"gordonlesti/lesti_fpc\",\n    \"type\": \"magento-module\",\n    \"description\": \"Simple Magento Fullpagecache\",\n    \"keywords\": [\"fpc\"],\n    \"homepage\": \"https://github.com/GordonLesti/Lesti_Fpc\",\n    \"license\": \"OSL-3.0\",\n    \"authors\": [\n        {\n            \"name\": \"Gordon Lesti\",\n            \"email\": \"info@gordonlesti.com\",\n            \"homepage\": \"http://gordonlesti.com/\",\n            \"role\": \"developer\"\n        }\n    ],\n    \"require\": {\n        \"magento-hackathon/magento-composer-installer\": \"^3.0\"\n    },\n    \"require-dev\": {\n        \"ecomdev/ecomdev_phpunit\": \"^0.3.7\",\n        \"phpunit/phpunit\": \"4.*\",\n        \"phpmd/phpmd\": \"^2.4\",\n        \"squizlabs/php_codesniffer\": \"^2.5\",\n        \"sebastian/phpcpd\": \"^2.0\",\n        \"satooshi/php-coveralls\": \"^1.0\"\n    },\n    \"repositories\": [\n        {\n            \"type\": \"composer\",\n            \"url\": \"https://packages.firegento.com/\"\n        }\n    ],\n    \"extra\": {\n        \"map\" : [\n            [\"app/code/community/Lesti/Fpc\", \"app/code/community/Lesti/Fpc\"],\n            [\"app/design/frontend/base/default/layout/fpc.xml\", \"app/design/frontend/base/default/layout/fpc.xml\"],\n            [\"app/design/frontend/base/default/template/fpc\", \"app/design/frontend/base/default/template/fpc\"],\n            [\"app/etc/modules/Lesti_Fpc.xml\", \"app/etc/modules/Lesti_Fpc.xml\"],\n            [\"app/etc/fpc.xml.sample\", \"app/etc/fpc.xml.sample\"]\n        ]\n    }\n}\n"
  },
  {
    "path": "modman",
    "content": "app/code/community/Lesti/Fpc app/code/community/Lesti/Fpc\napp/design/frontend/base/default/layout/fpc.xml app/design/frontend/base/default/layout/fpc.xml\napp/design/frontend/base/default/template/fpc app/design/frontend/base/default/template/fpc\napp/etc/modules/Lesti_Fpc.xml app/etc/modules/Lesti_Fpc.xml\napp/etc/fpc.xml.sample app/etc/fpc.xml.sample"
  }
]