P?36 Bp B 'B'BP B'BXBBpB'B = .!B'BB9"BBe(BB9"B8e(Bh&BB9"BB9"BB9"BB9"B  Ad$%Bx&B`@u9"BB9"B(i(BXB9"B+=B B0&B&Bp`B(B0(BBB^!B q+&0U=к(BBA !B(BXB(Bػ(B(B !B B(B(B Aػ(BX(B(B(B(BX(B"B !BMR=BBBBXB(B(B B (B(B !B B9&i'B&Bi'BBQXB(Bo'B)Bhw'B)B(B)Bx!B@)B/3@)BhP'Bx)B)B02C-.%Bh!B%B0&B`x)B Bo'B Bhw'B B(B Bx!B B@)B BPl'B B(D"B Bx)B BpNQ (D"B B(D"B Bh(B&)BB`')B0S'B%BT A7)B B uP CP9)B9)B @+k!B;)BX7)B(@)B ()QSAt !8BS)B]!BR)BdBR)BBO!B\)BH\)Bf)B(@)B8'B(@)B8'B@B8'B)BX7)BD)BXi)B)BX7)BO!B`!BP!BB!B`B"Bp`dB)B ` S)B0)BP B8 !BBBBB`oU oU'B)B! q%X(!BB-x)BH?B)BH?B%*B(B !B`!B&$&%)B B    *B>)B8*B>)BP"!B`*B ?5B*B 3&B!Bhw'B()B.@B8!B 0,.*B(*BpBX)&B B*B @&Bx*B@&BpIBtpB`K!BpB0+B pB+B !BB B@%+B B@%+B338!B@_!BH?B7+B:+Bf'B*Bx%B:+B(D"BB&B i'BB3XBB XB(B !B@%+B Bj+B Bj+B Bj+B`j+B; Bj+Bxn+Bj+B; B%B &B    @ '/path-to/home1/wp-content/cache/wp-rocket/example.com/home1/deleted-page', * '/path-to/home1/wp-content/cache/wp-rocket/example.com/home1/very-dead-page', * ], * ], * [ * 'home_url' => 'http://example.com/home1', * 'home_path' => '/path-to/home1/wp-content/cache/wp-rocket/example.com-Greg-594d03f6ae698691165999/home1', * 'logged_in' => true, * 'files' => [ * '/path-to/home1/wp-content/cache/wp-rocket/example.com-Greg-594d03f6ae698691165999/home1/how-to-prank-your-coworkers', * '/path-to/home1/wp-content/cache/wp-rocket/example.com-Greg-594d03f6ae698691165999/home1/best-source-of-gifs', * ], * ], * ] * @param array $args { * @type string $url The home url. * @type int $lifespan Files lifespan in seconds. * @type int $file_age_limit Timestamp of the maximum age files must have. This is basically `time() - $lifespan`. * } */ do_action( 'rocket_after_automatic_cache_purge_dir', $url_deleted, $args ); } $args = [ 'lifespan' => $lifespan, 'file_age_limit' => $file_age_limit, ]; /** * Fires after cache directories are purged. * * @since 3.4 * * @param array $deleted { * An array of arrays, described like: { * @type string $home_url The home URL. * @type string $home_path Path to home. * @type bool $logged_in True if the home path corresponds to a logged in user’s folder. * @type array $files A list of paths of files that have been deleted. * } * Ex: * [ * [ * 'home_url' => 'http://example.com/home1', * 'home_path' => '/path-to/home1/wp-content/cache/wp-rocket/example.com/home1', * 'logged_in' => false, * 'files' => [ * '/path-to/home1/wp-content/cache/wp-rocket/example.com/home1/deleted-page', * '/path-to/home1/wp-content/cache/wp-rocket/example.com/home1/very-dead-page', * ], * ], * [ * 'home_url' => 'http://example.com/home1', * 'home_path' => '/path-to/home1/wp-content/cache/wp-rocket/example.com-Greg-594d03f6ae698691165999/home1', * 'logged_in' => true, * 'files' => [ * '/path-to/home1/wp-content/cache/wp-rocket/example.com-Greg-594d03f6ae698691165999/home1/how-to-prank-your-coworkers', * '/path-to/home1/wp-content/cache/wp-rocket/example.com-Greg-594d03f6ae698691165999/home1/best-source-of-gifs', * ], * ], * [ * 'home_url' => 'http://example.com/home4', * 'home_path' => '/path-to/home4/wp-content/cache/wp-rocket/example.com-Greg-71edg8d6af865569979569/home4', * 'logged_in' => true, * 'files' => [ * '/path-to/home4/wp-content/cache/wp-rocket/example.com-Greg-71edg8d6af865569979569/home4/easter-eggs-in-code-your-best-opportunities', * ], * ], * ] * } * @param array $args { * @type int $lifespan Files lifespan in seconds. * @type int $file_age_limit Timestamp of the maximum age files must have. This is basically `time() - $lifespan`. * } */ do_action( 'rocket_after_automatic_cache_purge', $deleted, $args ); } /** ----------------------------------------------------------------------------------------- */ /** TOOLS =================================================================================== */ /** ----------------------------------------------------------------------------------------- */ /** * Get all cache files for the provided URL * * @since 3.4 * * @param array $file An array of the parsed URL parts. * @return array|\CallbackFilterIterator */ private function get_cache_files_in_dir( $file ) { // Grab cache folders. $host_pattern = '@^' . preg_quote( $file['host'], '@' ) . '@'; $sub_dir = rtrim( $file['path'], '/' ); try { $iterator = new \DirectoryIterator( $this->cache_path ); } catch ( \Exception $e ) { return []; } return new \CallbackFilterIterator( $iterator, function ( $current ) use ( $host_pattern, $sub_dir ) { if ( ! $current->isDir() || $current->isDot() ) { // We look for folders only, and don't want '.' nor '..'. return false; } if ( ! preg_match( $host_pattern, $current->getFilename() ) ) { // Not the right host. return false; } if ( '' !== $sub_dir && ! $this->filesystem->exists( $current->getPathname() . $sub_dir ) ) { // Not the right path. return false; } return true; } ); } /** * Purge a folder from old files. * * @since 3.4 * * @param string $dir_path Path to the folder to purge. * @param int $file_age_limit Timestamp of the maximum age files must have. * @return array A list of files that have been deleted. */ private function purge_dir( $dir_path, $file_age_limit ) { $deleted = []; try { $iterator = new \DirectoryIterator( $dir_path ); } catch ( \Exception $e ) { return []; } foreach ( $iterator as $item ) { if ( $item->isDot() ) { continue; } if ( $item->isDir() ) { /** * A folder, let’s see what’s in there. * Maybe there’s a dinosaur fossil or a hidden treasure. */ $dir_deleted = $this->purge_dir( $item->getPathname(), $file_age_limit ); $deleted = array_merge( $deleted, $dir_deleted ); } elseif ( $item->isFile() && $item->getMTime() < $file_age_limit ) { $file_path = $item->getPathname(); /** * The file is older than our limit. * This will also delete the file if `$item->getMTime()` fails. */ if ( ! $this->filesystem->delete( $file_path ) ) { continue; } /** * A page can have multiple cache files: * index(-mobile)(-https)(-dynamic-cookie-key){0,*}.html(_gzip). */ $dir_path = dirname( $file_path ); if ( ! in_array( $dir_path, $deleted, true ) ) { $deleted[] = $dir_path; } } } if ( $this->is_dir_empty( $dir_path ) ) { // If the folder is empty, remove it. $this->filesystem->delete( $dir_path ); } return $deleted; } /** * Tell if a folder is empty. * * @since 3.4 * * @param string $dir_path Path to the folder to purge. * @return bool True if empty. False if it contains files. */ private function is_dir_empty( $dir_path ) { try { $iterator = new \DirectoryIterator( $dir_path ); } catch ( \Exception $e ) { return true; } foreach ( $iterator as $item ) { if ( $item->isDot() ) { continue; } return false; } return true; } /** * Update lifespan option to convert old minutes to hours. * * @since 3.8 * * @param int $old_lifespan Old value in minutes. * @param string $old_lifespan_unit Old value of unit. * * @return void */ public function update_lifespan_value( $old_lifespan, $old_lifespan_unit ) { if ( 'MINUTE_IN_SECONDS' !== $old_lifespan_unit ) { return; } $options = get_option( 'wp_rocket_settings', [] ); if ( $old_lifespan > 0 && $old_lifespan < 60 ) { $old_lifespan = 60; } $options['purge_cron_unit'] = 'HOUR_IN_SECONDS'; $options['purge_cron_interval'] = round( $old_lifespan / 60 ); update_option( 'wp_rocket_settings', $options ); } }