object_cache_file_content( $backend ); if ( ! file_put_contents( $file, $file_string, LOCK_EX ) ) { return false; } return true; } /** * object-cache.php contents * * @param string $backend Persistent object cache backend * * @return mixed|void * @since 1.0 * @see Powered_Cache_Admin_Helper::object_cache_dropins * * @since 1.1 supports `POWERED_CACHE_OBJECT_CACHE_DROPIN` */ public function object_cache_file_content( $backend ) { $string = 'generate_advanced_cache_file(); $this->define_wp_cache( $status ); if ( can_configure_htaccess() ) { $this->configure_htaccess( $status ); } $this->protect_cache_dir(); return true; } /** * Generates advanced-cache.php * * @return bool * @since 1.1 is_multisite control added * @since 1.0 */ public function generate_advanced_cache_file() { $file = untrailingslashit( WP_CONTENT_DIR ) . '/advanced-cache.php'; $settings = \PoweredCache\Utils\get_settings(); $file_string = ''; /** * multisite setups should always have `advanced-cache.php` file */ if ( true === $settings['enable_page_cache'] || is_multisite() ) { $file_string = $this->advanced_cache_file_content(); } if ( ! file_put_contents( $file, $file_string ) ) { return false; } return true; } /** * Prepare advanced-cache.php contents * * @return mixed|void * @since 1.1 supports `POWERED_CACHE_ADVANCED_CACHE_DROPIN` * @since 1.0 */ public function advanced_cache_file_content() { $string = 'find_wp_config_file(); if ( ! $config_path ) { return false; } if ( defined( 'WP_CACHE' ) && WP_CACHE === $status ) { return true; } $config_file_string = file_get_contents( $config_path ); // Config file is empty. Maybe couldn't read it? if ( empty( $config_file_string ) ) { return false; } $config_file = preg_split( "#(\r\n|\r|\n)#", $config_file_string ); $line_key = false; foreach ( $config_file as $key => $line ) { if ( ! preg_match( '/^\s*define\(\s*(\'|")([A-Z_]+)(\'|")(.*)/', $line, $match ) ) { continue; } if ( 'WP_CACHE' === $match[2] ) { $line_key = $key; } } if ( false !== $line_key ) { unset( $config_file[ $line_key ] ); } $status_string = ( $status ) ? 'true' : 'false'; array_shift( $config_file ); array_unshift( $config_file, ' 1 ) { $file = '/..' . $file; } if ( file_exists( untrailingslashit( ABSPATH ) . $file ) ) { $config_path = untrailingslashit( ABSPATH ) . $file; break; } } if ( ! isset( $config_path ) ) { return false; } return $config_path; } /** * Create .htaccess file based on current setting preferences * * @param bool $enable Configure .htaccess automatically when it's true * * @return bool * @since 1.0 */ public function configure_htaccess( $enable = true ) { if ( ! function_exists( '\get_home_path' ) ) { require_once ABSPATH . '/wp-admin/includes/file.php'; } $htaccess_file = get_home_path() . '.htaccess'; $settings = \PoweredCache\Utils\get_settings(); /** * Filters whether automatically update or not update .htaccess file * * @hook powered_cache_auto_htaccess_update * * @param {boolean} true to automatic update. * * @return {boolean} New value. * * @since 1.1.1 */ if ( true !== apply_filters( 'powered_cache_auto_htaccess_update', true ) ) { return false; } /** * Apache users can control automatic configuration * * @since 1.2 */ $automatic_configuration = $settings['auto_configure_htaccess']; if ( is_multisite() && ! POWERED_CACHE_IS_NETWORK ) { $automatic_configuration = false; // individual sites shouldn't use .htaccess on multisite } if ( ! $automatic_configuration ) { return false; } if ( is_writable( $htaccess_file ) ) { $contents = file_get_contents( $htaccess_file ); // clean up $contents = preg_replace( '/# BEGIN POWERED CACHE(.*)# END POWERED CACHE\s*?/isU', '', $contents ); if ( false === $enable ) { return file_put_contents( $htaccess_file, $contents ); } $rules = Htaccess::factory()->htaccess_rules(); $contents = $rules . $contents; // Update the .htacces file if ( ! file_put_contents( $htaccess_file, $contents ) ) { return false; } return true; } return false; } /** * Prepares .htaccess rules for the caching * * @return string $rules * @since 1.1 * @deprecated 2.5.0 Use the {@see '\PoweredCache\Htaccess::factory()->htaccess_rules()'} instead. */ public function htaccess_rules() { $rules = Htaccess::factory()->htaccess_rules(); return $rules; } /** * Make sure directory listing disabled * * @return bool * @since 1.2 */ public function protect_cache_dir() { if ( ! file_exists( get_cache_dir() ) ) { mkdir( get_cache_dir() ); } $file = get_cache_dir() . '.htaccess'; $file_string = '' . PHP_EOL; $file_string .= ' Options -Indexes' . PHP_EOL; $file_string .= '' . PHP_EOL . PHP_EOL; $file_string .= '' . PHP_EOL; $file_string .= ' Order Allow,Deny' . PHP_EOL; $file_string .= ' Deny from all' . PHP_EOL; $file_string .= '' . PHP_EOL; /** * Filters the content of the .htaccess file in the cache directory. * * @param {string} $file_string Default configuration * * @hook powered_cache_cache_dir_htaccess_file_content * @since 3.5.3 */ $file_string = apply_filters( 'powered_cache_cache_dir_htaccess_file_content', $file_string ); if ( ! file_put_contents( $file, $file_string ) ) { return false; } return true; } /** * Prepare config name * * @param bool $is_network Whether network-wide config name or not * * @return string configuration file name * @since 2.0 */ public function get_config_filename( $is_network ) { if ( $is_network ) { return 'config-network.php'; } else { $url_parts = wp_parse_url( home_url() ); $config_name = 'config-' . $url_parts['host']; if ( is_multisite() && ! is_subdomain_install() ) { if ( ! is_main_site( get_current_blog_id() ) && ! empty( $url_parts['path'] ) ) { $subdir_name = ltrim( $url_parts['path'], '/' ); $config_name .= '-' . $subdir_name; } } $config_name .= '.php'; return $config_name; } } /** * Save settings to file * * @param array $configuration plugin settings * @param bool $network_wide Whether network-wide configuration or not * * @return bool * @since 1.0 */ public function save_to_file( $configuration, $network_wide = false ) { $config_dir = WP_CONTENT_DIR . '/pc-config'; $config_file_name = $this->get_config_filename( $network_wide ); if ( ! file_exists( $config_dir ) ) { mkdir( $config_dir ); } $config_file = trailingslashit( $config_dir ) . $config_file_name; if ( ! file_exists( $config_file ) ) { touch( $config_file ); } $configuration['cache_location'] = get_cache_dir(); $config_file_string = 'htaccess_rules(); $filename = '.htaccess_powered_cache'; } if ( 'nginx' === $server ) { $rules = $this->nginx_rules(); $filename = 'poweredcache.conf'; } nocache_headers(); @header( 'Content-Type: text/plain' ); @header( 'Content-Disposition: attachment; filename="' . $filename . '"' ); @header( 'Content-Transfer-Encoding: binary' ); @header( 'Content-Length: ' . strlen( $rules ) ); @header( 'Connection: close' ); echo $rules; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped exit; } /** * Make the caching configurations with given options * * @param array $settings Plugin settings * @param bool $network_wide Whether network-wide configuration or not * * @since 2.0 */ public function save_configuration( $settings, $network_wide = false ) { if ( can_configure_object_cache() ) { if ( ! empty( $settings['dev_mode'] ) ) { $this->setup_object_cache(); // dev mode, no object cache } else { $this->setup_object_cache( $settings['object_cache'] ); } } $this->setup_page_cache( $settings['enable_page_cache'] ); $private_settings = [ 'cloudflare_email', 'cloudflare_api_key', 'cloudflare_api_token', 'cloudflare_zone' ]; foreach ( $private_settings as $setting_key ) { unset( $settings[ $setting_key ] ); } $this->save_to_file( $settings, $network_wide ); } /** * Clean-up all the configurations and cache related footprints */ public function clean_up() { $object_cache_dropin = untrailingslashit( WP_CONTENT_DIR ) . '/object-cache.php'; if ( file_exists( $object_cache_dropin ) && false !== strpos( file_get_contents( $object_cache_dropin ), 'POWERED_OBJECT_CACHE' ) ) { unlink( $object_cache_dropin ); } $advanced_cache_dropin = untrailingslashit( WP_CONTENT_DIR ) . '/advanced-cache.php'; if ( file_exists( $advanced_cache_dropin ) ) { unlink( $advanced_cache_dropin ); } $this->define_wp_cache( false ); $this->configure_htaccess( false ); $this->protect_cache_dir(); if ( ! file_exists( get_cache_dir() ) ) { remove_dir( get_cache_dir() ); } $config_dir = WP_CONTENT_DIR . '/pc-config'; if ( is_multisite() ) { $config_file_name = $this->get_config_filename( POWERED_CACHE_IS_NETWORK ); $config_file = trailingslashit( $config_dir ) . $config_file_name; if ( file_exists( $config_file ) ) { unlink( $config_file ); } } else { // remove entire configuration directory on single site setup remove_dir( $config_dir ); } /** * Fires after cleanup all configurations * * @hook powered_cache_after_clean_up * * @since 2.0 */ do_action( 'powered_cache_after_clean_up' ); } }