Full Code of GordonLesti/Lesti_Fpc for AI

master f3f448529b92 cached
76 files
142.4 KB
39.4k tokens
171 symbols
1 requests
Download .txt
Repository: GordonLesti/Lesti_Fpc
Branch: master
Commit: f3f448529b92
Files: 76
Total size: 142.4 KB

Directory structure:
gitextract_7u5a0c3r/

├── .coveralls.yml
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── CONDUCT.md
├── LICENSE.md
├── README.md
├── app/
│   ├── code/
│   │   └── community/
│   │       └── Lesti/
│   │           └── Fpc/
│   │               ├── Block/
│   │               │   └── Catalog/
│   │               │       └── Product/
│   │               │           └── View/
│   │               │               └── Ajax.php
│   │               ├── Core/
│   │               │   └── Block/
│   │               │       └── Messages.php
│   │               ├── Helper/
│   │               │   ├── Abstract.php
│   │               │   ├── Block/
│   │               │   │   └── Messages.php
│   │               │   ├── Block.php
│   │               │   └── Data.php
│   │               ├── Model/
│   │               │   ├── Adminhtml/
│   │               │   │   └── System/
│   │               │   │       └── Config/
│   │               │   │           └── Source/
│   │               │   │               └── Gzcompress.php
│   │               │   ├── Fpc/
│   │               │   │   └── CacheItem.php
│   │               │   ├── Fpc.php
│   │               │   ├── Observer/
│   │               │   │   ├── Clean.php
│   │               │   │   ├── Parameters.php
│   │               │   │   ├── Save.php
│   │               │   │   └── Tags.php
│   │               │   └── Observer.php
│   │               ├── Test/
│   │               │   ├── Block/
│   │               │   │   ├── Catalog/
│   │               │   │   │   └── Product/
│   │               │   │   │       └── View/
│   │               │   │   │           ├── Ajax/
│   │               │   │   │           │   └── fixtures/
│   │               │   │   │           │       ├── get_ajax_url.yaml
│   │               │   │   │           │       ├── get_ajax_url_disabled_recently_viewed_products.yaml
│   │               │   │   │           │       ├── get_ajax_url_fpc_inactive.yaml
│   │               │   │   │           │       ├── get_ajax_url_miss_cache_able_action.yaml
│   │               │   │   │           │       └── get_ajax_url_no_current_product.yaml
│   │               │   │   │           └── Ajax.php
│   │               │   │   └── Core/
│   │               │   │       └── Messages.php
│   │               │   ├── Controller/
│   │               │   │   └── Catalog/
│   │               │   │       ├── ProductController/
│   │               │   │       │   └── fixtures/
│   │               │   │       │       └── view_action_with_product.yaml
│   │               │   │       └── ProductController.php
│   │               │   ├── Helper/
│   │               │   │   ├── Block/
│   │               │   │   │   ├── Messages.php
│   │               │   │   │   └── fixtures/
│   │               │   │   │       ├── are_lazy_blocks_valid.yaml
│   │               │   │   │       ├── get_dynamic_blocks.yaml
│   │               │   │   │       ├── get_dynamic_blocks_empty.yaml
│   │               │   │   │       ├── get_lazy_blocks.yaml
│   │               │   │   │       ├── get_lazy_blocks_empty.yaml
│   │               │   │   │       ├── use_recently_viewed_products_false.yaml
│   │               │   │   │       └── use_recently_viewed_products_true.yaml
│   │               │   │   ├── Block.php
│   │               │   │   ├── Data/
│   │               │   │   │   ├── fixtures/
│   │               │   │   │   │   ├── can_cache_request.yaml
│   │               │   │   │   │   ├── get_bypass_handles.yaml
│   │               │   │   │   │   ├── get_bypass_handles_empty.yaml
│   │               │   │   │   │   ├── get_cacheable_actions.yaml
│   │               │   │   │   │   ├── get_cacheable_actions_empty.yaml
│   │               │   │   │   │   ├── get_refresh_actions.yaml
│   │               │   │   │   │   ├── get_refresh_actions_empty.yaml
│   │               │   │   │   │   └── regex_uri_params.yaml
│   │               │   │   │   └── providers/
│   │               │   │   │       ├── testCanCacheRequest.yaml
│   │               │   │   │       └── testRegexUriParams.yaml
│   │               │   │   └── Data.php
│   │               │   ├── Model/
│   │               │   │   ├── Fpc/
│   │               │   │   │   └── fixtures/
│   │               │   │   │       └── save_load_clean.yaml
│   │               │   │   ├── Fpc.php
│   │               │   │   ├── Observer/
│   │               │   │   │   ├── Clean.php
│   │               │   │   │   ├── Parameters/
│   │               │   │   │   │   └── fixtures/
│   │               │   │   │   │       └── fpc_helper_collect_params.yaml
│   │               │   │   │   ├── Parameters.php
│   │               │   │   │   ├── Save.php
│   │               │   │   │   ├── Tags/
│   │               │   │   │   │   ├── fixtures/
│   │               │   │   │   │   │   ├── fpc_observer_collect_cache_tags.yaml
│   │               │   │   │   │   │   ├── get_catalog_product_view_cache_tags_configurable_prod.yaml
│   │               │   │   │   │   │   ├── get_catalog_product_view_cache_tags_grouped_product.yaml
│   │               │   │   │   │   │   ├── get_cms_index_index_cache_tags.yaml
│   │               │   │   │   │   │   └── get_cms_index_index_cache_tags_zero.yaml
│   │               │   │   │   │   └── providers/
│   │               │   │   │   │       └── testFpcObserverCollectCacheTags.yaml
│   │               │   │   │   ├── Tags.php
│   │               │   │   │   ├── fixtures/
│   │               │   │   │   │   └── controller_action_postdispatch.yaml
│   │               │   │   │   └── providers/
│   │               │   │   │       └── controllerActionPostdispatch.yaml
│   │               │   │   └── Observer.php
│   │               │   └── TestCase.php
│   │               ├── controllers/
│   │               │   └── Catalog/
│   │               │       └── ProductController.php
│   │               └── etc/
│   │                   ├── config.xml
│   │                   └── system.xml
│   ├── design/
│   │   └── frontend/
│   │       └── base/
│   │           └── default/
│   │               ├── layout/
│   │               │   └── fpc.xml
│   │               └── template/
│   │                   └── fpc/
│   │                       └── catalog/
│   │                           └── product/
│   │                               └── view/
│   │                                   └── ajax.phtml
│   └── etc/
│       ├── fpc.xml.sample
│       └── modules/
│           └── Lesti_Fpc.xml
├── composer.json
└── modman

================================================
FILE CONTENTS
================================================

================================================
FILE: .coveralls.yml
================================================
src_dir: app

================================================
FILE: .gitignore
================================================
/vendor
/composer.lock
.idea


================================================
FILE: .travis.yml
================================================
language: php

sudo: false

php:
  - 5.5
  - 5.6

env:
  - MAGE=magento-1-9-1-0
  - MAGE=magento-1-8-1-0
  - MAGE=magento-1-7-0-2
  - MAGE=magento-1-6-2-0
  - MAGE=magento-1-5-1-0

install:
  - composer install --dev --prefer-dist --no-scripts
  - curl https://gordonlesti.com/"$MAGE".tar.gz | tar xz
  - mv $MAGE magento
  - cd magento
  - wget https://raw.githubusercontent.com/colinmollenhour/modman/master/modman
  - chmod +x modman
  - ./modman init
  - cd ..

before_script:
  - mkdir -p build/logs
  - mysql -e 'create database `magento`;'
  - mysql -utravis magento < magento/var/magento.sql
  - mysql -e 'create database `magento_test`;'
  - mysql -utravis magento_test < magento/var/magento_test.sql
  - cd magento
  - ./modman link ./../../Lesti_Fpc
  - ./modman clone https://github.com/EcomDev/EcomDev_PHPUnit.git
  - cd ..

script:
  - php vendor/bin/phpcs --standard=Zend -n app/
  - php vendor/bin/phpmd app/ text codesize,design,unusedcode
  - php vendor/bin/phpcpd app/
  - cd magento && php ../vendor/bin/phpunit --coverage-clover ../build/logs/clover.xml && cd ..

after_script:
  - php vendor/bin/coveralls


================================================
FILE: CHANGELOG.md
================================================
# Changelog

All Notable changes to `Lesti_Fpc` will be documented in this file.

Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles.

## Unreleased

### Added
- Nothing

### Deprecated
- Nothing

### Fixed
- Nothing

### Removed
- Nothing

### Security
- Nothing

## 1.4.8 - 2016-12-06

### Added
- [added utm_* parameters to uri params, fixes #274](https://github.com/GordonLesti/Lesti_Fpc/pull/275)

## 1.4.7 - 2016-12-03

### Added
- [Invalidate cache after catalog rule apply](https://github.com/GordonLesti/Lesti_Fpc/pull/272)


================================================
FILE: CONDUCT.md
================================================
# Contributor Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
  address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at `info@gordonlesti.com`. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]

[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/


================================================
FILE: LICENSE.md
================================================
# Open Software License v. 3.0 (OSL-3.0)

> This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose
> owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original
> Work:
>
> Licensed under the Open Software License version 3.0
>
> 1) **Grant of Copyright License**. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable
> license, for > the duration of the copyright, to do the following:
>
> a) to reproduce the Original Work in copies, either alone or as part of a collective work;
>
> b) to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works
> ("Derivative Works") based upon the Original Work;
>
> c) to distribute or communicate copies of the Original Work and Derivative Works to the public, *with the proviso that
> copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open
> Software License*;
>
> d) to perform the Original Work publicly; and
>
> e) to display the Original Work publicly.
>
> 2) **Grant** of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license,
> under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the
> Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work
> and Derivative Works.
>
> 3) **Grant** of Source Code License. The term "Source Code" means the preferred form of the Original Work for making
> modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to
> provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that
> Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the
> Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for
> as long as Licensor continues to distribute the Original Work.
>
> 4) **Exclusions From License Grant**. Neither the names of Licensor, nor the names of any contributors to the Original
> Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this
> Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this
> License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual
> property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any
> patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor
> even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit
> Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a
> right to license.
>
> 5) **External Deployment**. The term "External Deployment" means the use, distribution, or communication of the
> Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone
> other than You, whether those works are distributed or communicated to those persons or made available as an
> application intended for use over a network. As an express condition for the grants of license hereunder, You must
> treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c).
>
> 6) **Attribution Rights**. You must retain, in the Source Code of any Derivative Works that You create, all copyright,
> patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any
> descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative
> Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have
> modified the Original Work.
>
> 7) **Warranty of Provenance and Disclaimer of Warranty**. Licensor warrants that the copyright in and to the Original
> Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the
> terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as
> expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS"
> BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of
> non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE
> ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to
> the Original Work is granted by this License except under this disclaimer.
>
> 8) **Limitation of Liability**. Under no circumstances and under no legal theory, whether in tort (including
> negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or
> consequential damages of any character arising as a result of this License or the use of the Original Work including,
> without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other
> commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such
> limitation.
>
> 9) **Acceptance and Termination**. If, at any time, You expressly assented to this License, that assent indicates your
> clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate
> copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain
> the express assent of recipients to the terms of this License. This License conditions your rights to undertake the
> activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and
> doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing
> in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing").
> This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this
> License upon your failure to honor the conditions in Section 1(c).
>
> 10) **Termination for Patent Action**. This License shall terminate automatically and You may no longer exercise any
> of the rights granted to You by this License as of the date You commence an action, including a cross-claim or
> counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination
> provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other
> software or hardware.
>
> 11) **Jurisdiction, Venue and Governing Law**. Any action or suit relating to this License may be brought only in the
> courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under
> the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations
> Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work
> outside the scope of this License or after its termination shall be subject to the requirements and penalties of
> copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License.
>
> 12) **Attorneys' Fees**. In any action to enforce the terms of this License or seeking damages relating thereto, the
> prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable
> attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section
> shall survive the termination of this License.
>
> 13) **Miscellaneous**. If any provision of this License is held to be unenforceable, such provision shall be reformed
> only to the extent necessary to make it enforceable.
>
> 14) **Definition of "You" in This License**. "You" throughout this License, whether in upper or lower case, means an
> individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal
> entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes
> of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such
> entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares,
> or (iii) beneficial ownership of such entity.
>
> 15) **Right to Use**. You may use the Original Work in all ways not otherwise restricted or conditioned by this
> License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.
>
> 16) **Modification of This License**. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy,
> distribute, or communicate this License without modification. Nothing in this License permits You to modify this
> License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and
> copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of
> authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the
> "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must
> replace the notice specified in the first paragraph above with the notice "Licensed under &lt;insert your license name
> here&gt;" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may
> not claim that your original works are open source software unless your Modified License has been approved by Open
> Source Initiative (OSI) and You comply with its license review and certification process.


================================================
FILE: README.md
================================================
# Lesti_Fpc

[![Latest Release][ico-version]][link-release]
[![Software License][ico-license]](LICENSE.md)
[![Build Status][ico-travis]][link-travis]
[![Coverage Status][ico-coverall]][link-coveralls]

Simple Magento Fullpagecache. The current documentation can be found
[here](https://gordonlesti.com/lesti-fpc-documentationversion-1-4-5/).

## Install

Several quick start options are available:
### Install manually
  * [Download the latest release](https://github.com/GordonLesti/Lesti_Fpc/releases/latest)
  * Unzip
  * Copy `app` directory into Magento

### Install with [modman](https://github.com/colinmollenhour/modman)

```bash
modman clone https://github.com/GordonLesti/Lesti_Fpc.git
```

### Install with [Magento Composer Installer](https://github.com/Cotya/magento-composer-installer)
  * add the requirement `gordonlesti/lesti_fpc`
```json
{
    "require": {
        "gordonlesti/lesti_fpc": "*"
    }
}
```

## Change log

Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.

## Contributing

Please see [CONTRIBUTING](CONTRIBUTING.md) and [CONDUCT](CONDUCT.md) for details.

## Security

If you discover any security related issues, please email info@gordonlesti.com instead of using the issue tracker.

## Credits

- [Gordon Lesti][link-author]
- [All Contributors][link-contributors]

## License

The Open Software License v. 3.0 (OSL-3.0). Please see [License File](LICENSE.md) for more information.

[ico-version]: https://img.shields.io/github/release/GordonLesti/Lesti_Fpc.svg?style=flat-square
[ico-license]: https://img.shields.io/badge/license-OSL--3.0-brightgreen.svg?style=flat-square
[ico-travis]: https://img.shields.io/travis/GordonLesti/Lesti_Fpc/master.svg?style=flat-square
[ico-coverall]: https://img.shields.io/coveralls/GordonLesti/Lesti_Fpc/master.svg?style=flat-square

[link-release]: https://github.com/GordonLesti/Lesti_Fpc/releases/latest
[link-travis]: https://travis-ci.org/GordonLesti/Lesti_Fpc
[link-coveralls]: https://coveralls.io/r/GordonLesti/Lesti_Fpc
[link-author]: https://gordonlesti.com/
[link-contributors]: ../../contributors


================================================
FILE: app/code/community/Lesti/Fpc/Block/Catalog/Product/View/Ajax.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Block_Catalog_Product_View_Ajax
 */
class Lesti_Fpc_Block_Catalog_Product_View_Ajax extends Mage_Core_Block_Template
{
    /**
     * @return bool|string
     */
    public function getAjaxUrl()
    {
        $id = $this->_getProductId();
        if (Mage::getSingleton('fpc/fpc')->isActive() &&
            in_array(
                'catalog_product_view',
                Mage::helper('fpc')->getCacheableActions()
            ) &&
            Mage::helper('fpc/block')->useRecentlyViewedProducts() &&
            $id
        ) {
            return $this->getUrl(
                'fpc/catalog_product/view',
                array(
                    'id' => $id,
                    '_secure' => Mage::app()->getStore()->isCurrentlySecure()
                )
            );
        }
        return false;
    }

    /**
     * @return bool
     */
    protected function _getProductId()
    {
        $product = Mage::registry('current_product');
        if ($product) {
            return $product->getId();
        }
        return false;
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Core/Block/Messages.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Core_Block_Messages
 */
class Lesti_Fpc_Core_Block_Messages extends Mage_Core_Block_Messages
{
    /**
     * Retrieve messages in HTML format grouped by type
     *
     * @param   string $type
     * @return  string
     */
    public function getGroupedHtml()
    {
        $html = parent::getGroupedHtml();

        /**
         * Use single transport object instance for all blocks
         */

        $_transportObject = new Varien_Object;
        $_transportObject->setHtml($html);
        Mage::dispatchEvent(
            'core_block_messages_get_grouped_html_after',
            array('block' => $this, 'transport' => $_transportObject)
        );
        $html = $_transportObject->getHtml();

        return $html;
    }
}

================================================
FILE: app/code/community/Lesti/Fpc/Helper/Abstract.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Helper_Abstract
 */
abstract class Lesti_Fpc_Helper_Abstract extends Mage_Core_Helper_Abstract
{
    /**
     * Returns comma seperated store configs as array
     *
     * @param $path
     * @param null $store
     * @return array
     */
    public function getCSStoreConfigs($path, $store = null)
    {
        $configs = trim(Mage::getStoreConfig($path, $store));

        if ($configs) {
            return array_unique(array_map('trim', explode(',', $configs)));
        }

        return array();
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Helper/Block/Messages.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Helper_Block_Messages
 */
class Lesti_Fpc_Helper_Block_Messages extends Mage_Core_Helper_Abstract
{
    /**
     * @param $layout
     * @return mixed
     */
    public function initLayoutMessages(
        Mage_Core_Model_Layout $layout,
        $messagesStorage =
        array('catalog/session', 'tag/session', 'checkout/session', 'customer/session')
    )
    {
        $block = $layout->getMessagesBlock();
        if ($block) {
            foreach ($messagesStorage as $storageName) {
                $storage = Mage::getSingleton($storageName);
                if ($storage) {
                    $block->addMessages($storage->getMessages(true));
                    $block->setEscapeMessageFlag(
                        $storage->getEscapeMessages(true)
                    );
                } else {
                    Mage::throwException(
                        Mage::helper('core')->__(
                            'Invalid messages storage "%s" for layout '.
                            'messages initialization',
                            (string)$storageName
                        )
                    );
                }
            }
        }
        return $layout;
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Helper/Block.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Helper_Block
 */
class Lesti_Fpc_Helper_Block extends Lesti_Fpc_Helper_Abstract
{
    const DYNAMIC_BLOCKS_XML_PATH = 'system/fpc/dynamic_blocks';
    const LAZY_BLOCKS_XML_PATH = 'system/fpc/lazy_blocks';
    const LAZY_BLOCKS_VALID_SESSION_PARAM = 'fpc_lazy_blocks_valid';
    const USE_RECENTLY_VIEWED_PRODUCTS_XML_PATH =
        'system/fpc/use_recently_viewed_products';

    /**
     * @return array
     */
    public function getDynamicBlocks()
    {
        return $this->getCSStoreConfigs(self::DYNAMIC_BLOCKS_XML_PATH);
    }

    /**
     * @return array
     */
    public function getLazyBlocks()
    {
        return $this->getCSStoreConfigs(self::LAZY_BLOCKS_XML_PATH);
    }

    /**
     * @return bool
     */
    public function areLazyBlocksValid()
    {
        $hash = $this->_getLazyBlocksValidHash();
        $session = Mage::getSingleton('customer/session');
        $sessionHash = $session->getData(self::LAZY_BLOCKS_VALID_SESSION_PARAM);
        if ($sessionHash === false || $hash != $sessionHash) {
            $session->setData(self::LAZY_BLOCKS_VALID_SESSION_PARAM, $hash);
            return false;
        }
        return true;
    }

    /**
     * @return string
     */
    protected function _getLazyBlocksValidHash()
    {
        $params = array();
        $request = Mage::app()->getRequest();
        $params['host'] = $request->getServer('HTTP_HOST');
        $params['port'] = $request->getServer('SERVER_PORT');
        // store
        $storeCode = Mage::app()->getStore()->getCode();
        if ($storeCode) {
            $params['store'] = $storeCode;
        }
        // currency
        $currencyCode = Mage::app()->getStore()->getCurrentCurrencyCode();
        if ($currencyCode) {
            $params['currency'] = $currencyCode;
        }
        $customerSession = Mage::getSingleton('customer/session');
        $params['customer_group_id'] = $customerSession->getCustomerGroupId();
        $design = Mage::getDesign();
        $params['design'] = $design->getPackageName().'_'.
            $design->getTheme('template');

        $params['blocks'] = implode(',', $this->getLazyBlocks());

        return sha1(serialize($params));
    }

    /**
     * @param $blockName
     * @return string
     */
    public function getPlaceholderHtml($blockName)
    {
        return '<!-- fpc ' . sha1($blockName) . ' -->';
    }

    /**
     * @param $blockName
     * @return string
     */
    public function getKey($blockName)
    {
        return sha1($blockName) . '_block';
    }

    /**
     * @return mixed
     */
    public function useRecentlyViewedProducts()
    {
        return (bool)Mage::getStoreConfig(
            self::USE_RECENTLY_VIEWED_PRODUCTS_XML_PATH
        );
    }

    /**
     * @param $block
     * @return array
     */
    public function getCacheTags($block)
    {
        $cacheTags = array();
        $blockName = $block->getNameInLayout();
        if ($blockName == 'product_list') {
            $cacheTags[] = sha1('product');
            foreach ($block->getLoadedProductCollection() as $product) {
                $cacheTags[] = sha1('product_' . $product->getId());
            }
        } else if ($block instanceof Mage_Cms_Block_Block ||
        is_subclass_of($block, 'Mage_Cms_Block_Block')) {
            $cacheTags[] = sha1('cmsblock');
            $cacheTags[] = sha1('cmsblock_' . $block->getBlockId());
        }
        return $cacheTags;
    }

}


================================================
FILE: app/code/community/Lesti/Fpc/Helper/Data.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Helper_Data
 */
class Lesti_Fpc_Helper_Data extends Lesti_Fpc_Helper_Abstract
{
    const XML_PATH_CACHEABLE_ACTIONS = 'system/fpc/cache_actions';
    const XML_PATH_BYPASS_HANDLES = 'system/fpc/bypass_handles';
    const XML_PATH_URI_PARAMS = 'system/fpc/uri_params';
    const XML_PATH_URI_PARAMS_LAYERED_NAVIGATION = 'system/fpc/uri_params_layered_navigation';
    const XML_PATH_CUSTOMER_GROUPS = 'system/fpc/customer_groups';
    const XML_PATH_REFRESH_ACTIONS = 'system/fpc/refresh_actions';
    const XML_PATH_MISS_URI_PARAMS = 'system/fpc/miss_uri_params';
    const LAYOUT_ELEMENT_CLASS = 'Mage_Core_Model_Layout_Element';
    const CACHE_KEY_LAYERED_NAVIGATION_ATTRIBUTES = 'layeredNavigationAttributes';

    const REGISTRY_KEY_PARAMS = 'fpc_params';

    // List of pages that contain layered navigation
    static protected $_pagesWithLayeredNavigation = array(
        'catalogsearch_result_index',
        'catalog_category_layered',
        'catalog_category_view'
    );

    /**
     * @return array
     */
    public function getCacheableActions()
    {
        return $this->getCSStoreConfigs(self::XML_PATH_CACHEABLE_ACTIONS);
    }

    /**
     * @return array
     */
    public function getBypassHandles()
    {
        return $this->getCSStoreConfigs(self::XML_PATH_BYPASS_HANDLES);
    }

    /**
     * @return array
     */
    public function getRefreshActions()
    {
        return $this->getCSStoreConfigs(self::XML_PATH_REFRESH_ACTIONS);
    }

    /**
     * @param string $postfix
     * @return string
     */
    public function getKey($postfix = '_page')
    {
        return sha1($this->_getParams()) . $postfix;
    }

    /**
     * @return mixed
     */
    protected function _getParams()
    {
        if (!Mage::registry(self::REGISTRY_KEY_PARAMS)) {
            $request = Mage::app()->getRequest();
            $params = array('host' => $request->getServer('HTTP_HOST'),
                'port' => $request->getServer('SERVER_PORT'),
                'secure' => Mage::app()->getStore()->isCurrentlySecure(),
                'full_action_name' => $this->getFullActionName(),
                'ajax' => $request->isAjax(),
              );
            $uriParams = $this->_getUriParams();
            foreach ($request->getParams() as $requestParam =>
                     $requestParamValue) {
                if (!$requestParamValue) {
                    continue;
                }
                foreach ($uriParams as $uriParam) {
                    if ($this->_matchUriParam($uriParam, $requestParam)) {
                        $params['uri_' . $requestParam] = $requestParamValue;
                        break;
                    }
                }
            }
            if (Mage::getStoreConfig(self::XML_PATH_CUSTOMER_GROUPS)) {
                $customerSession = Mage::getSingleton('customer/session');
                $params['customer_group_id'] = $customerSession
                    ->getCustomerGroupId();
            }

            // edit parameters via event
            $parameters = new Varien_Object();
            $parameters->setValue($params);
            Mage::dispatchEvent(
                'fpc_helper_collect_params',
                array('parameters' => $parameters)
            );
            $params = $parameters->getValue();


            Mage::register(self::REGISTRY_KEY_PARAMS, serialize($params));
        }
        return Mage::registry(self::REGISTRY_KEY_PARAMS);
    }

    /**
     * Matches URI param against expression
     * (string comparison or regular expression)
     *
     * @param string $expression
     * @param string $param
     * @return boolean
     */
    protected function _matchUriParam($expression, $param)
    {
        if (substr($expression, 0, 1) === '/' &&
            substr($expression, -1, 1) === '/') {
            return (bool) preg_match($expression, $param);
        } else {
            return $expression === $param;
        }
    }

    /**
     * @return array
     */
    public function _getUriParams()
    {
        $configParams = $this->getCSStoreConfigs(self::XML_PATH_URI_PARAMS);

        if (Mage::getStoreConfig(self::XML_PATH_URI_PARAMS_LAYERED_NAVIGATION)) {
            $layeredNavigationParams = $this->_getLayeredNavigationAttributes();
        } else {
            $layeredNavigationParams = array();
        }

        return array_merge($configParams, $layeredNavigationParams);
    }

    /**
     * If on a page that contains a layered navigation block, load all attributes that are supposed to show
     *
     * @return array
     */
    protected function _getLayeredNavigationAttributes()
    {
        // List of attributes that are used in layered navigation
        $layeredNavigationAttributes = array();

        $currentFullActionName = $this->getFullActionName();
        if (in_array($currentFullActionName, self::$_pagesWithLayeredNavigation)) {
            /** @var Mage_Catalog_Model_Resource_Product_Attribute_Collection $attributeCollection */
            $attributeCollection = Mage::getResourceModel('catalog/product_attribute_collection');

            // The category and search pages may have different filterable attributes, based on how the attributes
            // are configured
            switch ($currentFullActionName) {
                case 'catalogsearch_result_index':
                    $filterableField = 'is_filterable_in_search';
                    break;
                case 'catalog_category_layered':
                case 'catalog_category_view':
                default:
                    $filterableField = 'is_filterable';
            }

            $cache = Mage::app()->getCache();
            $cacheId = self::CACHE_KEY_LAYERED_NAVIGATION_ATTRIBUTES.'_'.$filterableField;
            $cacheTags = array('FPC', self::CACHE_KEY_LAYERED_NAVIGATION_ATTRIBUTES);
            $layeredNavigationAttributesCache = $cache->load($cacheId);

            if (!$layeredNavigationAttributesCache) {
                $attributeCollection->addFieldToFilter($filterableField, array('in' => array(1,2)));
                foreach ($attributeCollection as $attribute) {
                    $layeredNavigationAttributes[] = $attribute->getAttributeCode();
                }
                $cache->save(serialize($layeredNavigationAttributes), $cacheId, $cacheTags);
            } else {
                $layeredNavigationAttributes = unserialize($layeredNavigationAttributesCache);
            }
        }

        return $layeredNavigationAttributes;
    }

    /**
     * @return array
     */
    protected function _getMissUriParams()
    {
        return $this->getCSStoreConfigs(self::XML_PATH_MISS_URI_PARAMS);
    }

    /**
     * @return bool
     */
    public function canCacheRequest()
    {
        $request = Mage::app()->getRequest();
        if (strtoupper($request->getMethod()) != 'GET') {
            return false;
        }
        $missParams = $this->_getMissUriParams();
        foreach ($missParams as $missParam) {
            $pair = array_map('trim', explode('=', $missParam));
            $key = $pair[0];
            $param = $request->getParam($key);
            if ($param && isset($pair[1]) && preg_match($pair[1], $param)) {
                return false;
            }
        }

        $handles = Mage::app()->getLayout()->getUpdate()->getHandles();
        foreach ($this->getBypassHandles() as $handle) {
            if (in_array($handle, $handles)) {
                return false;
            }
        }

        return true;
    }

    /**
     * @return string
     */
    public function getFullActionName()
    {
        $delimiter = '_';
        $request = Mage::app()->getRequest();
        return $request->getRequestedRouteName() . $delimiter .
        $request->getRequestedControllerName() . $delimiter .
        $request->getRequestedActionName();
    }

    /**
     * @param Mage_Core_Controller_Response_Http $response
     * @return string
     */
    public function getContentType(\Mage_Core_Controller_Response_Http $response)
    {
        foreach ($response->getHeaders() as $header) {
            if (isset($header['name']) && $header['name'] === 'Content-Type' && isset($header['value'])) {
                return $header['value'];
            }
        }

        return 'text/html; charset=UTF-8';
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Model/Adminhtml/System/Config/Source/Gzcompress.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Model_Adminhtml_System_Config_Source_Gzcompress
 */
class Lesti_Fpc_Model_Adminhtml_System_Config_Source_Gzcompress
{
    /**
     * @return array
     */
    public function toOptionArray()
    {
        $options = array();
        foreach ($this->toArray() as $key => $value) {
            $options[] = array('value' => $key, 'label' => $value);
        }

        return $options;
    }

    /**
     * @return array
     */
    public function toArray()
    {
        $options = array(-2 => Mage::helper('fpc')->__('No'));
        for ($i=0; $i <10; $i++) {
            $options[$i] = $i;
        }

        return $options;
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Model/Fpc/CacheItem.php
================================================
<?php

/**
 * Class Lesti_Fpc_Model_Fpc_CacheItem
 */
class Lesti_Fpc_Model_Fpc_CacheItem
{
    /**
     * @var string
     */
    private $_content;

    /**
     * @var int
     */
    private $_time;

    /**
     * @var string
     */
    private $_contentType;

    /**
     * @param string $content
     * @param int    $time
     * @param string $contentType
     */
    public function __construct($content, $time, $contentType)
    {
        $this->_content = $content;
        $this->_time = $time;
        $this->_contentType = $contentType;
    }

    /**
     * @return string
     */
    public function getContent()
    {
        return $this->_content;
    }

    /**
     * @return int
     */
    public function getTime()
    {
        return $this->_time;
    }

    /**
     * @return string
     */
    public function getContentType()
    {
        return $this->_contentType;
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Model/Fpc.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Model_Fpc
 */
class Lesti_Fpc_Model_Fpc extends Mage_Core_Model_Cache
{
    const GZCOMPRESS_LEVEL_XML_PATH = 'system/fpc/gzcompress_level';
    const CACHE_TAG = 'FPC';

    /**
     * Default options for default backend
     *
     * @var array
     */
    protected $_defaultBackendOptions = array(
        'hashed_directory_level'    => 6,
        'hashed_directory_perm'    => 0777,
        'file_name_prefix'          => 'fpc',
    );

    /**
     * Default options for default backend used by Zend Framework versions
     * older than 1.12.0
     *
     * @var array
     */
    protected $_legacyDefaultBackendOptions = array(
        'hashed_directory_level'    => 6,
        'hashed_directory_umask'    => 0777,
        'file_name_prefix'          => 'fpc',
    );

    public function __construct()
    {
        /*
         * If the version of Zend Framework is older than 1.12, fallback to the
         * legacy cache settings.
         * See http://framework.zend.com/issues/browse/ZF-12047
         */
        if (Zend_Version::compareVersion('1.12.0') > 0) {
            $this->_defaultBackendOptions = $this->_legacyDefaultBackendOptions;
        }
        $node = Mage::getConfig()->getNode('global/fpc');
        $options = array();
        if ($node) {
            $options = $node->asArray();
        }
        parent::__construct($options);
    }

    /**
     * Save data
     *
     * @param mixed $item
     * @param string $id
     * @param array $tags
     * @param int $lifeTime
     * @return bool
     */
    public function save($item, $id, $tags=array(), $lifeTime=null)
    {
        if (!in_array(self::CACHE_TAG, $tags)) {
            $tags[] = self::CACHE_TAG;
        }
        if (is_null($lifeTime)) {
            $lifeTime = (int) $this->getFrontend()->getOption('lifetime');
        }
        $data = array(
            $item->getContent(),
            $item->getTime(),
            $item->getContentType(),
        );
        // edit cached object
        $cacheData = new Varien_Object();
        $cacheData->setCachedata($data);
        $cacheData->setCacheId($id);
        $cacheData->setTags($tags);
        $cacheData->setLifeTime($lifeTime);
        Mage::dispatchEvent(
            'fpc_save_data_before',
            array('cache_data' => $cacheData)
        );
        $data = $cacheData->getCachedata();
        $id = $cacheData->getCacheId();
        $tags = $cacheData->getTags();
        $lifeTime = $cacheData->getLifeTime();

        $compressLevel = Mage::getStoreConfig(self::GZCOMPRESS_LEVEL_XML_PATH);
        $data = serialize($data);
        if ($compressLevel != -2) {
            $data = gzcompress($data, $compressLevel);
        }

        return $this->_frontend->save(
            $data,
            $this->_id($id),
            $this->_tags($tags),
            $lifeTime
        );
    }

    /**
     * @param string $id
     * @return boolean|\Lesti_Fpc_Model_Fpc_CacheItem
     */
    public function load($id)
    {
        $data = parent::load($id);
        if ($data === false) {
            return false;
        }
        $compressLevel = Mage::getStoreConfig(self::GZCOMPRESS_LEVEL_XML_PATH);
        if ($data !== false && $compressLevel != -2) {
            $data = gzuncompress($data);
        }

        $data = unserialize($data);

        return new Lesti_Fpc_Model_Fpc_CacheItem($data[0], $data[1], $data[2]);
    }

    /**
     * Clean cached data by specific tag
     *
     * @param   array $tags
     * @return  bool
     */
    public function clean($tags=array())
    {
        $mode = Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG;
        if (!empty($tags)) {
            if (!is_array($tags)) {
                $tags = array($tags);
            }
            $res = $this->_frontend->clean($mode, $this->_tags($tags));
        } else {
            $res = $this->_frontend->clean($mode, array(self::CACHE_TAG));
            $res = $res &&
                $this->_frontend->clean(
                    $mode,
                    array(Mage_Core_Model_Config::CACHE_TAG)
                );
        }
        return $res;
    }

    /**
     * @return bool
     */
    public function isActive()
    {
        return Mage::app()->useCache('fpc');
    }

}


================================================
FILE: app/code/community/Lesti/Fpc/Model/Observer/Clean.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

class Lesti_Fpc_Model_Observer_Clean
{
    const CACHE_TYPE = 'fpc';

    /**
     * Cron job method to clean old cache resources
     */
    public function coreCleanCache()
    {
        $this->_getFpc()->getFrontend()->clean(Zend_Cache::CLEANING_MODE_OLD);
    }

    public function adminhtmlCacheFlushAll()
    {
        $this->_getFpc()->clean();
    }

    public function controllerActionPredispatchAdminhtmlCacheMassRefresh()
    {
        $types = Mage::app()->getRequest()->getParam('types');
        if ($this->_getFpc()->isActive()) {
            if ((is_array($types) && in_array(self::CACHE_TYPE, $types)) ||
                $types == self::CACHE_TYPE) {
                $this->_getFpc()->clean();
            }
        }
    }

    /**
     * @return Lesti_Fpc_Model_Fpc
     */
    protected function _getFpc()
    {
        return Mage::getSingleton('fpc/fpc');
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Model/Observer/Parameters.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Model_Observer_Parameters
 */
class Lesti_Fpc_Model_Observer_Parameters
{
    const XML_PATH_SESSION_PARAMS = 'system/fpc/session_params';

    /**
     * @param $observer
     */
    public function fpcHelperCollectParams($observer)
    {
        $params = array();
        // store
        $storeCode = Mage::app()->getStore(true)->getCode();
        if ($storeCode) {
            $params['store'] = $storeCode;
        }
        // currency
        $currencyCode = Mage::app()->getStore()->getCurrentCurrencyCode();
        if ($currencyCode) {
            $params['currency'] = $currencyCode;
        }
        // design
        $design = Mage::getDesign();
        $params['design'] = $design->getPackageName().'_'.
            $design->getTheme('template');
        // session paramaters
        /** @var Lesti_Fpc_Helper_Data $helper */
        $helper = Mage::helper('fpc');
        if ($helper->getFullActionName() === 'catalog_category_view') {
            $sessionParams = $this->_getSessionParams();
            $catalogSession = Mage::getSingleton('catalog/session');
            foreach ($sessionParams as $param) {
                if ($data = $catalogSession->getData($param)) {
                    $params['session_' . $param] = $data;
                }
            }
        }

        $parameters = $observer->getEvent()->getParameters();
        $additionalParams = $parameters->getValue();
        $additionalParams = array_merge($additionalParams, $params);
        $parameters->setValue($additionalParams);
    }

    /**
     * @return array
     */
    protected function _getSessionParams()
    {
        $helper = Mage::helper('fpc');
        return $helper->getCSStoreConfigs(self::XML_PATH_SESSION_PARAMS);
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Model/Observer/Save.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Model_Observer_Save
 */
class Lesti_Fpc_Model_Observer_Save
{
    const PRODUCT_IDS_MASS_ACTION_KEY = 'fpc_product_ids_mass_action';

    /**
     * @param $observer
     */
    public function catalogProductSaveAfter($observer)
    {
        if ($this->_getFpc()->isActive()) {
            $product = $observer->getEvent()->getProduct();
            if ($product->getId()) {
                $this->_getFpc()->clean(sha1('product_' . $product->getId()));

                $origData = $product->getOrigData();
                if (empty($origData)
                    || (!empty($origData) && $product->dataHasChangedFor('status'))
                ) {
                    $categories = $product->getCategoryIds();
                    foreach ($categories as $categoryId) {
                        $this->_getFpc()->clean(
                            sha1('category_' . $categoryId)
                        );
                    }
                }
            }
        }
    }

    /**
     * @param $observer
     */
    public function catalogCategorySaveAfter($observer)
    {
        if ($this->_getFpc()->isActive()) {
            $category = $observer->getEvent()->getCategory();
            if ($category->getId()) {
                $this->_getFpc()->clean(sha1('category_' . $category->getId()));
            }
        }
    }

    /**
     * @param $observer
     */
    public function cmsPageSaveAfter($observer)
    {
        if ($this->_getFpc()->isActive()) {
            $page = $observer->getEvent()->getObject();
            if ($page->getId()) {
                $tags = array(sha1('cms_' . $page->getId()),
                    sha1('cms_' . $page->getIdentifier()));
                $this->_getFpc()
                    ->clean($tags, Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG);
            }
        }
    }

    /**
     * @param $observer
     */
    public function modelSaveAfter($observer)
    {
        if ($this->_getFpc()->isActive()) {
            $object = $observer->getEvent()->getObject();
            if ($object instanceof Mage_Cms_Model_Block) {
                $this->_cmsBlockSaveAfter($object);
            } elseif ($object instanceof Mage_Index_Model_Event) {
                $dataObject = $object->getDataObject();
                if ($object->getType() === 'mass_action' &&
                    $object->getEntity() === 'catalog_product' &&
                    $dataObject instanceof Mage_Catalog_Model_Product_Action) {
                    $this->_catalogProductSaveAfterMassAction(
                        $dataObject->getProductIds()
                    );
                }
            }
        }
    }

    /**
     * @param $observer
     */
    public function reviewDeleteAfter($observer)
    {
        if ($this->_getFpc()->isActive()) {
            $object = $observer->getEvent()->getObject();
            $this->_getFpc()->clean(sha1('product_' . $object->getEntityPkValue()));
        }
    }

    /**
     * @param $observer
     */
    public function reviewSaveAfter($observer)
    {
        if ($this->_getFpc()->isActive()) {
            $object = $observer->getEvent()->getObject();
            $this->_getFpc()->clean(sha1('product_' . $object->getEntityPkValue()));
        }
    }

    /**
     * @param $observer
     */
    public function cataloginventoryStockItemSaveAfter($observer)
    {
        $item = $observer->getEvent()->getItem();
        if ($item->getStockStatusChangedAuto()) {
            $this->_getFpc()->clean(sha1('product_' . $item->getProductId()));
        }
    }

    /**
     * @return Lesti_Fpc_Model_Fpc
     */
    protected function _getFpc()
    {
        return Mage::getSingleton('fpc/fpc');
    }

    /**
     * @param Mage_Cms_Model_Block $block
     */
    protected function _cmsBlockSaveAfter(Mage_Cms_Model_Block $block)
    {
        $this->_getFpc()->clean(sha1('cmsblock_'.$block->getIdentifier()));
    }

    /**
     * @param array $productIds
     */
    protected function _catalogProductSaveAfterMassAction(array $productIds)
    {
        if (!empty($productIds)) {
            $tags = array();
            foreach ($productIds as $productId) {
                $tags[] = sha1('product_' . $productId);
            }
            $this->_getFpc()->clean($tags);
        }
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Model/Observer/Tags.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Model_Observer_Tags
 */
class Lesti_Fpc_Model_Observer_Tags
{
    /**
     * @param $observer
     */
    public function fpcObserverCollectCacheTags($observer)
    {
        /** @var Lesti_Fpc_Helper_Data $helper */
        $helper = Mage::helper('fpc');
        $fullActionName = $helper->getFullActionName();
        $cacheTags = array();
        $request = Mage::app()->getRequest();
        switch ($fullActionName) {
            case 'cms_index_index' :
                $cacheTags = $this->getCmsIndexIndexCacheTags();
                break;
            case 'cms_page_view' :
                $cacheTags = $this->getCmsPageViewCacheTags($request);
                break;
            case 'catalog_product_view' :
                $cacheTags = $this->getCatalogProductViewCacheTags($request);
                break;
            case 'catalog_category_view' :
                $cacheTags = $this->getCatalogCategoryViewCacheTags($request);
                break;
        }

        $cacheTagObject = $observer->getEvent()->getCacheTags();
        $additionalCacheTags = $cacheTagObject->getValue();
        $additionalCacheTags = array_merge($additionalCacheTags, $cacheTags);
        $cacheTagObject->setValue($additionalCacheTags);
    }

    /**
     * @return array
     */
    protected function getCmsIndexIndexCacheTags()
    {
        $cacheTags = array();
        $cacheTags[] = sha1('cms');
        $pageId = Mage::getStoreConfig(
            Mage_Cms_Helper_Page::XML_PATH_HOME_PAGE
        );
        if ($pageId) {
            $cacheTags[] = sha1('cms_' . $pageId);
        }
        return $cacheTags;
    }

    /**
     * @param Mage_Core_Controller_Request_Http $request
     * @return array
     */
    protected function getCmsPageViewCacheTags(
        Mage_Core_Controller_Request_Http $request
    )
    {
        $cacheTags = array();
        $cacheTags[] = sha1('cms');
        $pageId = $request->getParam(
            'page_id',
            $request->getParam('id', false)
        );
        if ($pageId) {
            $cacheTags[] = sha1('cms_' . $pageId);
        }
        return $cacheTags;
    }

    /**
     * @param Mage_Core_Controller_Request_Http $request
     * @return array
     */
    protected function getCatalogProductViewCacheTags(
        Mage_Core_Controller_Request_Http $request
    )
    {
        $cacheTags = array();
        $cacheTags[] = sha1('product');
        $productId = (int)$request->getParam('id');
        if ($productId) {
            $cacheTags[] = sha1('product_' . $productId);

            // configurable product
            $configurableProduct = Mage::getModel(
                'catalog/product_type_configurable'
            );
            // get all childs of this product and add the cache tag
            $childIds = $configurableProduct->getChildrenIds($productId);
            foreach ($childIds as $childIdGroup) {
                foreach ($childIdGroup as $childId) {
                    $cacheTags[] = sha1('product_' . $childId);
                }
            }
            // get all parents of this product and add the cache tag
            $parentIds = $configurableProduct
                ->getParentIdsByChild($productId);
            foreach ($parentIds as $parentId) {
                $cacheTags[] = sha1('product_' . $parentId);
            }

            // grouped product
            $groupedProduct = Mage::getModel('catalog/product_type_grouped');
            // get all childs of this product and add the cache tag
            $childIds = $groupedProduct->getChildrenIds($productId);
            foreach ($childIds as $childIdGroup) {
                foreach ($childIdGroup as $childId) {
                    $cacheTags[] = sha1('product_' . $childId);
                }
            }
            // get all parents of this product and add the cache tag
            $parentIds = $groupedProduct->getParentIdsByChild($productId);
            foreach ($parentIds as $parentId) {
                $cacheTags[] = sha1('product_' . $parentId);
            }

            $categoryId = (int)$request->getParam('category', false);
            if ($categoryId) {
                $cacheTags[] = sha1('category');
                $cacheTags[] = sha1('category_' . $categoryId);
            }
        }
        return $cacheTags;
    }

    /**
     * @param Mage_Core_Controller_Request_Http $request
     * @return array
     */
    protected function getCatalogCategoryViewCacheTags(
        Mage_Core_Controller_Request_Http $request
    )
    {
        $cacheTags = array();
        $cacheTags[] = sha1('category');
        $categoryId = (int)$request->getParam('id', false);
        if ($categoryId) {
            $cacheTags[] = sha1('category_' . $categoryId);
        }
        return $cacheTags;
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Model/Observer.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Model_Observer
 */
class Lesti_Fpc_Model_Observer
{
    const CUSTOMER_SESSION_REGISTRY_KEY = 'fpc_customer_session';
    const SHOW_AGE_XML_PATH = 'system/fpc/show_age';
    const FORM_KEY_PLACEHOLDER = '<!-- fpc form_key_placeholder -->';
    const SESSION_ID_PLACEHOLDER = '<!-- fpc session_id_placeholder -->';

    protected $_cached = false;
    protected $_html = array();
    protected $_placeholder = array();
    protected $_cacheTags = array();

    /**
     * @param $observer
     * @SuppressWarnings(PHPMD.ExitExpression)
     */
    public function controllerActionLayoutGenerateBlocksBefore($observer)
    {
        if ($this->_getFpc()->isActive() &&
            !$this->_cached &&
            Mage::helper('fpc')->canCacheRequest()) {
            $key = Mage::helper('fpc')->getKey();
            if ($object = $this->_getFpc()->load($key)) {
                $time = $object->getTime();
                $body = $object->getContent();
                $this->_cached = true;
                $session = Mage::getSingleton('customer/session');
                $lazyBlocks = Mage::helper('fpc/block')->getLazyBlocks();
                $dynamicBlocks = Mage::helper('fpc/block')->getDynamicBlocks();
                $blockHelper = Mage::helper('fpc/block');
                if ($blockHelper->areLazyBlocksValid()) {
                    foreach ($lazyBlocks as $blockName) {
                        $this->_placeholder[] = $blockHelper
                            ->getPlaceholderHtml($blockName);
                        $this->_html[] = $session
                            ->getData('fpc_lazy_block_' . $blockName);
                    }
                } else {
                    $dynamicBlocks = array_merge($dynamicBlocks, $lazyBlocks);
                }
                // prepare Layout
                $layout = $this->_prepareLayout(
                    $observer->getEvent()->getLayout(),
                    $dynamicBlocks
                );
                // insert dynamic blocks
                $this->_insertDynamicBlocks(
                    $layout,
                    $session,
                    $dynamicBlocks,
                    $lazyBlocks
                );
                $this->_placeholder[] = self::SESSION_ID_PLACEHOLDER;
                $this->_html[] = $session->getEncryptedSessionId();
                $this->_replaceFormKey();
                $body = str_replace($this->_placeholder, $this->_html, $body);
                if (Mage::getStoreConfig(self::SHOW_AGE_XML_PATH)) {
                    Mage::app()->getResponse()->setHeader('Age', time() - $time);
                }
                Mage::app()->getResponse()->setHeader('Content-Type', $object->getContentType(), true);
                $response = Mage::app()->getResponse();
                $response->setBody($body);
                Mage::dispatchEvent(
                    'fpc_http_response_send_before',
                    array('response' => $response)
                );
                $response->sendResponse();
                exit;
            }
            if (Mage::getStoreConfig(self::SHOW_AGE_XML_PATH)) {
                Mage::app()->getResponse()->setHeader('Age', 0);
            }
        }
    }

    /**
     * @param $observer
     */
    public function httpResponseSendBefore($observer)
    {
        $response = $observer->getEvent()->getResponse();
        if ($this->_getFpc()->isActive() &&
            !$this->_cached &&
            Mage::helper('fpc')->canCacheRequest() &&
            $response->getHttpResponseCode() == 200) {
            $fullActionName = Mage::helper('fpc')->getFullActionName();
            $cacheableActions = Mage::helper('fpc')->getCacheableActions();
            if (in_array($fullActionName, $cacheableActions)) {
                $key = Mage::helper('fpc')->getKey();
                $body = $observer->getEvent()->getResponse()->getBody();
                $session = Mage::getSingleton('core/session');
                $formKey = $session->getFormKey();
                if ($formKey) {
                    $body = str_replace(
                        $formKey,
                        self::FORM_KEY_PLACEHOLDER,
                        $body
                    );
                    $this->_placeholder[] = self::FORM_KEY_PLACEHOLDER;
                    $this->_html[] = $formKey;
                }
                $sid = $session->getEncryptedSessionId();
                if ($sid) {
                    $body = str_replace(
                        $sid,
                        self::SESSION_ID_PLACEHOLDER,
                        $body
                    );
                    $this->_placeholder[] = self::SESSION_ID_PLACEHOLDER;
                    $this->_html[] = $sid;
                }
                // edit cacheTags via event
                $cacheTags = new Varien_Object();
                $cacheTags->setValue($this->_cacheTags);
                Mage::dispatchEvent(
                    'fpc_observer_collect_cache_tags',
                    array('cache_tags' => $cacheTags)
                );
                $this->_cacheTags = $cacheTags->getValue();
                $this->_getFpc()->save(
                    new Lesti_Fpc_Model_Fpc_CacheItem($body, time(), Mage::helper('fpc')->getContentType($response)),
                    $key,
                    $this->_cacheTags
                );
                $this->_cached = true;
                $body = str_replace($this->_placeholder, $this->_html, $body);
                $observer->getEvent()->getResponse()->setBody($body);
            }
        }
    }

    /**
     * @param $observer
     */
    public function coreBlockAbstractToHtmlAfter($observer)
    {
        if ($this->_getFpc()->isActive() &&
            !$this->_cached &&
            Mage::helper('fpc')->canCacheRequest()) {
            $fullActionName = Mage::helper('fpc')->getFullActionName();
            $block = $observer->getEvent()->getBlock();
            $blockName = $block->getNameInLayout();
            $dynamicBlocks = Mage::helper('fpc/block')->getDynamicBlocks();
            $lazyBlocks = Mage::helper('fpc/block')->getLazyBlocks();
            $dynamicBlocks = array_merge($dynamicBlocks, $lazyBlocks);
            $cacheableActions = Mage::helper('fpc')->getCacheableActions();
            if (in_array($fullActionName, $cacheableActions)) {
                $this->_cacheTags = array_merge(
                    Mage::helper('fpc/block')->getCacheTags($block),
                    $this->_cacheTags
                );
                if (in_array($blockName, $dynamicBlocks)) {
                    $placeholder = Mage::helper('fpc/block')
                        ->getPlaceholderHtml($blockName);
                    $html = $observer->getTransport()->getHtml();
                    $this->_html[] = $html;
                    $this->_placeholder[] = $placeholder;
                    $observer->getTransport()->setHtml($placeholder);
                }
            }
        }
    }

    public function controllerActionPostdispatch()
    {
        if ($this->_getFpc()->isActive()) {
            $fullActionName = Mage::helper('fpc')->getFullActionName();
            if (in_array(
                $fullActionName,
                Mage::helper('fpc')->getRefreshActions()
            )) {
                $session = Mage::getSingleton('customer/session');
                $session->setData(
                    Lesti_Fpc_Helper_Block::LAZY_BLOCKS_VALID_SESSION_PARAM,
                    false
                );
            }
        }
    }

    /**
     * @return Lesti_Fpc_Model_Fpc
     */
    protected function _getFpc()
    {
        return Mage::getSingleton('fpc/fpc');
    }

    /**
     * @param Mage_Core_Model_Layout $layout
     * @param array $dynamicBlocks
     * @return Mage_Core_Model_Layout
     */
    protected function _prepareLayout(
        Mage_Core_Model_Layout $layout,
        array $dynamicBlocks
    )
    {
        $xml = $layout->getNode();
        $cleanXml = simplexml_load_string(
            '<layout/>',
            Lesti_Fpc_Helper_Data::LAYOUT_ELEMENT_CLASS
        );
        $types = array('block', 'reference', 'action');
        foreach ($dynamicBlocks as $blockName) {
            foreach ($types as $type) {
                $xPath = $xml->xpath(
                    "//" . $type . "[@name='" . $blockName . "']"
                );
                foreach ($xPath as $child) {
                    $cleanXml->appendChild($child);
                }
            }
        }
        $layout->setXml($cleanXml);
        $layout->generateBlocks();
        return Mage::helper('fpc/block_messages')
            ->initLayoutMessages($layout);
    }

    protected function _replaceFormKey()
    {
        $coreSession = Mage::getSingleton('core/session');
        $formKey = $coreSession->getFormKey();
        if ($formKey) {
            $this->_placeholder[] = self::FORM_KEY_PLACEHOLDER;
            $this->_html[] = $formKey;
        }
    }

    /**
     * @param Mage_Core_Model_Layout $layout
     * @param Mage_Customer_Model_Session $session
     * @param array $dynamicBlocks
     * @param array $lazyBlocks
     */
    protected function _insertDynamicBlocks(
        Mage_Core_Model_Layout &$layout,
        Mage_Customer_Model_Session &$session,
        array &$dynamicBlocks,
        array &$lazyBlocks
    )
    {
        foreach ($dynamicBlocks as $blockName) {
            $block = $layout->getBlock($blockName);
            if ($block) {
                $this->_placeholder[] = Mage::helper('fpc/block')
                    ->getPlaceholderHtml($blockName);
                $html = $block->toHtml();
                if (in_array($blockName, $lazyBlocks)) {
                    $session->setData('fpc_lazy_block_' . $blockName, $html);
                }
                $this->_html[] = $html;
            }
        }
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax/fixtures/get_ajax_url.yaml
================================================
config:
    default/system/fpc/cache_actions: catalog_product_view
    default/system/fpc/use_recently_viewed_products: 1
    default/web/unsecure/base_link_url: http://magento.dev/


================================================
FILE: app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax/fixtures/get_ajax_url_disabled_recently_viewed_products.yaml
================================================
config:
    default/system/fpc/cache_actions: catalog_product_view
    default/system/fpc/use_recently_viewed_products: 0


================================================
FILE: app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax/fixtures/get_ajax_url_fpc_inactive.yaml
================================================
config:
    default/system/fpc/cache_actions: catalog_product_view
    default/system/fpc/use_recently_viewed_products: 1


================================================
FILE: app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax/fixtures/get_ajax_url_miss_cache_able_action.yaml
================================================
config:
    default/system/fpc/cache_actions:
    default/system/fpc/use_recently_viewed_products: 1


================================================
FILE: app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax/fixtures/get_ajax_url_no_current_product.yaml
================================================
config:
    default/system/fpc/cache_actions: catalog_product_view
    default/system/fpc/use_recently_viewed_products: 1


================================================
FILE: app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Test_Block_Catalog_Product_View_Ajax
 */
class Lesti_Fpc_Test_Block_Catalog_Product_View_Ajax extends
    Lesti_Fpc_Test_TestCase
{
    /**
     * @var Lesti_Fpc_Block_Catalog_Product_View_Ajax
     */
    protected $_catalogProductViewAjaxBlock;

    protected function setUp()
    {
        parent::setUp();
        $this->_catalogProductViewAjaxBlock =
            new Lesti_Fpc_Block_Catalog_Product_View_Ajax();
        // register a product
        $product = new Mage_Catalog_Model_Product();
        $product->setId(5);
        Mage::register('current_product', $product);
    }

    protected function tearDown()
    {
        parent::tearDown();
        Mage::unregister('current_product');
    }

    /**
     * @test
     * @loadFixture get_ajax_url_fpc_inactive.yaml
     */
    public function testGetAjaxUrlFpcInactive()
    {
        Mage::app()->getCacheInstance()->banUse('fpc');
        $this->assertFalse($this->_catalogProductViewAjaxBlock->getAjaxUrl());
    }

    /**
     * @test
     * @loadFixture get_ajax_url_miss_cache_able_action.yaml
     */
    public function testGetAjaxUrlMissCacheAbleAction()
    {
        $this->assertFalse($this->_catalogProductViewAjaxBlock->getAjaxUrl());
    }

    /**
     * @test
     * @loadFixture get_ajax_url_disabled_recently_viewed_products.yaml
     */
    public function testGetAjaxUrlDisabledRecentlyViewedProducts()
    {
        $this->assertFalse($this->_catalogProductViewAjaxBlock->getAjaxUrl());
    }

    /**
     * @test
     * @loadFixture get_ajax_url_no_current_product.yaml
     */
    public function testGetAjaxUrlNoCurrentProduct()
    {
        Mage::unregister('current_product');
        $this->assertFalse($this->_catalogProductViewAjaxBlock->getAjaxUrl());
    }

    /**
     * @test
     * @loadFixture get_ajax_url.yaml
     */
    public function testGetAjaxUrl()
    {
        // clean baseUrlCache of Model/Store
        $this->clearBaseUrlProperty();
        $session = Mage::getSingleton('core/session');
        $sid = $session->getEncryptedSessionId();
        $expectedUrl = 'http://magento.dev/fpc/catalog_product/view/id/5/';
        if ($sid) {
            $expectedUrl .= '?'.$session->getSessionIdQueryParam().'='.$sid;
        }

        $this->assertEquals(
            $expectedUrl,
            $this->_catalogProductViewAjaxBlock->getAjaxUrl()
        );
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Test/Block/Core/Messages.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Test_Block_Core_Messages
 */
class Lesti_Fpc_Test_Block_Core_Messages extends Lesti_Fpc_Test_TestCase
{
    /**
     * @var Lesti_Fpc_Core_Block_Messages
     */
    protected $_messagesBlock;

    protected function setUp()
    {
        parent::setUp();
        $this->_messagesBlock = Mage::app()->getLayout()
            ->createBlock('core/messages');
    }

    /**
     * @test
     */
    public function testGetGroupedHtml()
    {
        $this->assertInstanceOf(
            'Lesti_Fpc_Core_Block_Messages',
            $this->_messagesBlock
        );
        $parentClass = get_parent_class($this->_messagesBlock);
        /** @var Mage_Core_Block_Messages $coreMessagesBlock */
        $coreMessagesBlock = new $parentClass;
        $this->assertInstanceOf(
            'Mage_Core_Block_Messages',
            $coreMessagesBlock
        );
        $expectedGroupHtml = $coreMessagesBlock->getGroupedHtml();
        $this->assertEquals(
            $expectedGroupHtml,
            $this->_messagesBlock->getGroupedHtml()
        );
        $this->assertEventDispatched(
            'core_block_messages_get_grouped_html_after'
        );
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Test/Controller/Catalog/ProductController/fixtures/view_action_with_product.yaml
================================================
tables:
  eav_attribute_set:
    - attribute_set_id: 13
      entity_type_id: 4
  catalog_product_entity:
    - entity_id: 5
      entity_type_id: 4
      attribute_set_id: 13


================================================
FILE: app/code/community/Lesti/Fpc/Test/Controller/Catalog/ProductController.php
================================================
<?php
/**
 * Created by JetBrains PhpStorm.
 * User: gordon
 * Date: 10/19/14
 * Time: 1:56 PM
 * To change this template use File | Settings | File Templates.
 */

/**
 * Class Lesti_Fpc_Test_Controller_Catalog_ProductController
 */
class Lesti_Fpc_Test_Controller_Catalog_ProductController extends
    Lesti_Fpc_Test_TestCase
{
    /**
     * @test
     */
    public function testViewActionWithoutProduct()
    {
        $this->dispatch('fpc/catalog_product/view');
        $this->assertEventNotDispatched('catalog_controller_product_view');
    }

    /**
     * @test
     * @loadFixture view_action_with_product.yaml
     */
    public function testViewActionWithProduct()
    {
        Mage::app()->getRequest()->setParam('id', 5);
        $this->dispatch('fpc/catalog_product/view');
        $this->assertEventDispatched('catalog_controller_product_view');
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Block/Messages.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Test_Helper_Block_Messages
 */
class Lesti_Fpc_Test_Helper_Block_Messages extends Lesti_Fpc_Test_TestCase
{
    /**
     * @var Lesti_Fpc_Helper_Block_Messages
     */
    protected $_messagesHelper;

    protected function setUp()
    {
        parent::setUp();
        $this->_messagesHelper = Mage::helper('fpc/block_messages');
    }

    /**
     * @test
     */
    public function testInitLayoutMessagesEmpty()
    {
        $layout = Mage::app()->getLayout();
        $this->_messagesHelper->initLayoutMessages($layout);
        $this->assertEmpty($layout->getMessagesBlock()->getMessages());
    }

    /**
     * @test
     */
    public function testInitLayoutMessagesCatalog()
    {
        $layout = Mage::app()->getLayout();
        /** @var Mage_Catalog_Model_Session $catalogStorage */
        $catalogStorage = Mage::getSingleton('catalog/session');
        $catalogStorage->addSuccess('Fpc is cool.');
        $catalogStorage->addError('Fpc has no errors.');
        $this->assertInstanceOf(
            'Mage_Core_Model_Layout',
            $this->_messagesHelper->initLayoutMessages($layout)
        );

        // test if session is now empty
        $this->assertEquals(0, $catalogStorage->getMessages()->count());
        $messages = $layout->getMessagesBlock()->getMessages();
        $this->assertCount(2, $messages);
    }

    /**
     * @test
     */
    public function testInitLayoutMessagesTag()
    {
        $layout = Mage::app()->getLayout();
        /** @var Mage_Tag_Model_Session $tagStorage */
        $tagStorage = Mage::getSingleton('tag/session');
        $tagStorage->addSuccess('Fpc is cool.');
        $tagStorage->addError('Fpc has no errors.');
        $this->assertInstanceOf(
            'Mage_Core_Model_Layout',
            $this->_messagesHelper->initLayoutMessages($layout)
        );

        // test if session is now empty
        $this->assertEquals(0, $tagStorage->getMessages()->count());
        $messages = $layout->getMessagesBlock()->getMessages();
        $this->assertCount(2, $messages);
    }

    /**
     * @test
     */
    public function testInitLayoutMessagesCheckout()
    {
        $layout = Mage::app()->getLayout();
        /** @var Mage_Checkout_Model_Session $checkoutStorage */
        $checkoutStorage = Mage::getSingleton('checkout/session');
        $checkoutStorage->addSuccess('Fpc is cool.');
        $checkoutStorage->addError('Fpc has no errors.');
        $this->assertInstanceOf(
            'Mage_Core_Model_Layout',
            $this->_messagesHelper->initLayoutMessages($layout)
        );

        // test if session is now empty
        $this->assertEquals(0, $checkoutStorage->getMessages()->count());
        $messages = $layout->getMessagesBlock()->getMessages();
        $this->assertCount(2, $messages);
    }

    /**
     * @test
     */
    public function testInitLayoutMessagesCustomer()
    {
        $layout = Mage::app()->getLayout();
        /** @var Mage_Customer_Model_Session $customerStorage */
        $customerStorage = Mage::getSingleton('customer/session');
        $customerStorage->addSuccess('Fpc is cool.');
        $customerStorage->addError('Fpc has no errors.');
        $this->assertInstanceOf(
            'Mage_Core_Model_Layout',
            $this->_messagesHelper->initLayoutMessages($layout)
        );

        // test if session is now empty
        $this->assertEquals(0, $customerStorage->getMessages()->count());
        $messages = $layout->getMessagesBlock()->getMessages();
        $this->assertCount(2, $messages);
    }

    /**
     * @test
     * @expectedException Mage_Core_exception
     * @expectedExceptionMessage Invalid messages storage "fpc/session"
     * for layout messages initialization
     */
    public function testInitLayoutInvalidStorage()
    {
        $layout = Mage::app()->getLayout();
        $this->_messagesHelper
            ->initLayoutMessages($layout, array('fpc/session'));
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/are_lazy_blocks_valid.yaml
================================================
tables:
  customer_entity:
    - entity_id: 1
    - group_id: 78


================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/get_dynamic_blocks.yaml
================================================
config:
    default/system/fpc/dynamic_blocks: >
     messages,
     global_messages, global_notices
      , global_messages


================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/get_dynamic_blocks_empty.yaml
================================================
config:
    default/system/fpc/dynamic_blocks: " "


================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/get_lazy_blocks.yaml
================================================
config:
    default/system/fpc/lazy_blocks: >
     top.links,
     cart_sidebar, catalog.compare.sidebar
      , cart_sidebar


================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/get_lazy_blocks_empty.yaml
================================================
config:
    default/system/fpc/lazy_blocks: " "


================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/use_recently_viewed_products_false.yaml
================================================
config:
    default/system/fpc/use_recently_viewed_products: 0

================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/use_recently_viewed_products_true.yaml
================================================
config:
    default/system/fpc/use_recently_viewed_products: 1

================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Block.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Test_Helper_Block
 *
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
 */
class Lesti_Fpc_Test_Helper_Block extends Lesti_Fpc_Test_TestCase
{
    /**
     * @var Lesti_Fpc_Helper_Block
     */
    protected $_blockHelper;

    protected function setUp()
    {
        parent::setUp();
        $this->_blockHelper = Mage::helper('fpc/block');
    }

    /**
     * @test
     * @loadFixture get_dynamic_blocks.yaml
     */
    public function testGetDynamicBlocks()
    {
        $this->assertEquals(
            array('messages', 'global_messages', 'global_notices'),
            $this->_blockHelper->getDynamicBlocks()
        );
    }

    /**
     * @test
     * @loadFixture get_dynamic_blocks_empty.yaml
     */
    public function testGetDynamicBlocksEmpty()
    {
        $this->assertEquals(array(), $this->_blockHelper->getDynamicBlocks());
    }

    /**
     * @test
     * @loadFixture get_lazy_blocks.yaml
     */
    public function testGetLazyBlocks()
    {
        $this->assertEquals(
            array('top.links', 'cart_sidebar', 'catalog.compare.sidebar'),
            $this->_blockHelper->getLazyBlocks()
        );
    }

    /**
     * @test
     * @loadFixture get_lazy_blocks_empty.yaml
     */
    public function testGetLazyBlocksEmpty()
    {
        $this->assertEquals(array(), $this->_blockHelper->getLazyBlocks());
    }

    /**
     * @test
     * @loadFixture are_lazy_blocks_valid.yaml
     */
    public function testAreLazyBlocksValid()
    {
        // initial should return false
        $this->assertFalse($this->_blockHelper->areLazyBlocksValid());
        // hash should be set and return true
        $this->assertTrue($this->_blockHelper->areLazyBlocksValid());

        // edit host
        $_SERVER['HTTP_HOST'] = 'fpc.dev';
        $this->assertFalse($this->_blockHelper->areLazyBlocksValid());
        $this->assertTrue($this->_blockHelper->areLazyBlocksValid());

        // edit port
        $_SERVER['SERVER_PORT'] = '80';
        $this->assertFalse($this->_blockHelper->areLazyBlocksValid());
        $this->assertTrue($this->_blockHelper->areLazyBlocksValid());

        // edit store code
        $storeCode = Mage::app()->getStore()->getCode();
        Mage::app()->getStore()->setCode('fpc');
        $this->assertFalse($this->_blockHelper->areLazyBlocksValid());
        $this->assertTrue($this->_blockHelper->areLazyBlocksValid());
        Mage::app()->getStore()->setCode($storeCode);

        // edit currency
        Mage::app()->getStore()->setCurrentCurrencyCode('FPC');
        $this->assertFalse($this->_blockHelper->areLazyBlocksValid());
        $this->assertTrue($this->_blockHelper->areLazyBlocksValid());

        // edit customer session
        /** @var Mage_Customer_Model_Session $customerSession */
        $customerSession = Mage::getSingleton('customer/session');
        if (version_compare(Mage::getVersion(), '1.6.0.0', '<')) {
            $customer = Mage::getModel('customer/customer')->load(1);
            $customerSession->setCustomerAsLoggedIn($customer);
        } else {
            $customerSession->setCustomerGroupId(78);
        }
        $this->assertFalse($this->_blockHelper->areLazyBlocksValid());
        $this->assertTrue($this->_blockHelper->areLazyBlocksValid());

        // edit design package name
        Mage::getDesign()->setPackageName('base');
        $this->assertFalse($this->_blockHelper->areLazyBlocksValid());
        $this->assertTrue($this->_blockHelper->areLazyBlocksValid());

        // edit design theme
        Mage::getDesign()->setTheme('template', 'FPC');
        $this->assertFalse($this->_blockHelper->areLazyBlocksValid());
        $this->assertTrue($this->_blockHelper->areLazyBlocksValid());
    }

    /**
     * @test
     */
    public function testGetPlaceholderHtml()
    {
        $this->assertEquals(
            '<!-- fpc 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 -->',
            $this->_blockHelper->getPlaceholderHtml('foo')
        );
    }

    /**
     * @test
     */
    public function testGetKey()
    {
        $this->assertEquals(
            '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33_block',
            $this->_blockHelper->getKey('foo')
        );
    }

    /**
     * @test
     * @loadFixture use_recently_viewed_products_true.yaml
     */
    public function testUseRecentlyViewedProductsTrue()
    {
        $this->assertTrue($this->_blockHelper->useRecentlyViewedProducts());
    }

    /**
     * @test
     * @loadFixture use_recently_viewed_products_false.yaml
     */
    public function testUseRecentlyViewedProductsFalse()
    {
        $this->assertFalse($this->_blockHelper->useRecentlyViewedProducts());
    }

    /**
     * @test
     */
    public function testGetCacheTagsEmpty()
    {
        $block = new Mage_Core_Block_Template();
        $block->setNameInLayout('foo');
        $this->assertEquals(array(), $this->_blockHelper->getCacheTags($block));
    }

    /**
     * @test
     */
    public function testGetCacheTagsProductList()
    {
        $productOne = new Mage_Catalog_Model_Product();
        $productOne->setId(1);
        $productTwo = new Mage_Catalog_Model_Product();
        $productTwo->setId(2);
        $block = new Mage_Core_Block_Template();
        $block->setNameInLayout('product_list');
        $block->setLoadedProductCollection(array($productOne, $productTwo));
        $this->assertEquals(
            array(
                '38a007151abe87cc01a5b6e9cc418e85286e2087', // sha1('product')
                '65dd4967fe508e9ebad619a8c976beabf46588fe', // sha1('product_1')
                '499ed21cb19c984d31e23b94a60730520afa8181' // sha1('product_2')
            ),
            $this->_blockHelper->getCacheTags($block)
        );
    }

    /**
     * @test
     */
    public function testGetCacheTagsCmsBlock()
    {
        $block = new Mage_Cms_Block_Block();
        $block->setNameInLayout('foo');
        $block->setId(5);
        $this->assertEquals(
            array(
                '74709cfbbdffe24885db05ff5d08ea9c13663422',
                'ba750b74090c01fda30a383d301af7e15b340928'
            ),
            $this->_blockHelper->getCacheTags($block)
        );
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/can_cache_request.yaml
================================================
config:
    default/system/fpc/miss_uri_params: >
     no_cache=/^1$/,
     limit=/^([0-9]+)|(all)$/, dir=/^[0-9a-z_]+$/
      , limit=/^([0-9]+)|(all)$/,
     order


================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/get_bypass_handles.yaml
================================================
config:
    default/system/fpc/bypass_handles: >
     some_handle,
     logged_in, CATEGORY_25
      , some_handle


================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/get_bypass_handles_empty.yaml
================================================
config:
    default/system/fpc/bypass_handles: " "


================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/get_cacheable_actions.yaml
================================================
config:
    default/system/fpc/cache_actions: >
     cms_index_index,
     cms_page_view, catalog_product_view
      , cms_page_view


================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/get_cacheable_actions_empty.yaml
================================================
config:
    default/system/fpc/cache_actions: " "


================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/get_refresh_actions.yaml
================================================
config:
    default/system/fpc/refresh_actions: >
     checkout_cart_add,
     checkout_cart_delete, checkout_cart_updatePost
      , checkout_cart_delete


================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/get_refresh_actions_empty.yaml
================================================
config:
    default/system/fpc/refresh_actions: " "


================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/regex_uri_params.yaml
================================================
config:
    default/system/fpc/uri_params: id,/^filter_\w+/,order

================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Data/providers/testCanCacheRequest.yaml
================================================
test_post:
  method: POST
  expected: 0
test_no_cache_1:
  method: GET
  expected: 0
  params:
    no_cache: 1
test_limit_digit:
  method: GET
  expected: 0
  params:
    limit: 55
test_limit_all:
  method: GET
  expected: 0
  params:
    limit: all
test_success:
  method: get
  expected: 1
  params:
    no_cache: 12
    order: 4
    limit: Fpc


================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Data/providers/testRegexUriParams.yaml
================================================
test_matched_param:
  uri_params:
    -
      id: 1
    -
      id: 1
      filter_1_attribute: filter_1_value_1
    -
      id: 1
      filter_1_attribute: filter_1_value_2
  expected_count: 3
test_not_matched_param:
  uri_params:
    -
      id: 1
    -
      id: 1
      no_filter_1_attribute: filter_1_value_1
    -
      id: 1
      no_filter_1_attribute: filter_1_value_2
  expected_count: 1
test_multiple_matched_params:
  uri_params:
    -
      id: 1
    -
      id: 1
      filter_1_attribute: filter_1_value_1
    -
      id: 1
      filter_2_attribute: filter_2_value_1
    -
      id: 1
      filter_1_attribute: filter_1_value_1
      filter_2_attribute: filter_2_value_1
    -
      id: 1
      filter_1_attribute: filter_1_value_1
      filter_2_attribute: filter_2_value_2
    -
      id: 1
      filter_1_attribute: filter_1_value_2
      filter_2_attribute: filter_2_value_1
    -
      id: 1
      filter_1_attribute: filter_1_value_2
      filter_2_attribute: filter_2_value_2
  expected_count: 7


================================================
FILE: app/code/community/Lesti/Fpc/Test/Helper/Data.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Test case for Lesti_Fpc_Helper_Data
 */
class Lesti_Fpc_Test_Helper_Data extends Lesti_Fpc_Test_TestCase
{
    /**
     * @var Lesti_Fpc_Helper_Data
     */
    protected $_helper;

    protected function setUp()
    {
        parent::setUp();
        $this->_helper = Mage::helper('fpc');
    }

    /**
     * @test
     * @loadFixture get_cacheable_actions.yaml
     */
    public function testGetCacheableActions()
    {
        $this->assertEquals(
            array('cms_index_index', 'cms_page_view', 'catalog_product_view'),
            $this->_helper->getCacheableActions()
        );
    }

    /**
     * @test
     * @loadFixture get_cacheable_actions_empty.yaml
     */
    public function testGetCacheableActionsEmpty()
    {
        $this->assertEquals(array(), $this->_helper->getCacheableActions());
    }

    /**
     * @test
     * @loadFixture get_bypass_handles.yaml
     */
    public function testGetBypassHandles()
    {
        $this->assertEquals(
            array('some_handle', 'logged_in', 'CATEGORY_25'),
            $this->_helper->getBypassHandles()
        );
    }

    /**
     * @test
     * @loadFixture get_bypass_handles_empty.yaml
     */
    public function testGetBypassHandlesEmpty()
    {
        $this->assertEquals(array(), $this->_helper->getBypassHandles());
    }

    /**
     * @test
     * @loadFixture get_refresh_actions.yaml
     */
    public function testGetRefreshActions()
    {
        $this->assertEquals(
            array(
                'checkout_cart_add',
                'checkout_cart_delete',
                'checkout_cart_updatePost'
            ),
            $this->_helper->getRefreshActions()
        );
    }

    /**
     * @test
     * @loadFixture get_refresh_actions_empty.yaml
     */
    public function testGetRefreshActionsEmpty()
    {
        $this->assertEquals(array(), $this->_helper->getRefreshActions());
    }

    /**
     * Test that URI params can be matched by RegEx
     *
     * @test
     * @loadFixture regex_uri_params.yaml
     * @dataProvider dataProvider
     */
    public function testRegexUriParams(
        $uriParamSets = array(),
        $expectedCount = 0
    )
    {
        $actualKeys = array();
        foreach ($uriParamSets as $uriParams) {
            $this->_resetParams();
            Mage::app()->getRequest()->setParams($uriParams);
            $actualKeys[] = $this->_helper->getKey();
        }
        $this->assertCount(
            $expectedCount,
            array_unique($actualKeys),
            sprintf('%d different keys expected', $expectedCount)
        );
    }

    /**
     * @test
     * @loadFixture can_cache_request.yaml
     * @dataProvider dataProvider
     */
    public function testCanCacheRequest($method, $expected, $params = array())
    {
        Mage::app()->getRequest()->clearParams();
        Mage::app()->getRequest()->setMethod($method);
        Mage::app()->getRequest()->setParams($params);
        $this->assertEquals(
            (bool) $expected,
            $this->_helper->canCacheRequest()
        );
    }

    /**
     * @test
     */
    public function getFullActionName()
    {
        Mage::app()->getRequest()->setRouteName('f');
        Mage::app()->getRequest()->setControllerName('p');
        Mage::app()->getRequest()->setActionName('c');
        $this->assertEquals('f_p_c', $this->_helper->getFullActionName());
    }

    /**
     * Reset parameters in Magento request and FPC
     */
    protected function _resetParams()
    {
        if (Mage::registry(Lesti_Fpc_Helper_Data::REGISTRY_KEY_PARAMS)) {
            Mage::unregister(Lesti_Fpc_Helper_Data::REGISTRY_KEY_PARAMS);
        }
        Mage::app()->getRequest()->clearParams();
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Test/Model/Fpc/fixtures/save_load_clean.yaml
================================================
config:
    default/system/fpc/gzcompress_level: 3

================================================
FILE: app/code/community/Lesti/Fpc/Test/Model/Fpc.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Test_Model_Fpc
 */
class Lesti_Fpc_Test_Model_Fpc extends Lesti_Fpc_Test_TestCase
{
    /**
     * @var Lesti_Fpc_Model_Fpc
     */
    protected $_fpc;

    protected function setUp()
    {
        parent::setUp();
        $this->_fpc = Mage::getSingleton('fpc/fpc');
    }

    /**
     * @test
     * @loadFixture save_load_clean.yaml
     */
    public function saveLoadClean()
    {
        $data = new \Lesti_Fpc_Model_Fpc_CacheItem('fpc_data', time(), 'text/html');
        $id = 'fpc_id';
        $tag = 'tag1';

        // check if tag tag1 (clean without array)
        $this->_fpc->save($data, $id, array($tag));
        $this->assertEquals($data, $this->_fpc->load($id));
        $this->_fpc->clean($tag);
        $this->assertFalse($this->_fpc->load($id));

        // check global tag FPC (clean with array)
        $this->_fpc->save($data, $id, array($tag));
        $this->assertEquals($data, $this->_fpc->load($id));
        $this->_fpc->clean(array(Lesti_Fpc_Model_Fpc::CACHE_TAG));
        $this->assertFalse($this->_fpc->load($id));

        // (global clean)
        $this->_fpc->save($data, $id, array($tag));
        $this->assertEquals($data, $this->_fpc->load($id));
        $this->_fpc->clean();
        $this->assertFalse($this->_fpc->load($id));

        // check timeout
        $this->_fpc->save($data, $id, array($tag), 2);
        $this->assertEquals($data, $this->_fpc->load($id));
        sleep(3);
        $this->assertFalse($this->_fpc->load($id));
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Test/Model/Observer/Clean.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Test_Model_Observer_Clean
 */
class Lesti_Fpc_Test_Model_Observer_Clean extends Lesti_Fpc_Test_TestCase
{
    /**
     * @var Lesti_Fpc_Model_Observer_Clean
     */
    protected $_cleanObserver;

    protected function setUp()
    {
        parent::setUp();
        $this->_cleanObserver = Mage::getSingleton('fpc/observer_clean');
    }

    protected function tearDown()
    {
        parent::tearDown();
        Mage::unregister('_singleton/fpc/observer_clean');
    }

    /**
     * @test
     */
    public function testCoreCleanCache()
    {
        $data = new \Lesti_Fpc_Model_Fpc_CacheItem('fpc_old_data', time(), 'text/html');
        $this->_fpc->save($data, 'fpc_old_id', array('fpc'), 1);
        sleep(2);
        $this->_cleanObserver->coreCleanCache();
        $this->assertFalse($this->_fpc->remove('fpc_old_id'));
    }

    /**
     * @test
     */
    public function testAdminhtmlCacheFlushAll()
    {
        $data = new \Lesti_Fpc_Model_Fpc_CacheItem('fpc_old_data', time(), 'text/html');
        $this->_fpc->save($data, 'fpc_id');
        Mage::dispatchEvent('adminhtml_cache_flush_all');
        $this->assertFalse($this->_fpc->remove('fpc_id'));
    }

    /**
     * @test
     */
    public function testControllerActionPredispatchAdminhtmlCacheMassRefresh()
    {
        $data = new \Lesti_Fpc_Model_Fpc_CacheItem('test_data', time(), 'text/html');
        $this->_fpc->save($data, 'test_id');
        Mage::app()->getRequest()->setParam('types', array('core'));
        $this->_cleanObserver->
            controllerActionPredispatchAdminhtmlCacheMassRefresh();
        $this->assertEquals($data, $this->_fpc->load('test_id'));

        $this->_fpc->clean();
        $this->_fpc->save($data, 'test_id');
        Mage::app()->getRequest()->setParam(
            'types',
            array('core', Lesti_Fpc_Model_Observer_Clean::CACHE_TYPE)
        );
        $this->_cleanObserver->
            controllerActionPredispatchAdminhtmlCacheMassRefresh();
        $this->assertFalse($this->_fpc->load('test_id'));

        $this->_fpc->clean();
        $this->_fpc->save($data, 'test_id');
        Mage::app()->getRequest()->setParam(
            'types',
            array('core', Lesti_Fpc_Model_Observer_Clean::CACHE_TYPE)
        );
        Mage::app()->getCacheInstance()->banUse('fpc');
        $this->_cleanObserver->
            controllerActionPredispatchAdminhtmlCacheMassRefresh();
        $this->assertEquals($data, $this->_fpc->load('test_id'));
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Test/Model/Observer/Parameters/fixtures/fpc_helper_collect_params.yaml
================================================
config:
  default/system/fpc/session_params: >
    magento,
    fpc


================================================
FILE: app/code/community/Lesti/Fpc/Test/Model/Observer/Parameters.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Test_Model_Observer_Parameters
 */
class Lesti_Fpc_Test_Model_Observer_Parameters extends Lesti_Fpc_Test_TestCase
{
    /**
     * @test
     * @loadFixture fpc_helper_collect_params.yaml
     */
    public function testFpcHelperCollectParams()
    {
        Mage::app()->getRequest()->setRouteName('catalog');
        Mage::app()->getRequest()->setControllerName('category');
        Mage::app()->getRequest()->setActionName('view');

        /** @var Mage_Catalog_Model_Session $catalogSession */
        $catalogSession = Mage::getSingleton('catalog/session');
        $catalogSession->setData('fpc', 'cool');

        $expectedResult = array(
            'fpc' => 'cool',
            'store' => Mage::app()->getStore(true)->getCode(),
            'currency' => Mage::app()->getStore()->getCurrentCurrencyCode(),
            'design' => Mage::getDesign()->getPackageName().'_'.
                Mage::getDesign()->getTheme('template'),
            'session_fpc' => 'cool',
        );
        $params = array('fpc' => 'cool');
        $object = new Varien_Object();
        $object->setValue($params);
        Mage::dispatchEvent(
            'fpc_helper_collect_params',
            array('parameters' => $object)
        );
        $this->assertEquals($expectedResult, $object->getValue());
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Test/Model/Observer/Save.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Test_Model_Observer_Save
 */
class Lesti_Fpc_Test_Model_Observer_Save extends Lesti_Fpc_Test_TestCase
{
    /**
     * @test
     */
    public function testCalaogProductSaveAfter()
    {
        $product1Data = new \Lesti_Fpc_Model_Fpc_CacheItem('product1', time(), 'text/html');
        $this->_fpc->save(
            $product1Data,
            'product1_cache_id',
            array(sha1('product_1'))
        );
        $category1Data = new \Lesti_Fpc_Model_Fpc_CacheItem('category1', time(), 'text/html');
        $this->_fpc->save(
            $category1Data,
            'category1_cache_id',
            array(sha1('category_1'))
        );
        $category2Data = new \Lesti_Fpc_Model_Fpc_CacheItem('category2', time(), 'text/html');
        $this->_fpc->save(
            $category2Data,
            'category2_cache_id',
            array(sha1('category_2'))
        );

        $product = new Mage_Catalog_Model_Product();
        $product->setOrigData(array());
        $product->setCategoryIds(array(1));
        $product->setId(1);
        Mage::dispatchEvent(
            'catalog_product_save_after',
            array('product' => $product)
        );

        $this->assertFalse($this->_fpc->load('product1_cache_id'));
        $this->assertFalse($this->_fpc->load('category1_cache_id'));
        $this->assertEquals(
            $category2Data,
            $this->_fpc->load('category2_cache_id')
        );
    }

    /**
     * @test
     */
    public function testCatalogCategorySaveAfter()
    {
        $category1Data = new \Lesti_Fpc_Model_Fpc_CacheItem('category1', time(), 'text/html');
        $this->_fpc->save(
            $category1Data,
            'category1_cache_id',
            array(sha1('category_1'))
        );
        $category2Data = new \Lesti_Fpc_Model_Fpc_CacheItem('category2', time(), 'text/html');
        $this->_fpc->save(
            $category2Data,
            'category2_cache_id',
            array(sha1('category_2'))
        );

        $category = new Mage_Catalog_Model_Category();
        $category->setId(1);
        Mage::dispatchEvent(
            'catalog_category_save_after',
            array('category' => $category)
        );

        $this->assertFalse($this->_fpc->load('category1_cache_id'));
        $this->assertEquals(
            $category2Data,
            $this->_fpc->load('category2_cache_id')
        );
    }

    /**
     * @test
     */
    public function testCmsPageSaveAfter()
    {
        $page1Data = new \Lesti_Fpc_Model_Fpc_CacheItem('page1', time(), 'text/html');
        $this->_fpc->save($page1Data, 'page1_cache_id', array(sha1('cms_1')));
        $page2Data = new \Lesti_Fpc_Model_Fpc_CacheItem('page2', time(), 'text/html');
        $this->_fpc->save($page2Data, 'page2_cache_id', array(sha1('cms_2')));
        $page3Data = new \Lesti_Fpc_Model_Fpc_CacheItem('page3', time(), 'text/html');
        $this->_fpc->save($page3Data, 'page3_cache_id', array(sha1('cms_3')));

        $page = new Mage_Cms_Model_Page();
        $page->setId(1);
        $page->setIdentifier('3');
        Mage::dispatchEvent('cms_page_save_after', array('object' => $page));

        $this->assertFalse($this->_fpc->load('page1_cache_id'));
        $this->assertFalse($this->_fpc->load('page3_cache_id'));
        $this->assertEquals($page2Data, $this->_fpc->load('page2_cache_id'));
    }

    /**
     * @test
     */
    public function testCmsBlockSaveAfter()
    {
        $page1Data = new \Lesti_Fpc_Model_Fpc_CacheItem('page1', time(), 'text/html');
        $this->_fpc->save(
            $page1Data,
            'page1_cache_id',
            array(sha1('cmsblock_1'))
        );
        $page2Data = new \Lesti_Fpc_Model_Fpc_CacheItem('page2', time(), 'text/html');
        $this->_fpc->save(
            $page2Data,
            'page2_cache_id',
            array(sha1('cmsblock_2'))
        );

        $cmsBlock = new Mage_Cms_Model_Block();
        $cmsBlock->setIdentifier('1');
        Mage::dispatchEvent('model_save_after', array('object' => $cmsBlock));

        $this->assertFalse($this->_fpc->load('page1_cache_id'));
        $this->assertEquals($page2Data, $this->_fpc->load('page2_cache_id'));
    }

    /**
     * @test
     */
    public function testCatalogProductSaveAfterMassAction()
    {
        $product1Data = new \Lesti_Fpc_Model_Fpc_CacheItem('product1', time(), 'text/html');
        $this->_fpc->save(
            $product1Data,
            'product1_cache_id',
            array(sha1('product_1'))
        );
        $product2Data = new \Lesti_Fpc_Model_Fpc_CacheItem('product2', time(), 'text/html');
        $this->_fpc->save(
            $product2Data,
            'product2_cache_id',
            array(sha1('product_2'))
        );
        $product3Data = new \Lesti_Fpc_Model_Fpc_CacheItem('product3', time(), 'text/html');
        $this->_fpc->save(
            $product3Data,
            'product3_cache_id',
            array(sha1('product_3'))
        );

        $event = new Mage_Index_Model_Event();
        $productAction = new Mage_Catalog_Model_Product_Action();
        $productAction->setProductIds(array(2, 3));
        $event->setType('mass_action');
        $event->setEntity('catalog_product');
        $event->setDataObject($productAction);
        Mage::dispatchEvent('model_save_after', array('object' => $event));

        $this->assertEquals($product1Data, $this->_fpc->load('product1_cache_id'));
        $this->assertFalse($this->_fpc->load('product2_cache_id'));
        $this->assertFalse($this->_fpc->load('product3_cache_id'));
    }

    /**
     * @test
     */
    public function testCataloginventoryStockItemSaveAfter()
    {
        $product1Data = new \Lesti_Fpc_Model_Fpc_CacheItem('product1', time(), 'text/html');
        $this->_fpc->save(
            $product1Data,
            'product1_cache_id',
            array(sha1('product_1'))
        );
        $product2Data = new \Lesti_Fpc_Model_Fpc_CacheItem('product2', time(), 'text/html');
        $this->_fpc->save(
            $product2Data,
            'product2_cache_id',
            array(sha1('product_2'))
        );

        $item = new Mage_CatalogInventory_Model_Stock_Item();
        $item->setStockStatusChangedAuto(true);
        $item->setProductId(1);
        Mage::dispatchEvent(
            'cataloginventory_stock_item_save_after',
            array('item' => $item)
        );

        $this->assertFalse($this->_fpc->load('product1_cache_id'));
        $this->assertEquals(
            $product2Data,
            $this->_fpc->load('product2_cache_id')
        );
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Test/Model/Observer/Tags/fixtures/fpc_observer_collect_cache_tags.yaml
================================================
config:
    default/web/default/cms_home_page: 5


================================================
FILE: app/code/community/Lesti/Fpc/Test/Model/Observer/Tags/fixtures/get_catalog_product_view_cache_tags_configurable_prod.yaml
================================================
tables:
  eav_attribute_set:
    - attribute_set_id: 13
      entity_type_id: 4
  catalog_product_entity:
    - entity_id: 5
      entity_type_id: 4
      attribute_set_id: 13
    - entity_id: 6
      entity_type_id: 4
      attribute_set_id: 13
  catalog_product_super_link:
    - product_id: 5
      parent_id: 6


================================================
FILE: app/code/community/Lesti/Fpc/Test/Model/Observer/Tags/fixtures/get_catalog_product_view_cache_tags_grouped_product.yaml
================================================
tables:
  eav_attribute_set:
    - attribute_set_id: 13
      entity_type_id: 4
  catalog_product_entity:
    - entity_id: 5
      entity_type_id: 4
      attribute_set_id: 13
    - entity_id: 6
      entity_type_id: 4
      attribute_set_id: 13
  catalog_product_link:
    - product_id: 5
      linked_product_id: 6
      link_type_id: 3


================================================
FILE: app/code/community/Lesti/Fpc/Test/Model/Observer/Tags/fixtures/get_cms_index_index_cache_tags.yaml
================================================
config:
    default/web/default/cms_home_page: 5


================================================
FILE: app/code/community/Lesti/Fpc/Test/Model/Observer/Tags/fixtures/get_cms_index_index_cache_tags_zero.yaml
================================================
config:
    default/web/default/cms_home_page: 0


================================================
FILE: app/code/community/Lesti/Fpc/Test/Model/Observer/Tags/providers/testFpcObserverCollectCacheTags.yaml
================================================
test_cms_index_index:
  route_name: cms
  controller_name: index
  action_name: index
  expected_cache_tags:
    # sha1('cms')
    293ae992f45cff1d17d3e83eefd2285d47f7c997
    # sha1('cms_5')
    133a307e26568a3c9c93e60b0e314945b91d446f
test_cms_page_view:
  route_name: cms
  controller_name: page
  action_name: view
  expected_cache_tags:
    # sha1('cms')
    293ae992f45cff1d17d3e83eefd2285d47f7c997
    # sha1('cms_5')
    133a307e26568a3c9c93e60b0e314945b91d446f
  params:
    id: 5

test_catalog_product_view:
  route_name: catalog
  controller_name: product
  action_name: view
  expected_cache_tags:
    # sha1('product')
    38a007151abe87cc01a5b6e9cc418e85286e2087
    # sha1('product_5')
    01337f5c00647634e8cef67064d9c4fd4fa0290e
  params:
    id: 5
test_catalog_category_view:
  route_name: catalog
  controller_name: category
  action_name: view
  expected_cache_tags:
    # sha1('category')
    5ccbf9c9c5fc1bc34df8238a97094968f38f5165
    # sha1('category_5')
    813322a624dfadc4b560f8ebdf2215e6a32c338c
  params:
    id: 5


================================================
FILE: app/code/community/Lesti/Fpc/Test/Model/Observer/Tags.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Test_Model_Observer_Tags
 *
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
 */
class Lesti_Fpc_Test_Model_Observer_Tags extends Lesti_Fpc_Test_TestCase
{
    /**
     * @test
     * @loadFixture fpc_observer_collect_cache_tags.yaml
     * @dataProvider dataProvider
     */
    public function testFpcObserverCollectCacheTags(
        $routeName,
        $controllerName,
        $actionName,
        $expectedCacheTags,
        $params = array()
    )
    {
        $this->setFullActionName($routeName, $controllerName, $actionName);
        Mage::app()->getRequest()->setParams($params);

        $tags = array('fpc_tag');
        $cacheTags = $this->dispatchCollectTagsEvent($tags);
        $expectedCacheTags = array_merge($tags, $expectedCacheTags);
        $this->assertEquals($expectedCacheTags, $cacheTags);
    }

    /**
     * @test
     * @loadFixture get_cms_index_index_cache_tags_zero.yaml
     */
    public function testGetCmsIndexIndexCacheTagsZero()
    {
        $expectedCacheTags = array(
            '293ae992f45cff1d17d3e83eefd2285d47f7c997', // sha1('cms')
        );
        $this->setFullActionName('cms', 'index', 'index');
        $cacheTags = $this->dispatchCollectTagsEvent(array());
        $this->assertEquals($expectedCacheTags, $cacheTags);
    }

    /**
     * @test
     * @loadFixture get_cms_index_index_cache_tags.yaml
     */
    public function testGetCmsIndexIndexCacheTags()
    {
        $expectedCacheTags = array(
            '293ae992f45cff1d17d3e83eefd2285d47f7c997', // sha1('cms')
            '133a307e26568a3c9c93e60b0e314945b91d446f', // sha1('cms_5')
        );
        $this->setFullActionName('cms', 'index', 'index');
        $cacheTags = $this->dispatchCollectTagsEvent(array());
        $this->assertEquals($expectedCacheTags, $cacheTags);
    }

    /**
     * @test
     */
    public function testGetCmsPageViewCacheTagsEmpty()
    {
        $expectedCacheTags = array(
            '293ae992f45cff1d17d3e83eefd2285d47f7c997', // sha1('cms')
        );
        $this->setFullActionName('cms', 'page', 'view');
        $cacheTags = $this->dispatchCollectTagsEvent(array());
        $this->assertEquals($expectedCacheTags, $cacheTags);
    }

    /**
     * @test
     */
    public function testGetCmsPageViewCacheTagsPageId()
    {
        $expectedCacheTags = array(
            '293ae992f45cff1d17d3e83eefd2285d47f7c997', // sha1('cms')
            '133a307e26568a3c9c93e60b0e314945b91d446f', // sha1('cms_5')
        );
        $request = Mage::app()->getRequest();
        $request->setParam('page_id', 5);
        $this->setFullActionName('cms', 'page', 'view');
        $cacheTags = $this->dispatchCollectTagsEvent(array());
        $this->assertEquals($expectedCacheTags, $cacheTags);
    }

    /**
     * @test
     */
    public function testGetCmsPageViewCacheTagsId()
    {
        $expectedCacheTags = array(
            '293ae992f45cff1d17d3e83eefd2285d47f7c997', // sha1('cms')
            '133a307e26568a3c9c93e60b0e314945b91d446f', // sha1('cms_5')
        );
        $request = Mage::app()->getRequest();
        $request->setParam('id', 5);
        $this->setFullActionName('cms', 'page', 'view');
        $cacheTags = $this->dispatchCollectTagsEvent(array());
        $this->assertEquals($expectedCacheTags, $cacheTags);
    }

    /**
     * @test
     */
    public function testGetCatalogProductViewCacheTagsZero()
    {
        $expectedCacheTags = array(
            '38a007151abe87cc01a5b6e9cc418e85286e2087', // sha1('product')
        );
        $this->setFullActionName('catalog', 'product', 'view');
        $cacheTags = $this->dispatchCollectTagsEvent(array());
        $this->assertEquals($expectedCacheTags, $cacheTags);
    }

    /**
     * @test
     */
    public function testGetCatalogProductViewCacheTagsSimpleProduct()
    {
        $expectedCacheTags = array(
            '38a007151abe87cc01a5b6e9cc418e85286e2087', // sha1('product')
            '01337f5c00647634e8cef67064d9c4fd4fa0290e', // sha1('product_5')
        );
        $request = Mage::app()->getRequest();
        $request->setParam('id', 5);
        $this->setFullActionName('catalog', 'product', 'view');
        $cacheTags = $this->dispatchCollectTagsEvent(array());
        $this->assertEquals($expectedCacheTags, $cacheTags);
    }

    /**
     * @test
     */
    public function testGetCatalogProductViewCacheTagsWithCategory()
    {
        $expectedCacheTags = array(
            '38a007151abe87cc01a5b6e9cc418e85286e2087', // sha1('product')
            '01337f5c00647634e8cef67064d9c4fd4fa0290e', // sha1('product_5')
            '5ccbf9c9c5fc1bc34df8238a97094968f38f5165', // sha1('category')
            '48ce6d1a1ef87339c758621f81e33b02f9d1cb72', // sha1('category_7')
        );
        $request = Mage::app()->getRequest();
        $request->setParam('id', 5);
        $request->setParam('category', 7);
        $this->setFullActionName('catalog', 'product', 'view');
        $cacheTags = $this->dispatchCollectTagsEvent(array());
        $this->assertEquals($expectedCacheTags, $cacheTags);
    }

    /**
     * @test
     * @loadFixture get_catalog_product_view_cache_tags_configurable_prod.yaml
     */
    public function testGetCatalogProductViewCacheTagsConfigurableProduct()
    {
        $expectedCacheTags = array(
            '38a007151abe87cc01a5b6e9cc418e85286e2087', // sha1('product')
            '01337f5c00647634e8cef67064d9c4fd4fa0290e', // sha1('product_5')
            'cfe471971355a3a3d4311e12813f7fa689cf5199', // sha1('product_6')
        );
        $request = Mage::app()->getRequest();
        $request->setParam('id', 5);
        $this->setFullActionName('catalog', 'product', 'view');
        $cacheTags = $this->dispatchCollectTagsEvent(array());
        $this->assertEquals($expectedCacheTags, $cacheTags);

        $expectedCacheTags = array(
            '38a007151abe87cc01a5b6e9cc418e85286e2087', // sha1('product')
            'cfe471971355a3a3d4311e12813f7fa689cf5199', // sha1('product_6')
            '01337f5c00647634e8cef67064d9c4fd4fa0290e', // sha1('product_5')
        );
        $request->setParam('id', 6);
        $this->setFullActionName('catalog', 'product', 'view');
        $cacheTags = $this->dispatchCollectTagsEvent(array());
        $this->assertEquals($expectedCacheTags, $cacheTags);
    }

    /**
     * @test
     * @loadFixture get_catalog_product_view_cache_tags_grouped_product.yaml
     */
    public function testGetCatalogProductViewCacheTagsGroupedProduct()
    {
        $expectedCacheTags = array(
            '38a007151abe87cc01a5b6e9cc418e85286e2087', // sha1('product')
            '01337f5c00647634e8cef67064d9c4fd4fa0290e', // sha1('product_5')
            'cfe471971355a3a3d4311e12813f7fa689cf5199', // sha1('product_6')
        );
        $request = Mage::app()->getRequest();
        $request->setParam('id', 5);
        $this->setFullActionName('catalog', 'product', 'view');
        $cacheTags = $this->dispatchCollectTagsEvent(array());
        $this->assertEquals($expectedCacheTags, $cacheTags);

        $expectedCacheTags = array(
            '38a007151abe87cc01a5b6e9cc418e85286e2087', // sha1('product')
            'cfe471971355a3a3d4311e12813f7fa689cf5199', // sha1('product_6')
            '01337f5c00647634e8cef67064d9c4fd4fa0290e', // sha1('product_5')
        );
        $request->setParam('id', 6);
        $this->setFullActionName('catalog', 'product', 'view');
        $cacheTags = $this->dispatchCollectTagsEvent(array());
        $this->assertEquals($expectedCacheTags, $cacheTags);
    }

    /**
     * @test
     */
    public function testGetCatalogCategoryViewCacheTagsEmpty()
    {
        $expectedCacheTags = array(
            '5ccbf9c9c5fc1bc34df8238a97094968f38f5165', // sha1('category')
        );
        $this->setFullActionName('catalog', 'category', 'view');
        $cacheTags = $this->dispatchCollectTagsEvent(array());
        $this->assertEquals($expectedCacheTags, $cacheTags);
    }

    /**
     * @test
     */
    public function testGetCatalogCategoryViewCacheTags()
    {
        $expectedCacheTags = array(
            '5ccbf9c9c5fc1bc34df8238a97094968f38f5165', // sha1('category')
            '48ce6d1a1ef87339c758621f81e33b02f9d1cb72', // sha1('category_7')
        );
        $request = Mage::app()->getRequest();
        $request->setParam('id', 7);
        $this->setFullActionName('catalog', 'category', 'view');
        $cacheTags = $this->dispatchCollectTagsEvent(array());
        $this->assertEquals($expectedCacheTags, $cacheTags);
    }

    /**
     * @param array $tags
     * @return mixed
     */
    protected function dispatchCollectTagsEvent(array $tags)
    {
        $cacheTags = new Varien_Object();
        $cacheTags->setValue($tags);
        Mage::dispatchEvent(
            'fpc_observer_collect_cache_tags',
            array('cache_tags' => $cacheTags)
        );
        return $cacheTags->getValue();
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Test/Model/Observer/fixtures/controller_action_postdispatch.yaml
================================================
config:
    default/system/fpc/refresh_actions: >
     checkout_cart_add,
     checkout_cart_delete, checkout_cart_updatePost
      , checkout_cart_delete


================================================
FILE: app/code/community/Lesti/Fpc/Test/Model/Observer/providers/controllerActionPostdispatch.yaml
================================================
test_false:
  route: checkout
  controller: cart
  action: add
  expected: 0
test_true:
  route: catalog
  controller: product
  action: view
  expected: 1


================================================
FILE: app/code/community/Lesti/Fpc/Test/Model/Observer.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Test_Model_Observer
 */
class Lesti_Fpc_Test_Model_Observer extends Lesti_Fpc_Test_TestCase
{
    /**
     * @var Lesti_Fpc_Model_Observer
     */
    protected $_observer;

    protected function setUp()
    {
        parent::setUp();
        $this->_observer = Mage::getSingleton('fpc/observer');
    }

    protected function tearDown()
    {
        parent::tearDown();
        // unregister observer
        Mage::unregister('_singleton/fpc/observer');
        Mage::getSingleton('customer/session')->setData(
            Lesti_Fpc_Helper_Block::LAZY_BLOCKS_VALID_SESSION_PARAM,
            false
        );
    }

    /**
     * @test
     * @loadFixture controller_action_postdispatch.yaml
     * @dataProvider dataProvider
     */
    public function controllerActionPostdispatch(
        $route,
        $controller,
        $action,
        $expected
    )
    {
        Mage::app()->getRequest()->setRouteName($route);
        Mage::app()->getRequest()->setControllerName($controller);
        Mage::app()->getRequest()->setActionName($action);
        Mage::getSingleton('customer/session')->setData(
            Lesti_Fpc_Helper_Block::LAZY_BLOCKS_VALID_SESSION_PARAM,
            true
        );

        $this->_observer->controllerActionPostdispatch();
        $this->assertEquals(
            (bool) $expected,
            Mage::getSingleton('customer/session')->getData(
                Lesti_Fpc_Helper_Block::LAZY_BLOCKS_VALID_SESSION_PARAM
            )
        );
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/Test/TestCase.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Test_TestCase
 */
abstract class Lesti_Fpc_Test_TestCase extends
    EcomDev_PHPUnit_Test_Case_Controller
{
    /**
     * @var Lesti_Fpc_Model_Fpc
     */
    protected $_fpc;

    protected $_cacheOptions;

    protected $_cache;

    protected function setUp()
    {
        parent::setUp();
        $this->_fpc = Mage::getSingleton('fpc/fpc');
        $this->_fpc->clean();
        // disable all caches expected fpc
        $this->_cache = Mage::app()->getCacheInstance();
        $this->_cacheOptions = Mage::getResourceSingleton('core/cache')
            ->getAllOptions();
        $cacheOptions = $this->_cacheOptions;
        foreach (array_keys($cacheOptions) as $cache) {
            $cacheOptions[$cache] = $cache == 'fpc' ? 1 : 0;
        }
        if (!array_key_exists('fpc', $cacheOptions)) {
            $cacheOptions['fpc'] = 1;
        }
        $this->_cache->saveOptions($cacheOptions);
        $cacheReflector = new ReflectionClass('Mage_Core_Model_Cache');
        $initOptionsMethod = $cacheReflector->getMethod('_initOptions');
        $initOptionsMethod->setAccessible(true);
        $initOptionsMethod->invokeArgs($this->_cache, array());
    }

    protected function tearDown()
    {
        parent::tearDown();
        $this->_cache->saveOptions($this->_cacheOptions);
        // unregister fpc
        Mage::unregister('_singleton/fpc/fpc');
        Mage::getSingleton('customer/session')->logout();
    }

    protected function clearBaseUrlProperty()
    {
        $storeReflector = new ReflectionClass('Mage_Core_Model_Store');
        $baseUrlCacheProperty = $storeReflector->getProperty('_baseUrlCache');
        $baseUrlCacheProperty->setAccessible(true);
        $baseUrlCacheProperty->setValue(Mage::app()->getStore(), array());
    }

    /**
     * @param $routeName
     * @param $controllerName
     * @param $actionName
     */
    protected function setFullActionName(
        $routeName,
        $controllerName,
        $actionName
    )
    {
        Mage::app()->getRequest()->setRouteName($routeName);
        Mage::app()->getRequest()->setControllerName($controllerName);
        Mage::app()->getRequest()->setActionName($actionName);
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/controllers/Catalog/ProductController.php
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

/**
 * Class Lesti_Fpc_Catalog_ProductController
 */
class Lesti_Fpc_Catalog_ProductController extends
    Mage_Core_Controller_Front_Action
{
    public function viewAction()
    {
        $productId = (int)Mage::app()->getRequest()->getParam('id');
        $product = Mage::getModel('catalog/product')->load($productId);
        if ($product->getId()) {
            Mage::dispatchEvent(
                'catalog_controller_product_view',
                array('product' => $product)
            );
        }
    }
}


================================================
FILE: app/code/community/Lesti/Fpc/etc/config.xml
================================================
<?xml version="1.0"?>
<!--
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */
-->
<config>
    <modules>
        <Lesti_Fpc>
            <version>1.4.8</version>
        </Lesti_Fpc>
    </modules>
    <global>
        <blocks>
            <fpc>
                <class>Lesti_Fpc_Block</class>
            </fpc>
            <core>
                <rewrite>
                    <messages>Lesti_Fpc_Core_Block_Messages</messages>
                </rewrite>
            </core>
        </blocks>
        <helpers>
            <fpc>
                <class>Lesti_Fpc_Helper</class>
            </fpc>
        </helpers>
        <models>
            <fpc>
                <class>Lesti_Fpc_Model</class>
            </fpc>
        </models>
        <cache>
            <types>
                <fpc translate="label,description" module="fpc">
                    <label><![CDATA[Fpc]]></label>
                    <description><![CDATA[Full Page Cache]]></description>
                    <tags><![CDATA[FPC]]></tags>
                </fpc>
            </types>
        </cache>
        <events>
            <catalog_product_save_after>
                <observers>
                    <fpc_catalog_product_save_after>
                        <class>fpc/observer_save</class>
                        <type>singleton</type>
                        <method>catalogProductSaveAfter</method>
                    </fpc_catalog_product_save_after>
                </observers>
            </catalog_product_save_after>
            <catalog_category_save_after>
                <observers>
                    <fpc_catalog_category_save_after>
                        <class>fpc/observer_save</class>
                        <type>singleton</type>
                        <method>catalogCategorySaveAfter</method>
                    </fpc_catalog_category_save_after>
                </observers>
            </catalog_category_save_after>
            <cms_page_save_after>
                <observers>
                    <fpc_cms_page_save_after>
                        <class>fpc/observer_save</class>
                        <type>singleton</type>
                        <method>cmsPageSaveAfter</method>
                    </fpc_cms_page_save_after>
                </observers>
            </cms_page_save_after>
            <model_save_after>
                <observers>
                    <fpc_model_save_after>
                        <class>fpc/observer_save</class>
                        <type>singleton</type>
                        <method>modelSaveAfter</method>
                    </fpc_model_save_after>
                </observers>
            </model_save_after>
            <review_delete_after>
                <observers>
                    <fpc_review_delete_after>
                        <class>fpc/observer_save</class>
                        <type>singleton</type>
                        <method>reviewDeleteAfter</method>
                    </fpc_review_delete_after>
                </observers>
            </review_delete_after>
            <review_save_after>
                <observers>
                    <fpc_review_save_after>
                        <class>fpc/observer_save</class>
                        <type>singleton</type>
                        <method>reviewSaveAfter</method>
                    </fpc_review_save_after>
                </observers>
            </review_save_after>
            <core_clean_cache>
                <observers>
                    <fpc_core_clean_cache>
                        <class>fpc/observer_clean</class>
                        <type>singleton</type>
                        <method>coreCleanCache</method>
                    </fpc_core_clean_cache>
                </observers>
            </core_clean_cache>
            <adminhtml_cache_flush_all>
                <observers>
                    <fpc_adminhtml_cache_flush_all>
                        <class>fpc/observer_clean</class>
                        <type>singleton</type>
                        <method>adminhtmlCacheFlushAll</method>
                    </fpc_adminhtml_cache_flush_all>
                </observers>
            </adminhtml_cache_flush_all>
            <cataloginventory_stock_item_save_after>
                <observers>
                    <fpc_cataloginventory_stock_item_save_after>
                        <class>fpc/observer_save</class>
                        <type>singleton</type>
                        <method>cataloginventoryStockItemSaveAfter</method>
                    </fpc_cataloginventory_stock_item_save_after>
                </observers>
            </cataloginventory_stock_item_save_after>
            <fpc_helper_collect_params>
                <observers>
                    <fpc_fpc_helper_collect_params>
                        <class>fpc/observer_parameters</class>
                        <type>singleton</type>
                        <method>fpcHelperCollectParams</method>
                    </fpc_fpc_helper_collect_params>
                </observers>
            </fpc_helper_collect_params>
            <fpc_observer_collect_cache_tags>
                <observers>
                    <fpc_fpc_observer_collect_cache_tags>
                        <class>fpc/observer_tags</class>
                        <type>singleton</type>
                        <method>fpcObserverCollectCacheTags</method>
                    </fpc_fpc_observer_collect_cache_tags>
                </observers>
            </fpc_observer_collect_cache_tags>
        </events>
        <catalogrule>
            <related_cache_types>
                <fpc />
            </related_cache_types>
        </catalogrule>
    </global>
    <frontend>
        <routers>
            <fpc>
                <use>standard</use>
                <args>
                    <module>Lesti_Fpc</module>
                    <frontName>fpc</frontName>
                </args>
            </fpc>
        </routers>
        <events>
            <controller_action_postdispatch>
                <observers>
                    <fpc_controller_action_postdispatch>
                        <class>fpc/observer</class>
                        <type>singleton</type>
                        <method>controllerActionPostdispatch</method>
                    </fpc_controller_action_postdispatch>
                </observers>
            </controller_action_postdispatch>
            <controller_action_layout_generate_blocks_before>
                <observers>
                    <fpc_controller_action_layout_generate_blocks_before>
                        <class>fpc/observer</class>
                        <type>singleton</type>
                        <method>controllerActionLayoutGenerateBlocksBefore</method>
                    </fpc_controller_action_layout_generate_blocks_before>
                </observers>
            </controller_action_layout_generate_blocks_before>
            <http_response_send_before>
                <observers>
                    <fpc_http_response_send_before>
                        <class>fpc/observer</class>
                        <type>singleton</type>
                        <method>httpResponseSendBefore</method>
                    </fpc_http_response_send_before>
                </observers>
            </http_response_send_before>
            <core_block_abstract_to_html_after>
                <observers>
                    <fpc_core_block_abstract_to_html_after>
                        <class>fpc/observer</class>
                        <type>singleton</type>
                        <method>coreBlockAbstractToHtmlAfter</method>
                    </fpc_core_block_abstract_to_html_after>
                </observers>
            </core_block_abstract_to_html_after>
            <core_block_messages_get_grouped_html_after>
                <observers>
                    <fpc_core_block_messages_get_grouped_html_after>
                        <class>fpc/observer</class>
                        <type>singleton</type>
                        <method>coreBlockAbstractToHtmlAfter</method>
                    </fpc_core_block_messages_get_grouped_html_after>
                </observers>
            </core_block_messages_get_grouped_html_after>
        </events>
        <layout>
            <updates>
                <fpc>
                    <file>fpc.xml</file>
                </fpc>
            </updates>
        </layout>
    </frontend>
    <adminhtml>
        <events>
            <controller_action_predispatch_adminhtml_cache_massRefresh>
                <observers>
                    <fpc_controller_action_predispatch_adminhtml_cache_massRefresh>
                        <class>fpc/observer_clean</class>
                        <type>singleton</type>
                        <method>controllerActionPredispatchAdminhtmlCacheMassRefresh</method>
                    </fpc_controller_action_predispatch_adminhtml_cache_massRefresh>
                </observers>
            </controller_action_predispatch_adminhtml_cache_massRefresh>
        </events>
    </adminhtml>
    <default>
        <system>
            <fpc>
                <cache_actions><![CDATA[cms_index_index,
cms_page_view,
catalog_product_view,
catalog_category_view]]></cache_actions>
                <dynamic_blocks><![CDATA[global_messages,
messages,
global_notices,
global_cookie_notice,
right.reports.product.viewed]]></dynamic_blocks>
                <refresh_actions><![CDATA[checkout_cart_add,
checkout_cart_delete,
checkout_cart_updatePost,
checkout_cart_ajaxDelete,
checkout_cart_ajaxUpdate,
checkout_cart_updateItemOptions,
catalog_product_compare_add,
catalog_product_compare_clear,
catalog_product_compare_remove,
wishlist_index_add,
wishlist_index_remove,
wishlist_index_update,
wishlist_index_allcart,
wishlist_index_configure,
checkout_onepage_success,
customer_account_login,
poll_vote_add]]></refresh_actions>
                <lazy_blocks><![CDATA[top.links,
cart_sidebar,
catalog.compare.sidebar,
right.reports.product.compared,
wishlist_sidebar,
welcome,
minicart_head,
right.poll]]></lazy_blocks>
                <uri_params><![CDATA[id,
category,
cat,
page_id,
p,
limit,
dir,
order,
mode,
/utm_.*/,
gclid,
gclsrc]]></uri_params>
                <uri_params_layered_navigation>1</uri_params_layered_navigation>
                <miss_uri_params><![CDATA[no_cache=/^1$/,
limit=/^([0-9]+)|(all)$/,
dir=/^[0-9a-z_]+$/,
order=/^[0-9a-z_]+$/,
mode=/^[0-9a-z_]+$/,
___store=/^[a-z]{1}[0-9a-z_]*$/]]></miss_uri_params>
                <session_params><![CDATA[limit_page,
sort_order,
sort_direction,
display_mode]]></session_params>
                <customer_groups>0</customer_groups>
                <use_recently_viewed_products>0</use_recently_viewed_products>
                <show_age>1</show_age>
                <gzcompress_level>-2</gzcompress_level>
            </fpc>
        </system>
    </default>
    <phpunit>
        <suite>
            <modules>
                <Lesti_Fpc/>
            </modules>
        </suite>
    </phpunit>
</config>


================================================
FILE: app/code/community/Lesti/Fpc/etc/system.xml
================================================
<?xml version="1.0"?>
<!--
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */
-->
<config>
    <sections>
        <system>
            <groups>
                <fpc>
                    <label>Lesti FPC</label>
                    <frontend_type>text</frontend_type>
                    <sort_order>200</sort_order>
                    <show_in_default>1</show_in_default>
                    <show_in_website>1</show_in_website>
                    <show_in_store>1</show_in_store>
                    <fields>
                        <cache_actions>
                            <label>Cachable actions</label>
                            <frontend_type>textarea</frontend_type>
                            <comment>All cachable Actions, separated with Comma</comment>
                            <sort_order>10</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </cache_actions>
                        <dynamic_blocks>
                            <label>Dynamic Blocks</label>
                            <frontend_type>textarea</frontend_type>
                            <comment>All dynamic Blocks, separated with Comma</comment>
                            <sort_order>20</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </dynamic_blocks>
                        <refresh_actions>
                            <label>Refresh Actions</label>
                            <frontend_type>textarea</frontend_type>
                            <comment>All Action to refresh lazy blocks, separated with Comma</comment>
                            <sort_order>30</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </refresh_actions>
                        <bypass_handles>
                            <label>Bypass Handles</label>
                            <frontend_type>textarea</frontend_type>
                            <comment>All layout handles to bypass FPC, separated with Comma</comment>
                            <sort_order>35</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </bypass_handles>
                        <lazy_blocks>
                            <label>Lazy Blocks</label>
                            <frontend_type>textarea</frontend_type>
                            <comment>All lazy Blocks, separated with Comma</comment>
                            <sort_order>40</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </lazy_blocks>
                        <uri_params>
                            <label>Uri Params</label>
                            <frontend_type>textarea</frontend_type>
                            <comment>All Uri Params, separated with Comma. Params enclosed with "/" are treated as regular expression.</comment>
                            <sort_order>50</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </uri_params>
                        <uri_params_layered_navigation>
                            <label>Add Layered Navigation Attributes To Uri Params</label>
                            <frontend_type>select</frontend_type>
                            <source_model>adminhtml/system_config_source_yesno</source_model>
                            <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>
                            <sort_order>52</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </uri_params_layered_navigation>
                        <miss_uri_params>
                            <label>Miss Uri Params</label>
                            <frontend_type>textarea</frontend_type>
                            <comment>Ignore Requests with this parameters. Regex separated with comma.</comment>
                            <sort_order>55</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </miss_uri_params>
                        <session_params>
                            <label>Category Session Params</label>
                            <frontend_type>textarea</frontend_type>
                            <comment>All Session Params, separated with comma. Works only on category pages.</comment>
                            <sort_order>60</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </session_params>
                        <customer_groups>
                            <label>Customer Group Caching</label>
                            <frontend_type>select</frontend_type>
                            <comment>Only enable if you have different price or layout for different customer groups.</comment>
                            <source_model>adminhtml/system_config_source_yesno</source_model>
                            <sort_order>70</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>0</show_in_website>
                            <show_in_store>0</show_in_store>
                        </customer_groups>
                        <use_recently_viewed_products>
                            <label>Use Recently Viewed Products</label>
                            <frontend_type>select</frontend_type>
                            <source_model>adminhtml/system_config_source_yesno</source_model>
                            <sort_order>80</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </use_recently_viewed_products>
                        <show_age>
                            <label>Show Age</label>
                            <frontend_type>select</frontend_type>
                            <comment>Show the age of a page in header</comment>
                            <source_model>adminhtml/system_config_source_yesno</source_model>
                            <sort_order>90</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </show_age>
                        <gzcompress_level>
                            <label>gzcompress Level</label>
                            <frontend_type>select</frontend_type>
                            <comment>Compress the cache (only for filecache, flush Lesti_Fpc after changing value)</comment>
                            <source_model>fpc/adminhtml_system_config_source_gzcompress</source_model>
                            <sort_order>100</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </gzcompress_level>
                    </fields>
                </fpc>
            </groups>
        </system>
    </sections>
</config>

================================================
FILE: app/design/frontend/base/default/layout/fpc.xml
================================================
<?xml version="1.0"?>
<!--
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */
-->
<layout version="0.1.0">
    <catalog_product_view>
        <reference name="after_body_start">
            <block type="fpc/catalog_product_view_ajax" name="fpc.catalog.product.view.ajax" template="fpc/catalog/product/view/ajax.phtml"/>
        </reference>
    </catalog_product_view>
</layout>

================================================
FILE: app/design/frontend/base/default/template/fpc/catalog/product/view/ajax.phtml
================================================
<?php
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */

if($url = $this->getAjaxUrl()): ?>
    <script type="text/javascript">
        new Ajax.Request(<?php echo '"' . $url . '"'; ?>);
    </script>
<?php endif;

================================================
FILE: app/etc/fpc.xml.sample
================================================
<?xml version="1.0"?>
<!--
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */
-->
<config>
    <global>
        <fpc>
            <lifetime>86400</lifetime>

            <!-- example for redis -->
            <!-- please read https://github.com/colinmollenhour/Cm_Cache_Backend_Redis for more informations -->

            <!--backend>Cm_Cache_Backend_Redis</backend>
            <backend_options>
                <server>127.0.0.1</server>
                <port>6379</port>
                <persistent>cache-fpc</persistent>
                <database>1</database>
                <password></password>
                <force_standalone>1</force_standalone>
                <connect_retries>1</connect_retries>
                <lifetimelimit>86400</lifetimelimit>
                <read_timeout>10</read_timeout>
                <compress_data>1</compress_data>
                <compress_tags>1</compress_tags>
                <compress_data>gzip</compress_data>
            </backend_options-->

            <!-- example for apc -->

            <!--backend>apc</backend>
            <prefix>LESTI_FPC_</prefix-->

            <!-- example for memcached -->

            <!--backend>memcached</backend>
            <memcached>
                <servers>
                    <server>
                        <host><![CDATA[127.0.0.1]]></host>
                        <port><![CDATA[11211]]></port>
                        <persistent><![CDATA[1]]></persistent>
                    </server>
                </servers>
                <compression><![CDATA[0]]></compression>
                <cache_dir><![CDATA[]]></cache_dir>
                <hashed_directory_level><![CDATA[]]></hashed_directory_level>
                <hashed_directory_umask><![CDATA[]]></hashed_directory_umask>
                <file_name_prefix><![CDATA[]]></file_name_prefix>
            </memcached-->
        </fpc>
    </global>
</config>


================================================
FILE: app/etc/modules/Lesti_Fpc.xml
================================================
<?xml version="1.0"?>
<!--
/**
 * Lesti_Fpc (http:gordonlesti.com/lestifpc)
 *
 * PHP version 5
 *
 * @link      https://github.com/GordonLesti/Lesti_Fpc
 * @package   Lesti_Fpc
 * @author    Gordon Lesti <info@gordonlesti.com>
 * @copyright Copyright (c) 2013-2016 Gordon Lesti (http://gordonlesti.com)
 * @license   http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */
-->
<config>
    <modules>
        <Lesti_Fpc>
            <active>true</active>
            <codePool>community</codePool>
            <depends>
                <Mage_Catalog/>
                <Mage_Cms/>
                <Mage_Core/>
            </depends>
        </Lesti_Fpc>
    </modules>
</config>

================================================
FILE: composer.json
================================================
{
    "name": "gordonlesti/lesti_fpc",
    "type": "magento-module",
    "description": "Simple Magento Fullpagecache",
    "keywords": ["fpc"],
    "homepage": "https://github.com/GordonLesti/Lesti_Fpc",
    "license": "OSL-3.0",
    "authors": [
        {
            "name": "Gordon Lesti",
            "email": "info@gordonlesti.com",
            "homepage": "http://gordonlesti.com/",
            "role": "developer"
        }
    ],
    "require": {
        "magento-hackathon/magento-composer-installer": "^3.0"
    },
    "require-dev": {
        "ecomdev/ecomdev_phpunit": "^0.3.7",
        "phpunit/phpunit": "4.*",
        "phpmd/phpmd": "^2.4",
        "squizlabs/php_codesniffer": "^2.5",
        "sebastian/phpcpd": "^2.0",
        "satooshi/php-coveralls": "^1.0"
    },
    "repositories": [
        {
            "type": "composer",
            "url": "https://packages.firegento.com/"
        }
    ],
    "extra": {
        "map" : [
            ["app/code/community/Lesti/Fpc", "app/code/community/Lesti/Fpc"],
            ["app/design/frontend/base/default/layout/fpc.xml", "app/design/frontend/base/default/layout/fpc.xml"],
            ["app/design/frontend/base/default/template/fpc", "app/design/frontend/base/default/template/fpc"],
            ["app/etc/modules/Lesti_Fpc.xml", "app/etc/modules/Lesti_Fpc.xml"],
            ["app/etc/fpc.xml.sample", "app/etc/fpc.xml.sample"]
        ]
    }
}


================================================
FILE: modman
================================================
app/code/community/Lesti/Fpc app/code/community/Lesti/Fpc
app/design/frontend/base/default/layout/fpc.xml app/design/frontend/base/default/layout/fpc.xml
app/design/frontend/base/default/template/fpc app/design/frontend/base/default/template/fpc
app/etc/modules/Lesti_Fpc.xml app/etc/modules/Lesti_Fpc.xml
app/etc/fpc.xml.sample app/etc/fpc.xml.sample
Download .txt
gitextract_7u5a0c3r/

├── .coveralls.yml
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── CONDUCT.md
├── LICENSE.md
├── README.md
├── app/
│   ├── code/
│   │   └── community/
│   │       └── Lesti/
│   │           └── Fpc/
│   │               ├── Block/
│   │               │   └── Catalog/
│   │               │       └── Product/
│   │               │           └── View/
│   │               │               └── Ajax.php
│   │               ├── Core/
│   │               │   └── Block/
│   │               │       └── Messages.php
│   │               ├── Helper/
│   │               │   ├── Abstract.php
│   │               │   ├── Block/
│   │               │   │   └── Messages.php
│   │               │   ├── Block.php
│   │               │   └── Data.php
│   │               ├── Model/
│   │               │   ├── Adminhtml/
│   │               │   │   └── System/
│   │               │   │       └── Config/
│   │               │   │           └── Source/
│   │               │   │               └── Gzcompress.php
│   │               │   ├── Fpc/
│   │               │   │   └── CacheItem.php
│   │               │   ├── Fpc.php
│   │               │   ├── Observer/
│   │               │   │   ├── Clean.php
│   │               │   │   ├── Parameters.php
│   │               │   │   ├── Save.php
│   │               │   │   └── Tags.php
│   │               │   └── Observer.php
│   │               ├── Test/
│   │               │   ├── Block/
│   │               │   │   ├── Catalog/
│   │               │   │   │   └── Product/
│   │               │   │   │       └── View/
│   │               │   │   │           ├── Ajax/
│   │               │   │   │           │   └── fixtures/
│   │               │   │   │           │       ├── get_ajax_url.yaml
│   │               │   │   │           │       ├── get_ajax_url_disabled_recently_viewed_products.yaml
│   │               │   │   │           │       ├── get_ajax_url_fpc_inactive.yaml
│   │               │   │   │           │       ├── get_ajax_url_miss_cache_able_action.yaml
│   │               │   │   │           │       └── get_ajax_url_no_current_product.yaml
│   │               │   │   │           └── Ajax.php
│   │               │   │   └── Core/
│   │               │   │       └── Messages.php
│   │               │   ├── Controller/
│   │               │   │   └── Catalog/
│   │               │   │       ├── ProductController/
│   │               │   │       │   └── fixtures/
│   │               │   │       │       └── view_action_with_product.yaml
│   │               │   │       └── ProductController.php
│   │               │   ├── Helper/
│   │               │   │   ├── Block/
│   │               │   │   │   ├── Messages.php
│   │               │   │   │   └── fixtures/
│   │               │   │   │       ├── are_lazy_blocks_valid.yaml
│   │               │   │   │       ├── get_dynamic_blocks.yaml
│   │               │   │   │       ├── get_dynamic_blocks_empty.yaml
│   │               │   │   │       ├── get_lazy_blocks.yaml
│   │               │   │   │       ├── get_lazy_blocks_empty.yaml
│   │               │   │   │       ├── use_recently_viewed_products_false.yaml
│   │               │   │   │       └── use_recently_viewed_products_true.yaml
│   │               │   │   ├── Block.php
│   │               │   │   ├── Data/
│   │               │   │   │   ├── fixtures/
│   │               │   │   │   │   ├── can_cache_request.yaml
│   │               │   │   │   │   ├── get_bypass_handles.yaml
│   │               │   │   │   │   ├── get_bypass_handles_empty.yaml
│   │               │   │   │   │   ├── get_cacheable_actions.yaml
│   │               │   │   │   │   ├── get_cacheable_actions_empty.yaml
│   │               │   │   │   │   ├── get_refresh_actions.yaml
│   │               │   │   │   │   ├── get_refresh_actions_empty.yaml
│   │               │   │   │   │   └── regex_uri_params.yaml
│   │               │   │   │   └── providers/
│   │               │   │   │       ├── testCanCacheRequest.yaml
│   │               │   │   │       └── testRegexUriParams.yaml
│   │               │   │   └── Data.php
│   │               │   ├── Model/
│   │               │   │   ├── Fpc/
│   │               │   │   │   └── fixtures/
│   │               │   │   │       └── save_load_clean.yaml
│   │               │   │   ├── Fpc.php
│   │               │   │   ├── Observer/
│   │               │   │   │   ├── Clean.php
│   │               │   │   │   ├── Parameters/
│   │               │   │   │   │   └── fixtures/
│   │               │   │   │   │       └── fpc_helper_collect_params.yaml
│   │               │   │   │   ├── Parameters.php
│   │               │   │   │   ├── Save.php
│   │               │   │   │   ├── Tags/
│   │               │   │   │   │   ├── fixtures/
│   │               │   │   │   │   │   ├── fpc_observer_collect_cache_tags.yaml
│   │               │   │   │   │   │   ├── get_catalog_product_view_cache_tags_configurable_prod.yaml
│   │               │   │   │   │   │   ├── get_catalog_product_view_cache_tags_grouped_product.yaml
│   │               │   │   │   │   │   ├── get_cms_index_index_cache_tags.yaml
│   │               │   │   │   │   │   └── get_cms_index_index_cache_tags_zero.yaml
│   │               │   │   │   │   └── providers/
│   │               │   │   │   │       └── testFpcObserverCollectCacheTags.yaml
│   │               │   │   │   ├── Tags.php
│   │               │   │   │   ├── fixtures/
│   │               │   │   │   │   └── controller_action_postdispatch.yaml
│   │               │   │   │   └── providers/
│   │               │   │   │       └── controllerActionPostdispatch.yaml
│   │               │   │   └── Observer.php
│   │               │   └── TestCase.php
│   │               ├── controllers/
│   │               │   └── Catalog/
│   │               │       └── ProductController.php
│   │               └── etc/
│   │                   ├── config.xml
│   │                   └── system.xml
│   ├── design/
│   │   └── frontend/
│   │       └── base/
│   │           └── default/
│   │               ├── layout/
│   │               │   └── fpc.xml
│   │               └── template/
│   │                   └── fpc/
│   │                       └── catalog/
│   │                           └── product/
│   │                               └── view/
│   │                                   └── ajax.phtml
│   └── etc/
│       ├── fpc.xml.sample
│       └── modules/
│           └── Lesti_Fpc.xml
├── composer.json
└── modman
Download .txt
SYMBOL INDEX (171 symbols across 28 files)

FILE: app/code/community/Lesti/Fpc/Block/Catalog/Product/View/Ajax.php
  class Lesti_Fpc_Block_Catalog_Product_View_Ajax (line 17) | class Lesti_Fpc_Block_Catalog_Product_View_Ajax extends Mage_Core_Block_...
    method getAjaxUrl (line 22) | public function getAjaxUrl()
    method _getProductId (line 47) | protected function _getProductId()

FILE: app/code/community/Lesti/Fpc/Core/Block/Messages.php
  class Lesti_Fpc_Core_Block_Messages (line 17) | class Lesti_Fpc_Core_Block_Messages extends Mage_Core_Block_Messages
    method getGroupedHtml (line 25) | public function getGroupedHtml()

FILE: app/code/community/Lesti/Fpc/Helper/Abstract.php
  class Lesti_Fpc_Helper_Abstract (line 17) | abstract class Lesti_Fpc_Helper_Abstract extends Mage_Core_Helper_Abstract
    method getCSStoreConfigs (line 26) | public function getCSStoreConfigs($path, $store = null)

FILE: app/code/community/Lesti/Fpc/Helper/Block.php
  class Lesti_Fpc_Helper_Block (line 17) | class Lesti_Fpc_Helper_Block extends Lesti_Fpc_Helper_Abstract
    method getDynamicBlocks (line 28) | public function getDynamicBlocks()
    method getLazyBlocks (line 36) | public function getLazyBlocks()
    method areLazyBlocksValid (line 44) | public function areLazyBlocksValid()
    method _getLazyBlocksValidHash (line 59) | protected function _getLazyBlocksValidHash()
    method getPlaceholderHtml (line 90) | public function getPlaceholderHtml($blockName)
    method getKey (line 99) | public function getKey($blockName)
    method useRecentlyViewedProducts (line 107) | public function useRecentlyViewedProducts()
    method getCacheTags (line 118) | public function getCacheTags($block)

FILE: app/code/community/Lesti/Fpc/Helper/Block/Messages.php
  class Lesti_Fpc_Helper_Block_Messages (line 17) | class Lesti_Fpc_Helper_Block_Messages extends Mage_Core_Helper_Abstract
    method initLayoutMessages (line 23) | public function initLayoutMessages(

FILE: app/code/community/Lesti/Fpc/Helper/Data.php
  class Lesti_Fpc_Helper_Data (line 17) | class Lesti_Fpc_Helper_Data extends Lesti_Fpc_Helper_Abstract
    method getCacheableActions (line 41) | public function getCacheableActions()
    method getBypassHandles (line 49) | public function getBypassHandles()
    method getRefreshActions (line 57) | public function getRefreshActions()
    method getKey (line 66) | public function getKey($postfix = '_page')
    method _getParams (line 74) | protected function _getParams()
    method _matchUriParam (line 126) | protected function _matchUriParam($expression, $param)
    method _getUriParams (line 139) | public function _getUriParams()
    method _getLayeredNavigationAttributes (line 157) | protected function _getLayeredNavigationAttributes()
    method _getMissUriParams (line 201) | protected function _getMissUriParams()
    method canCacheRequest (line 209) | public function canCacheRequest()
    method getFullActionName (line 238) | public function getFullActionName()
    method getContentType (line 251) | public function getContentType(\Mage_Core_Controller_Response_Http $re...

FILE: app/code/community/Lesti/Fpc/Model/Adminhtml/System/Config/Source/Gzcompress.php
  class Lesti_Fpc_Model_Adminhtml_System_Config_Source_Gzcompress (line 17) | class Lesti_Fpc_Model_Adminhtml_System_Config_Source_Gzcompress
    method toOptionArray (line 22) | public function toOptionArray()
    method toArray (line 35) | public function toArray()

FILE: app/code/community/Lesti/Fpc/Model/Fpc.php
  class Lesti_Fpc_Model_Fpc (line 17) | class Lesti_Fpc_Model_Fpc extends Mage_Core_Model_Cache
    method __construct (line 45) | public function __construct()
    method save (line 72) | public function save($item, $id, $tags=array(), $lifeTime=null)
    method load (line 118) | public function load($id)
    method clean (line 140) | public function clean($tags=array())
    method isActive (line 162) | public function isActive()

FILE: app/code/community/Lesti/Fpc/Model/Fpc/CacheItem.php
  class Lesti_Fpc_Model_Fpc_CacheItem (line 6) | class Lesti_Fpc_Model_Fpc_CacheItem
    method __construct (line 28) | public function __construct($content, $time, $contentType)
    method getContent (line 38) | public function getContent()
    method getTime (line 46) | public function getTime()
    method getContentType (line 54) | public function getContentType()

FILE: app/code/community/Lesti/Fpc/Model/Observer.php
  class Lesti_Fpc_Model_Observer (line 17) | class Lesti_Fpc_Model_Observer
    method controllerActionLayoutGenerateBlocksBefore (line 33) | public function controllerActionLayoutGenerateBlocksBefore($observer)
    method httpResponseSendBefore (line 95) | public function httpResponseSendBefore($observer)
    method coreBlockAbstractToHtmlAfter (line 151) | public function coreBlockAbstractToHtmlAfter($observer)
    method controllerActionPostdispatch (line 180) | public function controllerActionPostdispatch()
    method _getFpc (line 200) | protected function _getFpc()
    method _prepareLayout (line 210) | protected function _prepareLayout(
    method _replaceFormKey (line 237) | protected function _replaceFormKey()
    method _insertDynamicBlocks (line 253) | protected function _insertDynamicBlocks(

FILE: app/code/community/Lesti/Fpc/Model/Observer/Clean.php
  class Lesti_Fpc_Model_Observer_Clean (line 14) | class Lesti_Fpc_Model_Observer_Clean
    method coreCleanCache (line 21) | public function coreCleanCache()
    method adminhtmlCacheFlushAll (line 26) | public function adminhtmlCacheFlushAll()
    method controllerActionPredispatchAdminhtmlCacheMassRefresh (line 31) | public function controllerActionPredispatchAdminhtmlCacheMassRefresh()
    method _getFpc (line 45) | protected function _getFpc()

FILE: app/code/community/Lesti/Fpc/Model/Observer/Parameters.php
  class Lesti_Fpc_Model_Observer_Parameters (line 17) | class Lesti_Fpc_Model_Observer_Parameters
    method fpcHelperCollectParams (line 24) | public function fpcHelperCollectParams($observer)
    method _getSessionParams (line 63) | protected function _getSessionParams()

FILE: app/code/community/Lesti/Fpc/Model/Observer/Save.php
  class Lesti_Fpc_Model_Observer_Save (line 17) | class Lesti_Fpc_Model_Observer_Save
    method catalogProductSaveAfter (line 24) | public function catalogProductSaveAfter($observer)
    method catalogCategorySaveAfter (line 49) | public function catalogCategorySaveAfter($observer)
    method cmsPageSaveAfter (line 62) | public function cmsPageSaveAfter($observer)
    method modelSaveAfter (line 78) | public function modelSaveAfter($observer)
    method reviewDeleteAfter (line 100) | public function reviewDeleteAfter($observer)
    method reviewSaveAfter (line 111) | public function reviewSaveAfter($observer)
    method cataloginventoryStockItemSaveAfter (line 122) | public function cataloginventoryStockItemSaveAfter($observer)
    method _getFpc (line 133) | protected function _getFpc()
    method _cmsBlockSaveAfter (line 141) | protected function _cmsBlockSaveAfter(Mage_Cms_Model_Block $block)
    method _catalogProductSaveAfterMassAction (line 149) | protected function _catalogProductSaveAfterMassAction(array $productIds)

FILE: app/code/community/Lesti/Fpc/Model/Observer/Tags.php
  class Lesti_Fpc_Model_Observer_Tags (line 17) | class Lesti_Fpc_Model_Observer_Tags
    method fpcObserverCollectCacheTags (line 22) | public function fpcObserverCollectCacheTags($observer)
    method getCmsIndexIndexCacheTags (line 53) | protected function getCmsIndexIndexCacheTags()
    method getCmsPageViewCacheTags (line 70) | protected function getCmsPageViewCacheTags(
    method getCatalogProductViewCacheTags (line 90) | protected function getCatalogProductViewCacheTags(
    method getCatalogCategoryViewCacheTags (line 146) | protected function getCatalogCategoryViewCacheTags(

FILE: app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax.php
  class Lesti_Fpc_Test_Block_Catalog_Product_View_Ajax (line 17) | class Lesti_Fpc_Test_Block_Catalog_Product_View_Ajax extends
    method setUp (line 25) | protected function setUp()
    method tearDown (line 36) | protected function tearDown()
    method testGetAjaxUrlFpcInactive (line 46) | public function testGetAjaxUrlFpcInactive()
    method testGetAjaxUrlMissCacheAbleAction (line 56) | public function testGetAjaxUrlMissCacheAbleAction()
    method testGetAjaxUrlDisabledRecentlyViewedProducts (line 65) | public function testGetAjaxUrlDisabledRecentlyViewedProducts()
    method testGetAjaxUrlNoCurrentProduct (line 74) | public function testGetAjaxUrlNoCurrentProduct()
    method testGetAjaxUrl (line 84) | public function testGetAjaxUrl()

FILE: app/code/community/Lesti/Fpc/Test/Block/Core/Messages.php
  class Lesti_Fpc_Test_Block_Core_Messages (line 17) | class Lesti_Fpc_Test_Block_Core_Messages extends Lesti_Fpc_Test_TestCase
    method setUp (line 24) | protected function setUp()
    method testGetGroupedHtml (line 34) | public function testGetGroupedHtml()

FILE: app/code/community/Lesti/Fpc/Test/Controller/Catalog/ProductController.php
  class Lesti_Fpc_Test_Controller_Catalog_ProductController (line 13) | class Lesti_Fpc_Test_Controller_Catalog_ProductController extends
    method testViewActionWithoutProduct (line 19) | public function testViewActionWithoutProduct()
    method testViewActionWithProduct (line 29) | public function testViewActionWithProduct()

FILE: app/code/community/Lesti/Fpc/Test/Helper/Block.php
  class Lesti_Fpc_Test_Helper_Block (line 19) | class Lesti_Fpc_Test_Helper_Block extends Lesti_Fpc_Test_TestCase
    method setUp (line 26) | protected function setUp()
    method testGetDynamicBlocks (line 36) | public function testGetDynamicBlocks()
    method testGetDynamicBlocksEmpty (line 48) | public function testGetDynamicBlocksEmpty()
    method testGetLazyBlocks (line 57) | public function testGetLazyBlocks()
    method testGetLazyBlocksEmpty (line 69) | public function testGetLazyBlocksEmpty()
    method testAreLazyBlocksValid (line 78) | public function testAreLazyBlocksValid()
    method testGetPlaceholderHtml (line 133) | public function testGetPlaceholderHtml()
    method testGetKey (line 144) | public function testGetKey()
    method testUseRecentlyViewedProductsTrue (line 156) | public function testUseRecentlyViewedProductsTrue()
    method testUseRecentlyViewedProductsFalse (line 165) | public function testUseRecentlyViewedProductsFalse()
    method testGetCacheTagsEmpty (line 173) | public function testGetCacheTagsEmpty()
    method testGetCacheTagsProductList (line 183) | public function testGetCacheTagsProductList()
    method testGetCacheTagsCmsBlock (line 205) | public function testGetCacheTagsCmsBlock()

FILE: app/code/community/Lesti/Fpc/Test/Helper/Block/Messages.php
  class Lesti_Fpc_Test_Helper_Block_Messages (line 17) | class Lesti_Fpc_Test_Helper_Block_Messages extends Lesti_Fpc_Test_TestCase
    method setUp (line 24) | protected function setUp()
    method testInitLayoutMessagesEmpty (line 33) | public function testInitLayoutMessagesEmpty()
    method testInitLayoutMessagesCatalog (line 43) | public function testInitLayoutMessagesCatalog()
    method testInitLayoutMessagesTag (line 64) | public function testInitLayoutMessagesTag()
    method testInitLayoutMessagesCheckout (line 85) | public function testInitLayoutMessagesCheckout()
    method testInitLayoutMessagesCustomer (line 106) | public function testInitLayoutMessagesCustomer()
    method testInitLayoutInvalidStorage (line 130) | public function testInitLayoutInvalidStorage()

FILE: app/code/community/Lesti/Fpc/Test/Helper/Data.php
  class Lesti_Fpc_Test_Helper_Data (line 17) | class Lesti_Fpc_Test_Helper_Data extends Lesti_Fpc_Test_TestCase
    method setUp (line 24) | protected function setUp()
    method testGetCacheableActions (line 34) | public function testGetCacheableActions()
    method testGetCacheableActionsEmpty (line 46) | public function testGetCacheableActionsEmpty()
    method testGetBypassHandles (line 55) | public function testGetBypassHandles()
    method testGetBypassHandlesEmpty (line 67) | public function testGetBypassHandlesEmpty()
    method testGetRefreshActions (line 76) | public function testGetRefreshActions()
    method testGetRefreshActionsEmpty (line 92) | public function testGetRefreshActionsEmpty()
    method testRegexUriParams (line 104) | public function testRegexUriParams(
    method testCanCacheRequest (line 127) | public function testCanCacheRequest($method, $expected, $params = arra...
    method getFullActionName (line 141) | public function getFullActionName()
    method _resetParams (line 152) | protected function _resetParams()

FILE: app/code/community/Lesti/Fpc/Test/Model/Fpc.php
  class Lesti_Fpc_Test_Model_Fpc (line 17) | class Lesti_Fpc_Test_Model_Fpc extends Lesti_Fpc_Test_TestCase
    method setUp (line 24) | protected function setUp()
    method saveLoadClean (line 34) | public function saveLoadClean()

FILE: app/code/community/Lesti/Fpc/Test/Model/Observer.php
  class Lesti_Fpc_Test_Model_Observer (line 17) | class Lesti_Fpc_Test_Model_Observer extends Lesti_Fpc_Test_TestCase
    method setUp (line 24) | protected function setUp()
    method tearDown (line 30) | protected function tearDown()
    method controllerActionPostdispatch (line 46) | public function controllerActionPostdispatch(

FILE: app/code/community/Lesti/Fpc/Test/Model/Observer/Clean.php
  class Lesti_Fpc_Test_Model_Observer_Clean (line 17) | class Lesti_Fpc_Test_Model_Observer_Clean extends Lesti_Fpc_Test_TestCase
    method setUp (line 24) | protected function setUp()
    method tearDown (line 30) | protected function tearDown()
    method testCoreCleanCache (line 39) | public function testCoreCleanCache()
    method testAdminhtmlCacheFlushAll (line 51) | public function testAdminhtmlCacheFlushAll()
    method testControllerActionPredispatchAdminhtmlCacheMassRefresh (line 62) | public function testControllerActionPredispatchAdminhtmlCacheMassRefre...

FILE: app/code/community/Lesti/Fpc/Test/Model/Observer/Parameters.php
  class Lesti_Fpc_Test_Model_Observer_Parameters (line 17) | class Lesti_Fpc_Test_Model_Observer_Parameters extends Lesti_Fpc_Test_Te...
    method testFpcHelperCollectParams (line 23) | public function testFpcHelperCollectParams()

FILE: app/code/community/Lesti/Fpc/Test/Model/Observer/Save.php
  class Lesti_Fpc_Test_Model_Observer_Save (line 17) | class Lesti_Fpc_Test_Model_Observer_Save extends Lesti_Fpc_Test_TestCase
    method testCalaogProductSaveAfter (line 22) | public function testCalaogProductSaveAfter()
    method testCatalogCategorySaveAfter (line 63) | public function testCatalogCategorySaveAfter()
    method testCmsPageSaveAfter (line 95) | public function testCmsPageSaveAfter()
    method testCmsBlockSaveAfter (line 117) | public function testCmsBlockSaveAfter()
    method testCatalogProductSaveAfterMassAction (line 143) | public function testCatalogProductSaveAfterMassAction()
    method testCataloginventoryStockItemSaveAfter (line 180) | public function testCataloginventoryStockItemSaveAfter()

FILE: app/code/community/Lesti/Fpc/Test/Model/Observer/Tags.php
  class Lesti_Fpc_Test_Model_Observer_Tags (line 19) | class Lesti_Fpc_Test_Model_Observer_Tags extends Lesti_Fpc_Test_TestCase
    method testFpcObserverCollectCacheTags (line 26) | public function testFpcObserverCollectCacheTags(
    method testGetCmsIndexIndexCacheTagsZero (line 47) | public function testGetCmsIndexIndexCacheTagsZero()
    method testGetCmsIndexIndexCacheTags (line 61) | public function testGetCmsIndexIndexCacheTags()
    method testGetCmsPageViewCacheTagsEmpty (line 75) | public function testGetCmsPageViewCacheTagsEmpty()
    method testGetCmsPageViewCacheTagsPageId (line 88) | public function testGetCmsPageViewCacheTagsPageId()
    method testGetCmsPageViewCacheTagsId (line 104) | public function testGetCmsPageViewCacheTagsId()
    method testGetCatalogProductViewCacheTagsZero (line 120) | public function testGetCatalogProductViewCacheTagsZero()
    method testGetCatalogProductViewCacheTagsSimpleProduct (line 133) | public function testGetCatalogProductViewCacheTagsSimpleProduct()
    method testGetCatalogProductViewCacheTagsWithCategory (line 149) | public function testGetCatalogProductViewCacheTagsWithCategory()
    method testGetCatalogProductViewCacheTagsConfigurableProduct (line 169) | public function testGetCatalogProductViewCacheTagsConfigurableProduct()
    method testGetCatalogProductViewCacheTagsGroupedProduct (line 197) | public function testGetCatalogProductViewCacheTagsGroupedProduct()
    method testGetCatalogCategoryViewCacheTagsEmpty (line 224) | public function testGetCatalogCategoryViewCacheTagsEmpty()
    method testGetCatalogCategoryViewCacheTags (line 237) | public function testGetCatalogCategoryViewCacheTags()
    method dispatchCollectTagsEvent (line 254) | protected function dispatchCollectTagsEvent(array $tags)

FILE: app/code/community/Lesti/Fpc/Test/TestCase.php
  class Lesti_Fpc_Test_TestCase (line 17) | abstract class Lesti_Fpc_Test_TestCase extends
    method setUp (line 29) | protected function setUp()
    method tearDown (line 52) | protected function tearDown()
    method clearBaseUrlProperty (line 61) | protected function clearBaseUrlProperty()
    method setFullActionName (line 74) | protected function setFullActionName(

FILE: app/code/community/Lesti/Fpc/controllers/Catalog/ProductController.php
  class Lesti_Fpc_Catalog_ProductController (line 17) | class Lesti_Fpc_Catalog_ProductController extends
    method viewAction (line 20) | public function viewAction()
Condensed preview — 76 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (158K chars).
[
  {
    "path": ".coveralls.yml",
    "chars": 12,
    "preview": "src_dir: app"
  },
  {
    "path": ".gitignore",
    "chars": 29,
    "preview": "/vendor\n/composer.lock\n.idea\n"
  },
  {
    "path": ".travis.yml",
    "chars": 1128,
    "preview": "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=magent"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 566,
    "preview": "# Changelog\n\nAll Notable changes to `Lesti_Fpc` will be documented in this file.\n\nUpdates should follow the [Keep a CHAN"
  },
  {
    "path": "CONDUCT.md",
    "chars": 3221,
    "preview": "# Contributor Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncont"
  },
  {
    "path": "LICENSE.md",
    "chars": 10577,
    "preview": "# Open Software License v. 3.0 (OSL-3.0)\n\n> This Open Software License (the \"License\") applies to any original work of a"
  },
  {
    "path": "README.md",
    "chars": 2118,
    "preview": "# Lesti_Fpc\n\n[![Latest Release][ico-version]][link-release]\n[![Software License][ico-license]](LICENSE.md)\n[![Build Stat"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Block/Catalog/Product/View/Ajax.php",
    "chars": 1449,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Core/Block/Messages.php",
    "chars": 1130,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Helper/Abstract.php",
    "chars": 909,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Helper/Block/Messages.php",
    "chars": 1598,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Helper/Block.php",
    "chars": 3847,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Helper/Data.php",
    "chars": 8751,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Model/Adminhtml/System/Config/Source/Gzcompress.php",
    "chars": 1033,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Model/Fpc/CacheItem.php",
    "chars": 908,
    "preview": "<?php\n\n/**\n * Class Lesti_Fpc_Model_Fpc_CacheItem\n */\nclass Lesti_Fpc_Model_Fpc_CacheItem\n{\n    /**\n     * @var string\n "
  },
  {
    "path": "app/code/community/Lesti/Fpc/Model/Fpc.php",
    "chars": 4641,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Model/Observer/Clean.php",
    "chars": 1261,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Model/Observer/Parameters.php",
    "chars": 2139,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Model/Observer/Save.php",
    "chars": 4690,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Model/Observer/Tags.php",
    "chars": 5195,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Model/Observer.php",
    "chars": 10317,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax/fixtures/get_ajax_url.yaml",
    "chars": 182,
    "preview": "config:\n    default/system/fpc/cache_actions: catalog_product_view\n    default/system/fpc/use_recently_viewed_products: "
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax/fixtures/get_ajax_url_disabled_recently_viewed_products.yaml",
    "chars": 122,
    "preview": "config:\n    default/system/fpc/cache_actions: catalog_product_view\n    default/system/fpc/use_recently_viewed_products: "
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax/fixtures/get_ajax_url_fpc_inactive.yaml",
    "chars": 122,
    "preview": "config:\n    default/system/fpc/cache_actions: catalog_product_view\n    default/system/fpc/use_recently_viewed_products: "
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax/fixtures/get_ajax_url_miss_cache_able_action.yaml",
    "chars": 101,
    "preview": "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",
    "chars": 122,
    "preview": "config:\n    default/system/fpc/cache_actions: catalog_product_view\n    default/system/fpc/use_recently_viewed_products: "
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Block/Catalog/Product/View/Ajax.php",
    "chars": 2773,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Block/Core/Messages.php",
    "chars": 1554,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Controller/Catalog/ProductController/fixtures/view_action_with_product.yaml",
    "chars": 176,
    "preview": "tables:\n  eav_attribute_set:\n    - attribute_set_id: 13\n      entity_type_id: 4\n  catalog_product_entity:\n    - entity_i"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Controller/Catalog/ProductController.php",
    "chars": 873,
    "preview": "<?php\n/**\n * Created by JetBrains PhpStorm.\n * User: gordon\n * Date: 10/19/14\n * Time: 1:56 PM\n * To change this templat"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Block/Messages.php",
    "chars": 4350,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/are_lazy_blocks_valid.yaml",
    "chars": 65,
    "preview": "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",
    "chars": 125,
    "preview": "config:\n    default/system/fpc/dynamic_blocks: >\n     messages,\n     global_messages, global_notices\n      , global_mess"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/get_dynamic_blocks_empty.yaml",
    "chars": 51,
    "preview": "config:\n    default/system/fpc/dynamic_blocks: \" \"\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/get_lazy_blocks.yaml",
    "chars": 126,
    "preview": "config:\n    default/system/fpc/lazy_blocks: >\n     top.links,\n     cart_sidebar, catalog.compare.sidebar\n      , cart_si"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/get_lazy_blocks_empty.yaml",
    "chars": 48,
    "preview": "config:\n    default/system/fpc/lazy_blocks: \" \"\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Block/fixtures/use_recently_viewed_products_false.yaml",
    "chars": 62,
    "preview": "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",
    "chars": 62,
    "preview": "config:\n    default/system/fpc/use_recently_viewed_products: 1"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Block.php",
    "chars": 6587,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/can_cache_request.yaml",
    "chars": 166,
    "preview": "config:\n    default/system/fpc/miss_uri_params: >\n     no_cache=/^1$/,\n     limit=/^([0-9]+)|(all)$/, dir=/^[0-9a-z_]+$/"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/get_bypass_handles.yaml",
    "chars": 115,
    "preview": "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",
    "chars": 51,
    "preview": "config:\n    default/system/fpc/bypass_handles: \" \"\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/get_cacheable_actions.yaml",
    "chars": 133,
    "preview": "config:\n    default/system/fpc/cache_actions: >\n     cms_index_index,\n     cms_page_view, catalog_product_view\n      , c"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/get_cacheable_actions_empty.yaml",
    "chars": 50,
    "preview": "config:\n    default/system/fpc/cache_actions: \" \"\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/get_refresh_actions.yaml",
    "chars": 155,
    "preview": "config:\n    default/system/fpc/refresh_actions: >\n     checkout_cart_add,\n     checkout_cart_delete, checkout_cart_updat"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/get_refresh_actions_empty.yaml",
    "chars": 52,
    "preview": "config:\n    default/system/fpc/refresh_actions: \" \"\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/fixtures/regex_uri_params.yaml",
    "chars": 65,
    "preview": "config:\n    default/system/fpc/uri_params: id,/^filter_\\w+/,order"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/providers/testCanCacheRequest.yaml",
    "chars": 347,
    "preview": "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_limi"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data/providers/testRegexUriParams.yaml",
    "chars": 1018,
    "preview": "test_matched_param:\n  uri_params:\n    -\n      id: 1\n    -\n      id: 1\n      filter_1_attribute: filter_1_value_1\n    -\n "
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Helper/Data.php",
    "chars": 4107,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Fpc/fixtures/save_load_clean.yaml",
    "chars": 50,
    "preview": "config:\n    default/system/fpc/gzcompress_level: 3"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Fpc.php",
    "chars": 1889,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Clean.php",
    "chars": 2892,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Parameters/fixtures/fpc_helper_collect_params.yaml",
    "chars": 68,
    "preview": "config:\n  default/system/fpc/session_params: >\n    magento,\n    fpc\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Parameters.php",
    "chars": 1698,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Save.php",
    "chars": 6998,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Tags/fixtures/fpc_observer_collect_cache_tags.yaml",
    "chars": 49,
    "preview": "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",
    "chars": 315,
    "preview": "tables:\n  eav_attribute_set:\n    - attribute_set_id: 13\n      entity_type_id: 4\n  catalog_product_entity:\n    - entity_i"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Tags/fixtures/get_catalog_product_view_cache_tags_grouped_product.yaml",
    "chars": 339,
    "preview": "tables:\n  eav_attribute_set:\n    - attribute_set_id: 13\n      entity_type_id: 4\n  catalog_product_entity:\n    - entity_i"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Tags/fixtures/get_cms_index_index_cache_tags.yaml",
    "chars": 49,
    "preview": "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",
    "chars": 49,
    "preview": "config:\n    default/web/default/cms_home_page: 0\n"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Tags/providers/testFpcObserverCollectCacheTags.yaml",
    "chars": 1045,
    "preview": "test_cms_index_index:\n  route_name: cms\n  controller_name: index\n  action_name: index\n  expected_cache_tags:\n    # sha1("
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/Tags.php",
    "chars": 9345,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/fixtures/controller_action_postdispatch.yaml",
    "chars": 155,
    "preview": "config:\n    default/system/fpc/refresh_actions: >\n     checkout_cart_add,\n     checkout_cart_delete, checkout_cart_updat"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer/providers/controllerActionPostdispatch.yaml",
    "chars": 156,
    "preview": "test_false:\n  route: checkout\n  controller: cart\n  action: add\n  expected: 0\ntest_true:\n  route: catalog\n  controller: p"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/Model/Observer.php",
    "chars": 1890,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/Test/TestCase.php",
    "chars": 2590,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/controllers/Catalog/ProductController.php",
    "chars": 891,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/code/community/Lesti/Fpc/etc/config.xml",
    "chars": 11390,
    "preview": "<?xml version=\"1.0\"?>\n<!--\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https:/"
  },
  {
    "path": "app/code/community/Lesti/Fpc/etc/system.xml",
    "chars": 8798,
    "preview": "<?xml version=\"1.0\"?>\n<!--\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https:/"
  },
  {
    "path": "app/design/frontend/base/default/layout/fpc.xml",
    "chars": 693,
    "preview": "<?xml version=\"1.0\"?>\n<!--\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https:/"
  },
  {
    "path": "app/design/frontend/base/default/template/fpc/catalog/product/view/ajax.phtml",
    "chars": 529,
    "preview": "<?php\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https://github.com/GordonLes"
  },
  {
    "path": "app/etc/fpc.xml.sample",
    "chars": 2228,
    "preview": "<?xml version=\"1.0\"?>\n<!--\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https:/"
  },
  {
    "path": "app/etc/modules/Lesti_Fpc.xml",
    "chars": 696,
    "preview": "<?xml version=\"1.0\"?>\n<!--\n/**\n * Lesti_Fpc (http:gordonlesti.com/lestifpc)\n *\n * PHP version 5\n *\n * @link      https:/"
  },
  {
    "path": "composer.json",
    "chars": 1422,
    "preview": "{\n    \"name\": \"gordonlesti/lesti_fpc\",\n    \"type\": \"magento-module\",\n    \"description\": \"Simple Magento Fullpagecache\",\n"
  },
  {
    "path": "modman",
    "chars": 351,
    "preview": "app/code/community/Lesti/Fpc app/code/community/Lesti/Fpc\napp/design/frontend/base/default/layout/fpc.xml app/design/fro"
  }
]

About this extraction

This page contains the full source code of the GordonLesti/Lesti_Fpc GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 76 files (142.4 KB), approximately 39.4k tokens, and a symbol index with 171 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!