<?php



/**

 * W3 PgCache plugin - administrative interface

 */

if (!defined('W3TC')) {

    die();

}



w3_require_once(W3TC_INC_DIR . '/functions/file.php');

w3_require_once(W3TC_INC_DIR . '/functions/rule.php');

w3_require_once(W3TC_LIB_W3_DIR . '/Plugin.php');



/**

 * Class W3_Plugin_PgCacheAdmin

 */

class W3_Plugin_PgCacheAdmin extends W3_Plugin {

    /**

     * Activate plugin action

     */

    function activate() {

        w3_require_once(W3TC_INC_DIR . '/functions/activation.php');



        if ($this->_config->get_boolean('pgcache.enabled') && $this->_config->get_string('pgcache.engine') == 'file_generic') {

            /**

             * Disable enhanced mode if permalink structure is disabled

             */

            $permalink_structure = get_option('permalink_structure');



            if ($permalink_structure == '') {

                $this->_config->set('pgcache.engine', 'file');

                $this->_config->save();

            } else {

                if (w3_can_modify_rules(w3_get_pgcache_rules_core_path())) {

                    try {

                        $this->write_rules_core();

                    } catch (Exception $e) {}

                }



                if (w3_can_modify_rules(w3_get_pgcache_rules_cache_path())) {

                    try {

                        $this->write_rules_cache();

                    } catch (Exception $e)

                    {}

                }

            }

        }



        try{

            w3_copy_if_not_equal(W3TC_INSTALL_FILE_ADVANCED_CACHE, W3TC_ADDIN_FILE_ADVANCED_CACHE);

        }catch (Exception $ex) {}



        if (file_exists(W3TC_ADDIN_FILE_ADVANCED_CACHE)) {

            if ((!defined('WP_CACHE') || !WP_CACHE)) {

                try {

                    $this->enable_wp_cache();

                } catch(Exception $ex) {}

            }

        }



        $this->schedule();

        $this->schedule_prime();

    }



    /**

     * Deactivate plugin action

     */

    function deactivate() {

        $errors = array('errors' => array(), 'errors_short_form' => array(), 'ftp_form' => null);

        $results = array();

        $this->unschedule_prime();

        $this->unschedule();

        w3_require_once(W3TC_INC_DIR . '/functions/activation.php');

        $results[] = $this->disable_wp_cache_with_message();



        if (w3_can_modify_rules(w3_get_pgcache_rules_cache_path())) {

            $this->remove_rules_cache();

        }



        if (w3_can_modify_rules(w3_get_pgcache_rules_core_path())) {

            $results[] = $this->remove_rules_core_with_message();

        }



        if ($results) {

            foreach ($results as $result) {

                if ($result['errors']) {

                    $errors['errors'] = array_merge($errors['errors'], $result['errors']);

                    $errors['errors_short_form'] = array_merge($errors['errors_short_form'], $result['errors_short_form']);

                    if (!isset($errors['ftp_form']))

                        $errors['ftp_form'] = $result['ftp_form'];

                }

            }

        }



        return $errors;

    }



    /**

     * Called from admin interface before configuration is changed

     *

     * @param object $old_config

     */

    function before_config_change(&$old_config, &$new_config) {

        if ($old_config->get_integer('pgcache.file.gc') !=

                $new_config->get_integer('pgcache.file.gc')) {

            $this->unschedule();

        }



        if ($old_config->get_integer('pgcache.prime.interval') !=

                $new_config->get_integer('pgcache.prime.interval')) {

            $this->unschedule_prime();

        }

    }



    /**

     * Called from admin interface after configuration is changed

     */

    function after_config_change() {

        $this->schedule();

        $this->schedule_prime();



        /**

         * Write page cache rewrite rules

         */

        if ($this->_config->get_boolean('pgcache.enabled') &&

                $this->_config->get_string('pgcache.engine') == 'file_generic') {

            if (w3_can_modify_rules(w3_get_pgcache_rules_core_path())) {

                try {

                    $this->write_rules_core();

                } catch (Exception $e) {}

            }



            if (w3_can_modify_rules(w3_get_pgcache_rules_cache_path())) {

                try {

                    $this->write_rules_cache();

                } catch (Exception $e)

                {}

            }

        } else {

            if (w3_can_modify_rules(w3_get_pgcache_rules_core_path())) {

                try {

                    $this->remove_rules_core();

                } catch (Exception $e) {}

            }



            if (w3_can_modify_rules(w3_get_pgcache_rules_cache_path())) {

                $this->remove_rules_cache();

            }

        }

    }



    function cleanup() {

        // We check to see if we're dealing with a cluster

        $config = w3_instance('W3_Config');

        $is_cluster = $config->get_boolean('cluster.messagebus.enabled');



        // If we are, we notify the subscribers. If not, we just cleanup in here

        if ($is_cluster) {

            $this->cleanup_cluster();

        } else {

            $this->cleanup_local();

        }



    }

    

    /**

     * Will trigger notifications to be sent to the cluster to 'order' them to clean their page cache.

     */

    function cleanup_cluster() {

        $sns_client = w3_instance('W3_Enterprise_SnsClient');

        $sns_client->pgcache_cleanup();

    }

    

    function cleanup_local() {

        $engine = $this->_config->get_string('pgcache.engine');



        switch ($engine) {

            case 'file':

                w3_require_once(W3TC_LIB_W3_DIR . '/Cache/File/Cleaner.php');



                $w3_cache_file_cleaner = new W3_Cache_File_Cleaner(array(

                    'cache_dir' => w3_cache_blog_dir('page'),

                    'clean_timelimit' => $this->_config->get_integer('timelimit.cache_gc')

                ));



                $w3_cache_file_cleaner->clean();

                break;



            case 'file_generic':

                w3_require_once(W3TC_LIB_W3_DIR . '/Cache/File/Cleaner/Generic.php');



                if (w3_get_blog_id() == 0)

                    $flush_dir = W3TC_CACHE_PAGE_ENHANCED_DIR;

                else

                    $flush_dir = W3TC_CACHE_PAGE_ENHANCED_DIR . '/' . w3_get_domain(w3_get_host());



                $w3_cache_file_cleaner_generic = new W3_Cache_File_Cleaner_Generic(array(

                    'exclude' => array(

                        '.htaccess'

                    ),

                    'cache_dir' => $flush_dir,

                    'expire' => $this->_config->get_integer('browsercache.html.lifetime'),

                    'clean_timelimit' => $this->_config->get_integer('timelimit.cache_gc')

                ));



                $w3_cache_file_cleaner_generic->clean();

                break;

        }

    }



    /**

     * Prime cache

     *

     * @param integer $start

     * @return void

     */

    function prime($start = 0) {

        $start = (int) $start;



        /**

         * Don't start cache prime if queues are still scheduled

         */

        if ($start == 0) {

            $crons = _get_cron_array();



            foreach ($crons as $timestamp => $hooks) {

                foreach ($hooks as $hook => $keys) {

                    foreach ($keys as $key => $data) {

                        if ($hook == 'w3_pgcache_prime' && count($data['args'])) {

                            return;

                        }

                    }

                }

            }

        }



        $interval = $this->_config->get_integer('pgcache.prime.interval');

        $limit = $this->_config->get_integer('pgcache.prime.limit');

        $sitemap = $this->_config->get_string('pgcache.prime.sitemap');



        /**

         * Parse XML sitemap

         */

        $urls = $this->parse_sitemap($sitemap);



        /**

         * Queue URLs

         */

        $queue = array_slice($urls, $start, $limit);



        if (count($urls) > ($start + $limit)) {

            wp_schedule_single_event(time() + $interval, 'w3_pgcache_prime', array(

                $start + $limit

            ));

        }



        /**

         * Make HTTP requests and prime cache

         */

        w3_require_once(W3TC_INC_DIR . '/functions/http.php');

        w3_require_once(W3TC_INC_DIR . '/functions/url.php');



        // use empty user-agent since by default we use W3TC-powered by

        // which blocks caching

        foreach ($queue as $url)

            w3_http_get($url, array('user-agent' => ''));

    }



    /**

     * Parses sitemap

     *

     * @param string $url

     * @return array

     */

    function parse_sitemap($url) {

        w3_require_once(W3TC_INC_DIR . '/functions/http.php');



        $urls = array();

        $response = w3_http_get($url);



        if (!is_wp_error($response) && $response['response']['code'] == 200) {

            $url_matches = null;

            $sitemap_matches = null;



            if (preg_match_all('~<sitemap>(.*?)</sitemap>~is', $response['body'], $sitemap_matches)) {

                $loc_matches = null;



                foreach ($sitemap_matches[1] as $sitemap_match) {

                    if (preg_match('~<loc>(.*?)</loc>~is', $sitemap_match, $loc_matches)) {

                        $loc = trim($loc_matches[1]);



                        if ($loc) {

                            $urls = array_merge($urls, $this->parse_sitemap($loc));

                        }

                    }

                }

            } elseif (preg_match_all('~<url>(.*?)</url>~is', $response['body'], $url_matches)) {

                $locs = array();

                $loc_matches = null;

                $priority_matches = null;



                foreach ($url_matches[1] as $url_match) {

                    $loc = '';

                    $priority = 0;



                    if (preg_match('~<loc>(.*?)</loc>~is', $url_match, $loc_matches)) {

                        $loc = trim($loc_matches[1]);

                    }



                    if (preg_match('~<priority>(.*?)</priority>~is', $url_match, $priority_matches)) {

                        $priority = (double) trim($priority_matches[1]);

                    }



                    if ($loc && $priority) {

                        $locs[$loc] = $priority;

                    }

                }



                arsort($locs);



                $urls = array_keys($locs);

            }

        }



        return $urls;

    }



    /**

     * Schedules events

     */

    function schedule() {

        if ($this->_config->get_boolean('pgcache.enabled') && ($this->_config->get_string('pgcache.engine') == 'file' || $this->_config->get_string('pgcache.engine') == 'file_generic')) {

            if (!wp_next_scheduled('w3_pgcache_cleanup')) {

                wp_schedule_event(current_time('timestamp'), 'w3_pgcache_cleanup', 'w3_pgcache_cleanup');

            }

        } else {

            $this->unschedule();

        }

    }



    /**

     * Schedule prime event

     */

    function schedule_prime() {

        if ($this->_config->get_boolean('pgcache.enabled') && $this->_config->get_boolean('pgcache.prime.enabled')) {

            if (!wp_next_scheduled('w3_pgcache_prime')) {

                wp_schedule_event(current_time('timestamp'), 'w3_pgcache_prime', 'w3_pgcache_prime');

            }

        } else {

            $this->unschedule_prime();

        }

    }



    /**

     * Unschedules events

     */

    function unschedule() {

        if (wp_next_scheduled('w3_pgcache_cleanup')) {

            wp_clear_scheduled_hook('w3_pgcache_cleanup');

        }

    }



    /**

     * Unschedules prime

     */

    function unschedule_prime() {

        if (wp_next_scheduled('w3_pgcache_prime')) {

            wp_clear_scheduled_hook('w3_pgcache_prime');

        }

    }



    /**

     * Erases WP_CACHE define

     *

     * @param string $content

     * @return mixed

     */

    function erase_wp_cache($content) {

        $content = preg_replace("~\\/\\*\\* Enable W3 Total Cache \\*\\*?\\/.*?\\/\\/ Added by W3 Total Cache(\r\n)*~s", '', $content);

        $content = preg_replace("~(\\/\\/\\s*)?define\\s*\\(\\s*['\"]?WP_CACHE['\"]?\\s*,.*?\\)\\s*;+\\r?\\n?~is", '', $content);



        return $content;

    }



    /**

     * Enables WP_CACHE

     * @return boolean

     * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials

     * @throws FileOperationException

     */

    function enable_wp_cache() {



        $config_path = w3_get_wp_config_path();

        $config_data = w3_wp_read_from_file($config_path);



        if ($config_data === false) {

            return false;

        }



        $new_config_data = $this->erase_wp_cache($config_data);

        $new_config_data = preg_replace('~<\?(php)?~', "\\0\r\n/** Enable W3 Total Cache */\r\ndefine('WP_CACHE', true); // Added by W3 Total Cache\r\n", $new_config_data, 1);



        if ($new_config_data != $config_data) {

            w3_wp_write_to_file($config_path, $new_config_data);

         }



        return true;

    }



    /**

     * Disables WP_CACHE

     * @return bool

     * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials

     * @throws FileOperationException

     */

    function disable_wp_cache() {

        $config_path = w3_get_wp_config_path();

        $config_data = @file_get_contents($config_path);



        if ($config_data === false) {

            return false;

        }



        $new_config_data = $this->erase_wp_cache($config_data);



        if ($new_config_data != $config_data) {

            w3_wp_write_to_file($config_path, $new_config_data);

        }



        return true;

    }



    /**

     * Generates rules for WP dir

     *

     * @return string

     */

    function generate_rules_core() {

        switch (true) {

            case w3_is_apache():

            case w3_is_litespeed():

                return $this->generate_rules_core_apache();



            case w3_is_nginx():

                return $this->generate_rules_core_nginx();

        }



        return false;

    }



    /**

     * Generates directives for file cache dir

     *

     * @return string

     */

    function generate_rules_cache() {

        switch (true) {

            case w3_is_apache():

            case w3_is_litespeed():

                return $this->generate_rules_cache_apache();



            case w3_is_nginx():

                return $this->generate_rules_cache_nginx();

        }



        return false;

    }



    /**

     * Generates rules for WP dir

     *

     * @return string

     */

    function generate_rules_core_apache() {

        $is_network = w3_is_network();



        $base_path = w3_get_base_path();

        $home_path = w3_get_home_path();

        $rewrite_base = ($is_network ? $base_path : $home_path);

        $cache_dir = w3_path(W3TC_CACHE_PAGE_ENHANCED_DIR);

        $permalink_structure = get_option('permalink_structure');



        $current_user = get_currentuserinfo();



        /**

         * Auto reject cookies

         */

        $reject_cookies = array(

            'comment_author',

            'wp-postpass'

        );



        if ($this->_config->get_string('pgcache.engine') == 'file_generic') {

            $reject_cookies[] = 'w3tc_logged_out';

        }



        /**

         * Reject cache for logged in users

         * OR

         * Reject cache for roles if any

         */

        if ($this->_config->get_boolean('pgcache.reject.logged')) {

            $reject_cookies = array_merge($reject_cookies, array(

                'wordpress_logged_in'

            ));

        } elseif($this->_config->get_boolean('pgcache.reject.logged_roles')) {

            $new_cookies = array();

            foreach( $this->_config->get_array('pgcache.reject.roles') as $role ) {

                $new_cookies[] = 'w3tc_logged_' . md5(NONCE_KEY . $role);

            }

            $reject_cookies = array_merge($reject_cookies, $new_cookies);

        }



        /**

         * Custom config

         */

        $reject_cookies = array_merge($reject_cookies, $this->_config->get_array('pgcache.reject.cookie'));

        w3_array_trim($reject_cookies);



        $reject_user_agents = $this->_config->get_array('pgcache.reject.ua');

        if ($this->_config->get_boolean('pgcache.compatibility')) {

            $reject_user_agents = array_merge(array(W3TC_POWERED_BY), $reject_user_agents);

        }



        w3_array_trim($reject_user_agents);



        /**

         * Generate directives

         */

        $env_W3TC_UA = '';

        $env_W3TC_REF = '';

        $env_W3TC_SSL = '';

        $env_W3TC_ENC = '';



        $rules = '';

        $rules .= W3TC_MARKER_BEGIN_PGCACHE_CORE . "\n";

        $rules .= "<IfModule mod_rewrite.c>\n";

        $rules .= "    RewriteEngine On\n";

        $rules .= "    RewriteBase " . $rewrite_base . "\n";



        if ($this->_config->get_boolean('pgcache.debug')) {

            $rules .= "    RewriteRule ^(.*\\/)?w3tc_rewrite_test$ $1?w3tc_rewrite_test=1 [L]\n";

        }



        /**

         * Check for mobile redirect

         */

        if ($this->_config->get_boolean('mobile.enabled')) {

            $mobile_groups = $this->_config->get_array('mobile.rgroups');



            foreach ($mobile_groups as $mobile_group => $mobile_config) {

                $mobile_enabled = (isset($mobile_config['enabled']) ? (boolean) $mobile_config['enabled'] : false);

                $mobile_agents = (isset($mobile_config['agents']) ? (array) $mobile_config['agents'] : '');

                $mobile_redirect = (isset($mobile_config['redirect']) ? $mobile_config['redirect'] : '');



                if ($mobile_enabled && count($mobile_agents) && $mobile_redirect) {

                    $rules .= "    RewriteCond %{HTTP_USER_AGENT} (" . implode('|', $mobile_agents) . ") [NC]\n";

                    $rules .= "    RewriteRule .* " . $mobile_redirect . " [R,L]\n";

                }

            }

        }



        /**

         * Check for referrer redirect

         */

        if ($this->_config->get_boolean('referrer.enabled')) {

            $referrer_groups = $this->_config->get_array('referrer.rgroups');



            foreach ($referrer_groups as $referrer_group => $referrer_config) {

                $referrer_enabled = (isset($referrer_config['enabled']) ? (boolean) $referrer_config['enabled'] : false);

                $referrer_referrers = (isset($referrer_config['referrers']) ? (array) $referrer_config['referrers'] : '');

                $referrer_redirect = (isset($referrer_config['redirect']) ? $referrer_config['redirect'] : '');



                if ($referrer_enabled && count($referrer_referrers) && $referrer_redirect) {

                    $rules .= "    RewriteCond %{HTTP_COOKIE} w3tc_referrer=.*(" . implode('|', $referrer_referrers) . ") [NC]\n";

                    $rules .= "    RewriteRule .* " . $referrer_redirect . " [R,L]\n";

                }

            }

        }



        /**

         * Set mobile groups

         */

        if ($this->_config->get_boolean('mobile.enabled')) {

            $mobile_groups = array_reverse($this->_config->get_array('mobile.rgroups'));



            foreach ($mobile_groups as $mobile_group => $mobile_config) {

                $mobile_enabled = (isset($mobile_config['enabled']) ? (boolean) $mobile_config['enabled'] : false);

                $mobile_agents = (isset($mobile_config['agents']) ? (array) $mobile_config['agents'] : '');

                $mobile_redirect = (isset($mobile_config['redirect']) ? $mobile_config['redirect'] : '');



                if ($mobile_enabled && count($mobile_agents) && !$mobile_redirect) {

                    $rules .= "    RewriteCond %{HTTP_USER_AGENT} (" . implode('|', $mobile_agents) . ") [NC]\n";

                    $rules .= "    RewriteRule .* - [E=W3TC_UA:_" . $mobile_group . "]\n";

                    $env_W3TC_UA = '%{ENV:W3TC_UA}';

                }

            }

        }



        /**

         * Set referrer groups

         */

        if ($this->_config->get_boolean('referrer.enabled')) {

            $referrer_groups = array_reverse($this->_config->get_array('referrer.rgroups'));



            foreach ($referrer_groups as $referrer_group => $referrer_config) {

                $referrer_enabled = (isset($referrer_config['enabled']) ? (boolean) $referrer_config['enabled'] : false);

                $referrer_referrers = (isset($referrer_config['referrers']) ? (array) $referrer_config['referrers'] : '');

                $referrer_redirect = (isset($referrer_config['redirect']) ? $referrer_config['redirect'] : '');



                if ($referrer_enabled && count($referrer_referrers) && !$referrer_redirect) {

                    $rules .= "    RewriteCond %{HTTP_COOKIE} w3tc_referrer=.*(" . implode('|', $referrer_referrers) . ") [NC]\n";

                    $rules .= "    RewriteRule .* - [E=W3TC_REF:_" . $referrer_group . "]\n";

                    $env_W3TC_REF = '%{ENV:W3TC_REF}';

                }

            }

        }



        /**

         * Set HTTPS

         */

        if ($this->_config->get_boolean('pgcache.cache.ssl')) {

            $rules .= "    RewriteCond %{HTTPS} =on\n";

            $rules .= "    RewriteRule .* - [E=W3TC_SSL:_ssl]\n";

            $rules .= "    RewriteCond %{SERVER_PORT} =443\n";

            $rules .= "    RewriteRule .* - [E=W3TC_SSL:_ssl]\n";

            $env_W3TC_SSL = '%{ENV:W3TC_SSL}';

        }



        $cache_path = str_replace(w3_get_document_root(), '', $cache_dir);



        /**

         * Set Accept-Encoding

         */

        if ($this->_config->get_boolean('browsercache.enabled') && $this->_config->get_boolean('browsercache.html.compression')) {

            $rules .= "    RewriteCond %{HTTP:Accept-Encoding} gzip\n";

            $rules .= "    RewriteRule .* - [E=W3TC_ENC:_gzip]\n";

            $env_W3TC_ENC = '%{ENV:W3TC_ENC}';

        }



        $use_cache_rules = '';

        /**

         * Don't accept POSTs

         */

        $use_cache_rules .= "    RewriteCond %{REQUEST_METHOD} !=POST\n";



        /**

         * Query string should be empty

         */

        $use_cache_rules .= "    RewriteCond %{QUERY_STRING} =\"\"\n";



        /**

         * Check permalink structure trailing slash

         */

        if (substr($permalink_structure, -1) == '/') {

            $use_cache_rules .= "    RewriteCond %{REQUEST_URI} \\/$\n";

        }



        /**

         * Check for rejected cookies

         */

        $use_cache_rules .= "    RewriteCond %{HTTP_COOKIE} !(" . implode('|', array_map('w3_preg_quote', $reject_cookies)) . ") [NC]\n";



        /**

         * Check for rejected user agents

         */

        if (count($reject_user_agents)) {

            $use_cache_rules .= "    RewriteCond %{HTTP_USER_AGENT} !(" . implode('|', array_map('w3_preg_quote', $reject_user_agents)) . ") [NC]\n";

        }



        /**

         * Make final rewrites for specific files

         */

        $uri_prefix =  $cache_path . '/%{HTTP_HOST}/%{REQUEST_URI}/' .

            '_index' . $env_W3TC_UA . $env_W3TC_REF . $env_W3TC_SSL;

        $switch = " -" . ($this->_config->get_boolean('pgcache.file.nfs') ? 'F' : 'f');



        // support for GoDaddy servers configuration which uses

        // SUBDOMAIN_DOCUMENT_ROOT variable

        if (isset($_SERVER['SUBDOMAIN_DOCUMENT_ROOT']) &&

            $_SERVER['SUBDOMAIN_DOCUMENT_ROOT'] != $_SERVER['DOCUMENT_ROOT'])

            $document_root = '%{ENV:SUBDOMAIN_DOCUMENT_ROOT}';

        elseif (isset($_SERVER['PHP_DOCUMENT_ROOT']) &&

            $_SERVER['PHP_DOCUMENT_ROOT'] != $_SERVER['DOCUMENT_ROOT'])

            $document_root = '%{ENV:PHP_DOCUMENT_ROOT}';

        else

            $document_root = '%{DOCUMENT_ROOT}';



        // write rule to rewrite to .html file

        $ext = '.html';

        $rules .= $use_cache_rules;

        $rules .= "    RewriteCond \"" . $document_root . $uri_prefix . $ext .

            $env_W3TC_ENC . "\"" . $switch . "\n";

        $rules .= "    RewriteRule .* \"" . $uri_prefix . $ext .

            $env_W3TC_ENC . "\" [L]\n";



        $rules .= "</IfModule>\n";



        $rules .= W3TC_MARKER_END_PGCACHE_CORE . "\n";



        return $rules;

    }



    /**

     * Generates rules for WP dir

     *

     * @return string

     */

    function generate_rules_core_nginx() {

        $is_network = w3_is_network();



        $base_path = w3_get_base_path();

        $cache_dir = w3_path(W3TC_CACHE_PAGE_ENHANCED_DIR);

        $permalink_structure = get_option('permalink_structure');



        /**

         * Auto reject cookies

         */

        $reject_cookies = array(

            'comment_author',

            'wp-postpass'

        );



        if ($this->_config->get_string('pgcache.engine') == 'file_generic') {

            $reject_cookies[] = 'w3tc_logged_out';

        }



        /**

         * Reject cache for logged in users

         * OR

         * Reject cache for roles if any

         */

        if ($this->_config->get_boolean('pgcache.reject.logged')) {

            $reject_cookies = array_merge($reject_cookies, array(

                'wordpress_logged_in'

            ));

        } elseif ($this->_config->get_boolean('pgcache.reject.logged_roles')) {

            $new_cookies = array();

            foreach( $this->_config->get_array('pgcache.reject.roles') as $role ) {

                $new_cookies[] = 'w3tc_logged_' . md5(NONCE_KEY . $role);

            }

            $reject_cookies = array_merge($reject_cookies, $new_cookies);

        }



        /**

         * Custom config

         */

        $reject_cookies = array_merge($reject_cookies, $this->_config->get_array('pgcache.reject.cookie'));

        w3_array_trim($reject_cookies);

        

        $reject_user_agents = $this->_config->get_array('pgcache.reject.ua');

        if ($this->_config->get_boolean('pgcache.compatibility')) {

            $reject_user_agents = array_merge(array(W3TC_POWERED_BY), $reject_user_agents);

        }

        w3_array_trim($reject_user_agents);



        /**

         * Generate rules

         */

        $env_w3tc_ua = '';

        $env_w3tc_ref = '';

        $env_w3tc_ssl = '';

        $env_w3tc_ext = '';

        $env_w3tc_enc = '';



        $rules = '';

        $rules .= W3TC_MARKER_BEGIN_PGCACHE_CORE . "\n";

        if ($this->_config->get_boolean('pgcache.debug')) {

            $rules .= "rewrite ^(.*\\/)?w3tc_rewrite_test$ $1?w3tc_rewrite_test=1 last;\n";

        }



        /**

         * Check for mobile redirect

         */

        if ($this->_config->get_boolean('mobile.enabled')) {

            $mobile_groups = $this->_config->get_array('mobile.rgroups');



            foreach ($mobile_groups as $mobile_group => $mobile_config) {

                $mobile_enabled = (isset($mobile_config['enabled']) ? (boolean) $mobile_config['enabled'] : false);

                $mobile_agents = (isset($mobile_config['agents']) ? (array) $mobile_config['agents'] : '');

                $mobile_redirect = (isset($mobile_config['redirect']) ? $mobile_config['redirect'] : '');



                if ($mobile_enabled && count($mobile_agents) && $mobile_redirect) {

                    $rules .= "if (\$http_user_agent ~* \"(" . implode('|', $mobile_agents) . ")\") {\n";

                    $rules .= "    rewrite .* " . $mobile_redirect . " last;\n";

                    $rules .= "}\n";

                }

            }

        }



        /**

         * Check for referrer redirect

         */

        if ($this->_config->get_boolean('referrer.enabled')) {

            $referrer_groups = $this->_config->get_array('referrer.rgroups');



            foreach ($referrer_groups as $referrer_group => $referrer_config) {

                $referrer_enabled = (isset($referrer_config['enabled']) ? (boolean) $referrer_config['enabled'] : false);

                $referrer_referrers = (isset($referrer_config['referrers']) ? (array) $referrer_config['referrers'] : '');

                $referrer_redirect = (isset($referrer_config['redirect']) ? $referrer_config['redirect'] : '');



                if ($referrer_enabled && count($referrer_referrers) && $referrer_redirect) {

                    $rules .= "if (\$http_cookie ~* \"w3tc_referrer=.*(" . implode('|', $referrer_referrers) . ")\") {\n";

                    $rules .= "    rewrite .* " . $referrer_redirect . " last;\n";

                    $rules .= "}\n";

                }

            }

        }



        /**

         * Don't accept POSTs

         */

        $rules .= "set \$w3tc_rewrite 1;\n";

        $rules .= "if (\$request_method = POST) {\n";

        $rules .= "    set \$w3tc_rewrite 0;\n";

        $rules .= "}\n";



        /**

         * Query string should be empty

         */

        $rules .= "if (\$query_string != \"\") {\n";

        $rules .= "    set \$w3tc_rewrite 0;\n";

        $rules .= "}\n";



        /**

         * Check permalink structure trailing slash

         */

        if (substr($permalink_structure, -1) == '/') {

            $rules .= "if (\$request_uri !~ \\/$) {\n";

            $rules .= "    set \$w3tc_rewrite 0;\n";

            $rules .= "}\n";

        }



        /**

         * Check for rejected cookies

         */

        $rules .= "if (\$http_cookie ~* \"(" . implode('|', array_map('w3_preg_quote', $reject_cookies)) . ")\") {\n";

        $rules .= "    set \$w3tc_rewrite 0;\n";

        $rules .= "}\n";



        /**

         * Check for rejected user agents

         */

        if (count($reject_user_agents)) {

            $rules .= "if (\$http_user_agent ~* \"(" . implode('|', array_map('w3_preg_quote', $reject_user_agents)) . ")\") {\n";

            $rules .= "    set \$w3tc_rewrite 0;\n";

            $rules .= "}\n";

        }



        /**

         * Check mobile groups

         */

        if ($this->_config->get_boolean('mobile.enabled')) {

            $mobile_groups = array_reverse($this->_config->get_array('mobile.rgroups'));



            foreach ($mobile_groups as $mobile_group => $mobile_config) {

                $mobile_enabled = (isset($mobile_config['enabled']) ? (boolean) $mobile_config['enabled'] : false);

                $mobile_agents = (isset($mobile_config['agents']) ? (array) $mobile_config['agents'] : '');

                $mobile_redirect = (isset($mobile_config['redirect']) ? $mobile_config['redirect'] : '');



                if ($mobile_enabled && count($mobile_agents) && !$mobile_redirect) {

                    $rules .= "set \$w3tc_ua \"\";\n";



                    $rules .= "if (\$http_user_agent ~* \"(" . implode('|', $mobile_agents) . ")\") {\n";

                    $rules .= "    set \$w3tc_ua _" . $mobile_group . ";\n";

                    $rules .= "}\n";



                    $env_w3tc_ua = "\$w3tc_ua";

                }

            }

        }



        /**

         * Check referrer groups

         */

        if ($this->_config->get_boolean('referrer.enabled')) {

            $referrer_groups = array_reverse($this->_config->get_array('referrer.rgroups'));



            foreach ($referrer_groups as $referrer_group => $referrer_config) {

                $referrer_enabled = (isset($referrer_config['enabled']) ? (boolean) $referrer_config['enabled'] : false);

                $referrer_referrers = (isset($referrer_config['referrers']) ? (array) $referrer_config['referrers'] : '');

                $referrer_redirect = (isset($referrer_config['redirect']) ? $referrer_config['redirect'] : '');



                if ($referrer_enabled && count($referrer_referrers) && !$referrer_redirect) {

                    $rules .= "set \$w3tc_ref \"\";\n";



                    $rules .= "if (\$http_cookie ~* \"w3tc_referrer=.*(" . implode('|', $referrer_referrers) . ")\") {\n";

                    $rules .= "    set \$w3tc_ref _" . $referrer_group . ";\n";

                    $rules .= "}\n";



                    $env_w3tc_ref = "\$w3tc_ref";

                }

            }

        }



        if ($this->_config->get_boolean('pgcache.cache.ssl')) {

            $rules .= "set \$w3tc_ssl \"\";\n";



            $rules .= "if (\$scheme = https) {\n";

            $rules .= "    set \$w3tc_ssl _ssl;\n";

            $rules .= "}\n";



            $env_w3tc_ssl = "\$w3tc_ssl";

        }



        if ($this->_config->get_boolean('browsercache.enabled') && $this->_config->get_boolean('browsercache.html.compression')) {

            $rules .= "set \$w3tc_enc \"\";\n";



            $rules .= "if (\$http_accept_encoding ~ gzip) {\n";

            $rules .= "    set \$w3tc_enc _gzip;\n";

            $rules .= "}\n";



            $env_w3tc_enc = "\$w3tc_enc";

        }



        $cache_path = str_replace(w3_get_document_root(), '', $cache_dir);

        $uri_prefix = $cache_path . "/\$http_host/" .

            "\$request_uri/_index" . $env_w3tc_ua . $env_w3tc_ref . $env_w3tc_ssl;



        if (!$this->_config->get_boolean('pgcache.cache.nginx_handle_xml')) {

            $env_w3tc_ext = '.html';



            $rules .= "if (-f \"\$document_root" . $uri_prefix . ".html" .

                $env_w3tc_enc . "\") {\n";

            $rules .= "  set \$w3tc_rewrite 0;\n";

            $rules .= "}\n";

        } else {

            $env_w3tc_ext = "\$w3tc_ext";



            $rules .= "set \$w3tc_ext \"\";\n";

            $rules .= "if (-f \"\$document_root" . $uri_prefix . ".html" .

                $env_w3tc_enc . "\") {\n";

            $rules .= "    set \$w3tc_ext .html;\n";

            $rules .= "}\n";



            $rules .= "if (-f \"\$document_root" . $uri_prefix . ".xml" .

                $env_w3tc_enc . "\") {\n";

            $rules .= "    set \$w3tc_ext .xml;\n";

            $rules .= "}\n";



            $rules .= "if (\$w3tc_ext = \"\") {\n";

            $rules .= "  set \$w3tc_rewrite 0;\n";

            $rules .= "}\n";

        }



        $rules .= "if (\$w3tc_rewrite = 1) {\n";

        $rules .= "    rewrite .* \"" . $uri_prefix . $env_w3tc_ext . $env_w3tc_enc . "\" last;\n";

        $rules .= "}\n";

        $rules .= W3TC_MARKER_END_PGCACHE_CORE . "\n";



        return $rules;

    }



    /**

     * Generates directives for file cache dir

     *

     * @return string

     */

    function generate_rules_cache_apache() {

        $charset = get_option('blog_charset');

        $pingback_url = get_bloginfo('pingback_url');



        $browsercache = $this->_config->get_boolean('browsercache.enabled');

        $compression = ($browsercache && $this->_config->get_boolean('browsercache.html.compression'));

        $expires = ($browsercache && $this->_config->get_boolean('browsercache.html.expires'));

        $lifetime = ($browsercache ? $this->_config->get_integer('browsercache.html.lifetime') : 0);

        $cache_control = ($browsercache && $this->_config->get_boolean('browsercache.html.cache.control'));

        $etag = ($browsercache && $this->_config->get_integer('browsercache.html.etag'));

        $w3tc = ($browsercache && $this->_config->get_integer('browsercache.html.w3tc'));

        $compatibility = $this->_config->get_boolean('pgcache.compatibility');



        $rules = '';

        $rules .= W3TC_MARKER_BEGIN_PGCACHE_CACHE . "\n";

        if ($compatibility) {

            $rules .= "Options -MultiViews\n";



            // allow to read files by apache if they are blocked at some level above

            $rules .= "<Files ~ \"\.(html|html_gzip|xml|xml_gzip)$\">\n";

            $rules .= "  Allow from all\n";

            $rules .= "</Files>\n";



            if (!$etag) {

                $rules .= "FileETag None\n";

            }



            $rules .= "AddDefaultCharset " . ($charset ? $charset : 'UTF-8') . "\n";

        }



        if ($etag) {

            $rules .= "FileETag MTime Size\n";

        }



        if ($compression) {

            $rules .= "<IfModule mod_mime.c>\n";

            $rules .= "    AddType text/html .html_gzip\n";

            $rules .= "    AddEncoding gzip .html_gzip\n";

            $rules .= "    AddType text/xml .xml_gzip\n";

            $rules .= "    AddEncoding gzip .xml_gzip\n";

            $rules .= "</IfModule>\n";

            $rules .= "<IfModule mod_deflate.c>\n";

            $rules .= "    SetEnvIfNoCase Request_URI \\.html_gzip$ no-gzip\n";

            $rules .= "    SetEnvIfNoCase Request_URI \\.xml_gzip$ no-gzip\n";

            $rules .= "</IfModule>\n";

        }



        if ($expires) {

            $rules .= "<IfModule mod_expires.c>\n";

            $rules .= "    ExpiresActive On\n";

            $rules .= "    ExpiresByType text/html M" . $lifetime . "\n";

            $rules .= "</IfModule>\n";

        }



        $header_rules = '';



        if ($compatibility) {

            $header_rules .= "    Header set X-Pingback \"" . $pingback_url . "\"\n";

        }



        if ($w3tc) {

            $header_rules .= "    Header set X-Powered-By \"" . W3TC_POWERED_BY . "\"\n";

        }



        if ($compression) {

            $header_rules .= "    Header set Vary \"Accept-Encoding, Cookie\"\n";

        } else {

            if ($compatibility) {

                $header_rules .= "    Header set Vary \"Cookie\"\n";

            }

        }





        $set_last_modified = $this->_config->get_boolean('browsercache.html.last_modified');



        if (!$set_last_modified && $this->_config->get_boolean('browsercache.enabled')) {

            $header_rules .= "    Header unset Last-Modified\n";

        }



        if ($cache_control) {

            $cache_policy = $this->_config->get_string('browsercache.html.cache.policy');



            switch ($cache_policy) {

                case 'cache':

                    $header_rules .= "    Header set Pragma \"public\"\n";

                    $header_rules .= "    Header set Cache-Control \"public\"\n";

                    break;



                case 'cache_public_maxage':

                    $header_rules .= "    Header set Pragma \"public\"\n";



                    if ($expires) {

                        $header_rules .= "    Header append Cache-Control \"public\"\n";

                    } else {

                        $header_rules .= "    Header set Cache-Control \"max-age=" . $lifetime . ", public\"\n";

                    }

                    break;



                case 'cache_validation':

                    $header_rules .= "    Header set Pragma \"public\"\n";

                    $header_rules .= "    Header set Cache-Control \"public, must-revalidate, proxy-revalidate\"\n";

                    break;



                case 'cache_noproxy':

                    $header_rules .= "    Header set Pragma \"public\"\n";

                    $header_rules .= "    Header set Cache-Control \"public, must-revalidate\"\n";

                    break;



                case 'cache_maxage':

                    $header_rules .= "    Header set Pragma \"public\"\n";



                    if ($expires) {

                        $header_rules .= "    Header append Cache-Control \"public, must-revalidate, proxy-revalidate\"\n";

                    } else {

                        $header_rules .= "    Header set Cache-Control \"max-age=" . $lifetime . ", public, must-revalidate, proxy-revalidate\"\n";

                    }

                    break;



                case 'no_cache':

                    $header_rules .= "    Header set Pragma \"no-cache\"\n";

                    $header_rules .= "    Header set Cache-Control \"max-age=0, private, no-store, no-cache, must-revalidate\"\n";

                    break;

            }

        }



        if (strlen($header_rules) > 0) {

            $rules .= "<IfModule mod_headers.c>\n";

            $rules .= $header_rules;

            $rules .= "</IfModule>\n";

        }



        $rules .= W3TC_MARKER_END_PGCACHE_CACHE . "\n";



        return $rules;

    }



    /**

     * Generates directives for file cache dir

     *

     * @return string

     */

    function generate_rules_cache_nginx() {

        $cache_root = w3_path(W3TC_CACHE_PAGE_ENHANCED_DIR);

        $cache_dir = rtrim(str_replace(w3_get_document_root(), '', $cache_root), '/');



        if (w3_is_network()) {

            $cache_dir = preg_replace('~/w3tc.*?/~', '/w3tc.*?/', $cache_dir, 1);

        }



        $browsercache = $this->_config->get_boolean('browsercache.enabled');

        $compression = ($browsercache && $this->_config->get_boolean('browsercache.html.compression'));

        $expires = ($browsercache && $this->_config->get_boolean('browsercache.html.expires'));

        $lifetime = ($browsercache ? $this->_config->get_integer('browsercache.html.lifetime') : 0);

        $cache_control = ($browsercache && $this->_config->get_boolean('browsercache.html.cache.control'));

        $w3tc = ($browsercache && $this->_config->get_integer('browsercache.html.w3tc'));



        $common_rules = '';



        if ($expires) {

            $common_rules .= "    expires modified " . $lifetime . "s;\n";

        }



        if ($w3tc) {

            $common_rules .= "    add_header X-Powered-By \"" . W3TC_POWERED_BY . "\";\n";

        }



        if ($compression) {

            $common_rules .= "    add_header Vary \"Accept-Encoding, Cookie\";\n";

        } else {

            $common_rules .= "    add_header Vary Cookie;\n";

        }



        if ($cache_control) {

            $cache_policy = $this->_config->get_string('browsercache.html.cache.policy');



            switch ($cache_policy) {

                case 'cache':

                    $common_rules .= "    add_header Pragma \"public\";\n";

                    $common_rules .= "    add_header Cache-Control \"public\";\n";

                    break;



                case 'cache_public_maxage':

                    $common_rules .= "    add_header Pragma \"public\";\n";

                    $common_rules .= "    add_header Cache-Control \"max-age=" . $lifetime . ", public\";\n";

                    break;



                case 'cache_validation':

                    $common_rules .= "    add_header Pragma \"public\";\n";

                    $common_rules .= "    add_header Cache-Control \"public, must-revalidate, proxy-revalidate\";\n";

                    break;



                case 'cache_noproxy':

                    $common_rules .= "    add_header Pragma \"public\";\n";

                    $common_rules .= "    add_header Cache-Control \"public, must-revalidate\";\n";

                    break;



                case 'cache_maxage':

                    $common_rules .= "    add_header Pragma \"public\";\n";

                    $common_rules .= "    add_header Cache-Control \"max-age=" . $lifetime . ", public, must-revalidate, proxy-revalidate\";\n";

                    break;



                case 'no_cache':

                    $common_rules .= "    add_header Pragma \"no-cache\";\n";

                    $common_rules .= "    add_header Cache-Control \"max-age=0, private, no-store, no-cache, must-revalidate\";\n";

                    break;

            }

        }



        $rules = '';

        $rules .= W3TC_MARKER_BEGIN_PGCACHE_CACHE . "\n";



        $rules .= "location ~ " . $cache_dir . ".*html$ {\n";

        $rules .= $common_rules;

        $rules .= "}\n";



        if ($compression) {

            $rules .= "location ~ " . $cache_dir . ".*gzip$ {\n";

            $rules .= "    gzip off;\n";

            $rules .= "    types {}\n";

            $rules .= "    default_type text/html;\n";

            $rules .= $common_rules;

            $rules .= "    add_header Content-Encoding gzip;\n";

            $rules .= "}\n";

        }



        $rules .= W3TC_MARKER_END_PGCACHE_CACHE . "\n";



        return $rules;

    }



    /**

     * Writes directives to WP .htaccess

     *

     * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials

     * @throws FileOperationException

     */

    function write_rules_core() {

        $path = w3_get_pgcache_rules_core_path();



        if (file_exists($path)) {

            $data = @file_get_contents($path);



            if ($data !== false) {

                $data = $this->erase_rules_legacy($data);

                $data = $this->erase_rules_wpsc($data);

            } else {

                return false;

            }

        } else {

            $data = '';

        }



        $replace_start = strpos($data, W3TC_MARKER_BEGIN_PGCACHE_CORE);

        $replace_end = strpos($data, W3TC_MARKER_END_PGCACHE_CORE);



        if ($replace_start !== false && $replace_end !== false && $replace_start < $replace_end) {

            $replace_length = $replace_end - $replace_start + strlen(W3TC_MARKER_END_PGCACHE_CORE) + 1;

        } else {

            $replace_start = false;

            $replace_length = 0;



            $search = array(

                W3TC_MARKER_BEGIN_BROWSERCACHE_NO404WP => 0,

                W3TC_MARKER_BEGIN_WORDPRESS => 0,

                W3TC_MARKER_END_MINIFY_CORE => strlen(W3TC_MARKER_END_MINIFY_CORE) + 1,

                W3TC_MARKER_END_BROWSERCACHE_CACHE => strlen(W3TC_MARKER_END_BROWSERCACHE_CACHE) + 1,

                W3TC_MARKER_END_PGCACHE_CACHE => strlen(W3TC_MARKER_END_PGCACHE_CACHE) + 1,

                W3TC_MARKER_END_MINIFY_CACHE => strlen(W3TC_MARKER_END_MINIFY_CACHE) + 1

            );



            foreach ($search as $string => $length) {

                $replace_start = strpos($data, $string);



                if ($replace_start !== false) {

                    $replace_start += $length;

                    break;

                }

            }

        }



        $rules = $this->generate_rules_core();



        if ($replace_start !== false) {

            $data = w3_trim_rules(substr_replace($data, $rules, $replace_start, $replace_length));

        } else {

            $data = w3_trim_rules($data . $rules);

        }



        w3_require_once(W3TC_INC_DIR . '/functions/activation.php');

        w3_wp_write_to_file($path, $data);

    }



    /**

     * Writes directives to file cache .htaccess

     * Throws exception on error

     */

    function write_rules_cache($use_fs = false) {

        w3_require_once(W3TC_INC_DIR . '/functions/activation.php');



        $path = w3_get_pgcache_rules_cache_path();



        if (file_exists($path)) {

            $data = @file_get_contents($path);



            if ($data === false) {

                w3_throw_on_read_error($path);

            }

        } else {

            $data = '';

        }



        $replace_start = strpos($data, W3TC_MARKER_BEGIN_PGCACHE_CACHE);

        $replace_end = strpos($data, W3TC_MARKER_END_PGCACHE_CACHE);



        if ($replace_start !== false && $replace_end !== false && $replace_start < $replace_end) {

            $replace_length = $replace_end - $replace_start + strlen(W3TC_MARKER_END_PGCACHE_CACHE) + 1;

        } else {

            $replace_start = false;

            $replace_length = 0;



            $search = array(

                W3TC_MARKER_BEGIN_BROWSERCACHE_CACHE => 0,

                W3TC_MARKER_BEGIN_MINIFY_CORE => 0,

                W3TC_MARKER_BEGIN_PGCACHE_CORE => 0,

                W3TC_MARKER_BEGIN_BROWSERCACHE_NO404WP => 0,

                W3TC_MARKER_BEGIN_WORDPRESS => 0,

                W3TC_MARKER_END_MINIFY_CACHE => strlen(W3TC_MARKER_END_MINIFY_CACHE) + 1

            );



            foreach ($search as $string => $length) {

                $replace_start = strpos($data, $string);



                if ($replace_start !== false) {

                    $replace_start += $length;

                    break;

                }

            }

        }



        $rules = $this->generate_rules_cache();



        if ($replace_start !== false) {

            $data = w3_trim_rules(substr_replace($data, $rules, $replace_start, $replace_length));

        } else {

            $data = w3_trim_rules($data . $rules);

        }



        if (!@file_exists(dirname($path))) {

            w3_mkdir_from(dirname($path), W3TC_CACHE_DIR);

        }



        if ($use_fs) {

            w3_wp_write_to_file($path, $data);

        } else {

            if (!@file_put_contents($path, $data)) {

                w3_throw_on_write_error($path);

            }

        }

    }



    /**

     * Erases Page Cache core directives

     *

     * @param string $data

     * @return string

     */

    function erase_rules_core($data) {

        $data = w3_erase_rules($data, W3TC_MARKER_BEGIN_PGCACHE_CORE, W3TC_MARKER_END_PGCACHE_CORE);



        return $data;

    }



    /**

     * Erases Page Cache cache directives

     *

     * @param string $data

     * @return string

     */

    function erase_rules_cache($data) {

        $data = w3_erase_rules($data, W3TC_MARKER_BEGIN_PGCACHE_CACHE, W3TC_MARKER_END_PGCACHE_CACHE);



        return $data;

    }



    /**

     * Erases Page Cache legacy directives

     *

     * @param string $data

     * @return string

     */

    function erase_rules_legacy($data) {

        $data = w3_erase_rules($data, W3TC_MARKER_BEGIN_PGCACHE_LEGACY, W3TC_MARKER_END_PGCACHE_LEGACY);



        return $data;

    }



    /**

     * Erases WP Super Cache rules directives

     *

     * @param string $data

     * @return string

     */

    function erase_rules_wpsc($data) {

        $data = w3_erase_rules($data, W3TC_MARKER_BEGIN_PGCACHE_WPSC, W3TC_MARKER_END_PGCACHE_WPSC);



        return $data;

    }



    /**

     * Removes Page Cache core directives

     *

     * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials

     * @throws FileOperationException

     */

    function remove_rules_core() {

        $path = w3_get_pgcache_rules_core_path();



        if (file_exists($path)) {

            if (($data = @file_get_contents($path)) !== false) {

                $data = $this->erase_rules_core($data);



                w3_require_once(W3TC_INC_DIR . '/functions/activation.php');

                w3_wp_write_to_file($path, $data);

            }

        }

    }



    /**

     * Removes Page Cache cache directives

     *

     * @return boolean

     */

    function remove_rules_cache() {

        $path = w3_get_pgcache_rules_cache_path();



        if (file_exists($path)) {

            if (($data = @file_get_contents($path)) !== false) {

                $data = $this->erase_rules_cache($data);



                return @file_put_contents($path, $data);

            }



            return false;

        }



        return true;

    }



    /**

     * Removes Page Cache legacy directives

     *

     * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials

     * @throws FileOperationException

     */

    function remove_rules_legacy() {

        $path = w3_get_pgcache_rules_core_path();



        if (file_exists($path)) {

            if (($data = @file_get_contents($path)) !== false) {

                $data = $this->erase_rules_legacy($data);



                w3_require_once(W3TC_INC_DIR . '/functions/activation.php');

                w3_wp_write_to_file($path, $data);

            }

        }

    }



    /**

     * Removes WPSC directives

     *

     * @return boolean

     */

    function remove_rules_wpsc() {

        $path = w3_get_pgcache_rules_core_path();



        if (file_exists($path)) {

            if (($data = @file_get_contents($path)) !== false) {

                $data = $this->erase_rules_wpsc($data);



                return @file_put_contents($path, $data);

            }



            return false;

        }



        return true;

    }



    /**

     * Check if legacy rules exists

     *

     * @return boolean

     */

    function check_rules_has_legacy() {

        $path = w3_get_pgcache_rules_core_path();



        return (($data = @file_get_contents($path)) && w3_has_rules(w3_clean_rules($data), W3TC_MARKER_BEGIN_PGCACHE_LEGACY, W3TC_MARKER_END_PGCACHE_LEGACY));

    }



    /**

     * Check if legacy rules exists

     *

     * @return boolean

     */

    function check_rules_has_core() {

        $path = w3_get_pgcache_rules_core_path();



        return (($data = @file_get_contents($path)) && w3_has_rules(w3_clean_rules($data), W3TC_MARKER_BEGIN_PGCACHE_CORE, W3TC_MARKER_END_PGCACHE_CORE));

    }



    /**

     * Checks if core rules exists

     *

     * @return boolean

     */

    function check_rules_core() {

        $path = w3_get_pgcache_rules_core_path();

        $search = $this->generate_rules_core();



        return (($data = @file_get_contents($path)) && strstr(w3_clean_rules($data), w3_clean_rules($search)) !== false);

    }



    /**

     * Checks if cache rules exists

     *

     * @return boolean

     */

    function check_rules_cache() {

        $path = w3_get_pgcache_rules_cache_path();

        $search = $this->generate_rules_cache();



        return (($data = @file_get_contents($path)) && strstr(w3_clean_rules($data), w3_clean_rules($search)) !== false);

    }



    /**

     * Check if WPSC rules exists

     *

     * @return boolean

     */

    function check_rules_wpsc() {

        $path = w3_get_pgcache_rules_core_path();



        return (($data = @file_get_contents($path)) && w3_has_rules(w3_clean_rules($data), W3TC_MARKER_BEGIN_PGCACHE_WPSC, W3TC_MARKER_END_PGCACHE_WPSC));

    }



    /**

     * Returns required rules for module

     * @return array

     */

    function get_required_rules() {

        $rewrite_rules = array();

        if ($this->_config->get_boolean('pgcache.enabled') && $this->_config->get_string('pgcache.engine') == 'file_generic') {

            $pgcache_rules_cache_path = w3_get_pgcache_rules_cache_path();

            $rewrite_rules[] = array('filename' => $pgcache_rules_cache_path, 'content' => $this->generate_rules_cache());

            $pgcache_rules_core_path = w3_get_pgcache_rules_core_path();

            $rewrite_rules[] = array('filename' => $pgcache_rules_core_path, 'content' => $this->generate_rules_core());

        }

        return $rewrite_rules;

    }



    /**

     * @return array

     */

    function disable_wp_cache_with_message() {

        $ftp_form = null;

        $errors = array();

        $errors_short_form = array();



        try {

            $this->disable_wp_cache();

        } catch(Exception $e) {

            $errors[] = sprintf('To disable Page Cache remove <strong>define(\'WP_CACHE\', true);</strong>, edit the configuration file (<strong>%s</strong>)', w3_get_wp_config_path());

            $errors_short_form[] = sprintf('Edit file (<strong>%s</strong>) and remove <strong>define(\'WP_CACHE\', true);</strong>', w3_get_wp_config_path());

            if ($e instanceof FilesystemCredentialException)

                $ftp_form = $e->ftp_form();

        }

        return array('errors' => $errors, 'ftp_form' => $ftp_form, 'errors_short_form' => $errors_short_form);

    }



    /**

     * @param bool $check_engine if pgcache should be taken into account when removing

     * @return array

     */

    function remove_rules_core_with_message($check_engine = false) {

        $ftp_form = null;

        $errors = array();

        $errors_short_form = array();



        $engine_remove = $check_engine ?

                                $this->_config->get_string('pgcache.engine') != 'file_generic' ||

                                !$this->_config->get_boolean('pgcache.enabled') :

                                true;

        if ($engine_remove) {

            if ($this->check_rules_has_core()) {

                try {

                    $this->remove_rules_core();

                } catch(Exception $e) {

                    $errors[] = sprintf('To disable Page Cache Disc: Enhanced rules need to be removed. To remove them manually, edit the configuration file (<strong>%s</strong>) and remove all lines between and including <strong>%s</strong> and <strong>%s</strong> markers inclusive.'

                        , w3_get_pgcache_rules_core_path(),

                        W3TC_MARKER_BEGIN_PGCACHE_CORE, W3TC_MARKER_END_PGCACHE_CORE);

                    $errors_short_form[] = sprintf('Edit file (<strong>%s</strong>) and remove all lines between and including <strong>%s</strong> and <strong>%s</strong> markers inclusive.'

                        , w3_get_pgcache_rules_core_path(),

                        W3TC_MARKER_BEGIN_PGCACHE_CORE, W3TC_MARKER_END_PGCACHE_CORE);

                    if (!isset($ftp_form) && $e instanceof FilesystemCredentialException)

                        $ftp_form = $e->ftp_form();

                }

            }

        }

        return array('errors' => $errors, 'ftp_form' => $ftp_form, 'errors_short_form' => $errors_short_form);

    }



    /**

     * @return array

     */

    function remove_rules_cache_multisite_nginx_with_message() {

        $ftp_form = null;

        $errors = array();

        $errors_short_form = array();



        if (w3_is_multisite() && w3_is_nginx() && $this->check_rules_cache()) {

            try {

                $this->remove_rules_cache();

            } catch(Exception $e) {

                $errors[] = sprintf('To fully disable Page Cache Disc: Enhanced for Network Sites rules need to be removed. To remove them manually, edit the configuration file (<strong>%s</strong>) and remove all lines between and including <strong>%s</strong> and <strong>%s</strong> markers inclusive.'

                    , w3_get_pgcache_rules_core_path(),

                    W3TC_MARKER_BEGIN_PGCACHE_CACHE, W3TC_MARKER_END_PGCACHE_CACHE);

                $errors_short_form[] = sprintf('Edit file (<strong>%s</strong>) and remove all lines between and including <strong>%s</strong> and <strong>%s</strong> markers inclusive.'

                    , w3_get_pgcache_rules_core_path(),

                    W3TC_MARKER_BEGIN_PGCACHE_CACHE, W3TC_MARKER_END_PGCACHE_CACHE);



                if (!isset($ftp_form) && $e instanceof FilesystemCredentialException)

                    $ftp_form = $e->ftp_form();

            }

        }

        return array('errors' => $errors, 'ftp_form' => $ftp_form, 'errors_short_form' => $errors_short_form);

    }

}