', addslashes($reactivate_url)); w3_activate_error(sprintf('%s
then %s.', $e->getMessage(), $reactivate_button)); } /** * W3 writable error * * @param string $path * @return string */ function w3_writable_error($path) { $reactivate_url = wp_nonce_url('plugins.php?action=activate&plugin=' . W3TC_FILE, 'activate-plugin_' . W3TC_FILE); $reactivate_button = sprintf('', addslashes($reactivate_url)); try { w3_throw_on_write_error($path); } catch (Exception $e) { w3_activation_error_on_exception($e); } } /** * W3 error on read * * @param string $path * @throws FileOperationException */ function w3_throw_on_read_error($path) { w3_require_once(W3TC_INC_DIR . '/functions/file.php'); if (w3_check_open_basedir($path)) { $error = sprintf('%s could not be read, please run following ' . 'command:
chmod 777 %s', $path, (file_exists($path) ? $path : dirname($path))); } else { $error = sprintf('%s could not be read, open_basedir' . ' restriction in effect, please check your php.ini settings:
' . 'open_basedir = "%s"', $path, ini_get('open_basedir')); } throw new FileOperationException($error, 'read', 'file', $path); } /** * W3 writable error * * @param string $path * @throws FileOperationException */ function w3_throw_on_write_error($path) { w3_require_once(W3TC_INC_DIR . '/functions/file.php'); if (w3_check_open_basedir($path)) { $error = sprintf('%s could not be created, please run following ' . 'command:
chmod 777 %s', $path, (file_exists($path) ? $path : dirname($path))); } else { $error = sprintf('%s could not be created, open_basedir' . ' restriction in effect, please check your php.ini settings:
' . 'open_basedir = "%s"', $path, ini_get('open_basedir')); } throw new FileOperationException($error, 'create', 'file', $path); } /** * Creates cache folder and extension files. * Throws exception on failure. * * @throws Exception */ function w3_activation_create_required_files() { /** * Check installation files */ $files = array( W3TC_INSTALL_FILE_ADVANCED_CACHE, W3TC_INSTALL_FILE_DB, W3TC_INSTALL_FILE_OBJECT_CACHE); $nonexistent_files = array(); foreach ($files as $file) { if (!file_exists($file)) { $nonexistent_files[] = $file; } } if (count($nonexistent_files)) { throw new Exception(sprintf('Unfortunately core file(s): (%s) ' . 'are missing, so activation will fail. Please re-start the installation ' . 'process from the beginning.', implode(', ', $nonexistent_files))); } $directories = array( W3TC_CACHE_DIR, W3TC_CONFIG_DIR, W3TC_CACHE_CONFIG_DIR, W3TC_CACHE_TMP_DIR); foreach ($directories as $d) { if (!@is_dir($d)) { try{ w3_wp_create_folder($d, 'direct'); } catch(Exception $ex) {} } } } /** * Copy file if destination does not exists or not equal * * @param string $source_filename * @param string $destination_filename * @param string $method Which method to use when creating * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials * @throws FileOperationException */ function w3_copy_if_not_equal($source_filename, $destination_filename, $method = 'direct') { if (@file_exists($destination_filename)) { $s = fopen($source_filename, 'rb'); if ($s) { $v1 = fread($s, filesize($source_filename)); fclose($s); $d = fopen($destination_filename, 'rb'); if ($d) { if (filesize($destination_filename) <= 0) $v2 = ''; else $v2 = fread($d, filesize($destination_filename)); fclose($d); if ($v1 && $v2 && $v1 == $v2) return; } } } w3_wp_copy_file($source_filename, $destination_filename, $method); } /** * Copy file using WordPress filesystem functions. * @param $source_filename * @param $destination_filename * @param string $method Which method to use when creating * @param string $url Where to redirect after creation * @param bool|string $context folder to copy files too * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials * @throws FileOperationException */ function w3_wp_copy_file($source_filename, $destination_filename, $method = '', $url = '', $context = false) { w3_wp_request_filesystem_credentials($method, $url, $context); global $wp_filesystem; $contents = $wp_filesystem->get_contents($source_filename); if (!$wp_filesystem->put_contents( $destination_filename, $contents, FS_CHMOD_FILE)) { throw new FileOperationException('Could not create file ' . $destination_filename, 'create', 'file', $destination_filename); } } /** * @param $folder * @param string $method Which method to use when creating * @param string $url Where to redirect after creation * @param bool|string $context folder to create folder in * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials * @throws FileOperationException */ function w3_wp_create_folder($folder, $method = '', $url = '', $context = false) { w3_wp_request_filesystem_credentials($method, $url, $context); global $wp_filesystem; if (!$wp_filesystem->mkdir($folder, FS_CHMOD_DIR)) { throw new FileOperationException('Could not create folder:' . $folder, 'create', 'folder', $folder); } } /** * @param $folders * @param string $method Which method to use when creating * @param string $url Where to redirect after creation * @param bool|string $context folder to create folders in * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials * @throws FileOperationException */ function w3_wp_create_folders($folders, $method = '', $url = '', $context = false) { w3_wp_request_filesystem_credentials($method, $url, $context); global $wp_filesystem; foreach($folders as $folder) { if (!$wp_filesystem->mkdir($folder, FS_CHMOD_DIR)) { throw new FileOperationException('Could not create folder: ' . $folder, 'create', 'folder', $folder); } } } /** * @param $folders * @param string $method Which method to use when creating * @param string $url Where to redirect after creation * @param bool|string $context path folder where delete folders resides * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials * @throws FileOperationException */ function w3_wp_delete_folders($folders, $method = '', $url = '', $context = false) { $delete_folders = array(); foreach($folders as $folder) { if (is_dir($folder) && file_exists($folder)) $delete_folders[] = $folder; } if (empty($delete_folders)) return; w3_wp_request_filesystem_credentials($method, $url, $context); global $wp_filesystem; foreach($delete_folders as $folder) { w3_rmdir($folder); if (file_exists($folder)) if (!$wp_filesystem->rmdir($folder, FS_CHMOD_DIR)) { throw new FileOperationException('Could not delete folder: ' . $folder, 'delete', 'folder', $folder); } } } /** * @param $file * @param string $method * @param string $url * @param bool|string $context folder where file to be deleted resides * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials * @throws FileOperationException */ function w3_wp_delete_file($file, $method = '', $url = '', $context = false) { if (@unlink($file)) { w3_wp_request_filesystem_credentials($method, $url, false, $context = false); global $wp_filesystem; if (file_exists($file) && !$wp_filesystem->delete($file)) { throw new FileOperationException('Could not delete file: ' . $file, 'delete', 'file', $file); } } } /** * Copy files using WordPress filesystem functions. * @param $files * @param string $method Which method to use when creating * @param string $url Where to redirect after creation * @param bool|string $context folder to copy too * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials * @throws FileOperationException */ function w3_wp_copy_files($files, $method = '', $url = '', $context = false) { w3_wp_request_filesystem_credentials($method, $url, false, $context); global $wp_filesystem; foreach($files as $source_filename => $destination_filename) { $contents = $wp_filesystem->get_contents($source_filename); if (!$wp_filesystem->put_contents($destination_filename, $contents, FS_CHMOD_FILE)) { throw new FileOperationException('Could not create file: ' . $destination_filename, 'create', 'file', $destination_filename); } } } /** * Get WordPress filesystems credentials. Required for WP filesystem usage. * @param string $method Which method to use when creating * @param string $url Where to redirect after creation * @param bool|string $context path to folder that should be have filesystem credentials. If false WP_CONTENT_DIR is assumed * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials */ function w3_wp_request_filesystem_credentials($method = '', $url = '', $context = false) { $success = true; ob_start(); if (false === ($creds = request_filesystem_credentials($url, $method, false, $context, array()))) { $success = false; } $form = ob_get_contents(); ob_end_clean(); ob_start(); // If first check failed try again and show error message if (!WP_Filesystem($creds) && $success) { request_filesystem_credentials($url, $method, true, false, array()); $success = false; $form = ob_get_contents(); } ob_end_clean(); if (!$success) { throw new FilesystemCredentialException('Could not get write credentials', $method, $form); } } /** * @param $add_in_files array with key as source and value as destination * @param $cache_folders value is the folder path * @param string $method Which method to use when creating * @param string $url Where to redirect after creation * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials * @throws FileOperationException */ function w3_create_missing_files_and_folders($add_in_files, $cache_folders, $method = '', $url = '') { if (empty($add_in_files) && empty($cache_folders)) return; w3_wp_request_filesystem_credentials($method, $url); global $wp_filesystem; foreach($cache_folders as $folder) { if (!$wp_filesystem->mkdir($folder, FS_CHMOD_DIR)) { throw new FileOperationException('Could not create folder:' . $folder, 'create', 'folder', $folder); } } foreach($add_in_files as $source_filename => $destination_filename) { $contents = $wp_filesystem->get_contents($source_filename); if (file_exists($destination_filename) && ! $wp_filesystem->delete($destination_filename)) throw new FileOperationException('Could not delete file: ' . $destination_filename, 'delete', 'file', $destination_filename); if (!$wp_filesystem->put_contents($destination_filename, $contents, FS_CHMOD_FILE)) { throw new FileOperationException('Could not create file: ' . $destination_filename, 'create', 'file', $destination_filename); } } } /** * Create files * @param $files array(from file => to file) * @param string $method * @param string $url * @param bool|string path to folder where files should be created * @throws FileOperationException */ function w3_create_files($files, $method = '', $url = '', $context = false) { if (empty($files)) return; w3_wp_request_filesystem_credentials($method, $url, $context); global $wp_filesystem; foreach($files as $source_filename => $destination_filename) { $contents = $wp_filesystem->get_contents($source_filename); if (file_exists($destination_filename) && ! $wp_filesystem->delete($destination_filename)) throw new FileOperationException('Could not delete file: ' . $destination_filename, 'delete', 'file', $destination_filename); if (!$wp_filesystem->put_contents($destination_filename, $contents, FS_CHMOD_FILE)) { throw new FileOperationException('Could not create file: ' . $destination_filename, 'create', 'file', $destination_filename); } } } /** * Create folders * @param $folders array(folderpath1, folderpath2, ...) * @param string $method * @param string $url * @throws FileOperationException */ function w3_create_folders($folders, $method = '', $url = '') { if (empty($add_in_files) && empty($folders)) return; w3_wp_request_filesystem_credentials($method, $url); global $wp_filesystem; foreach($folders as $folder) { if (!$wp_filesystem->mkdir($folder, FS_CHMOD_DIR)) { throw new FileOperationException('Could not create folder:' . $folder, 'create', 'folder', $folder); } } } /** * Tries to write file content * @param $filename path to file * @param $content data to write * @param string $method Which method to use when creating * @param string $url Where to redirect after creation * @param bool|string $context folder in which to write file * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials * @throws FileOperationException * @return true; */ function w3_write_to_file($filename, $content, $method = '', $url = '', $context = false) { if (is_writable($filename)) { if (@file_put_contents($filename, $content)) return true; w3_wp_request_filesystem_credentials('direct'); global $wp_filesystem; if ($wp_filesystem->put_contents($filename, $content)) return true; } w3_wp_request_filesystem_credentials($method, $url, $context); $permissions = array(0644, 0664, 0666); global $wp_filesystem; if (!$wp_filesystem->put_contents($filename, $content)) { foreach ($permissions as $permission) { try{ w3_chmod_file($filename, $permission); if ($wp_filesystem->put_contents($filename, $content)) return true; }catch (Exception $ex) {} } throw new FileOperationException('Could not write to file: ' . $filename, 'write', 'file', $filename); } return true; } /** * Tries to read file content * @param $filename path to file * @param string $method Which method to use when creating * @param string $url Where to redirect after creation * @param bool|string $context folder to read from * @return mixed * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials * @throws FileOperationException */ function w3_read_from_file($filename, $method = '', $url = '', $context = false) { w3_wp_request_filesystem_credentials($method, $url, $context); global $wp_filesystem; if (!($content = $wp_filesystem->get_contents($filename))) { throw new FileOperationException('Could not read file: ' . $filename, 'write', 'file', $filename); } return $content; } /** * @param string $dir path to dir * @param int $permission * @param bool $recursive * @param string $method * @param string $url * @param bool|string $context folder where dir resides to chmod * @return bool * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials * @throws FileOperationException */ function w3_chmod_dir($dir, $permission, $recursive = false, $method = '', $url = '', $context = false) { if (!is_dir($dir) || !file_exists($dir)) return false; w3_wp_request_filesystem_credentials($method, $url, $context); global $wp_filesystem; if (!$wp_filesystem->chmod($dir, $permission, $recursive)) { throw new FileOperationException('Could not chmod dir: ' . $dir, 'chmod', 'dir', $dir); } return true; } /** * @param $file path to file * @param $permission * @param string $method * @param string $url * @param bool|string $context * @return bool * @throws FilesystemCredentialException with S/FTP form if it can't get the required filesystem credentials * @throws FileOperationException */ function w3_chmod_file($file, $permission, $method = '', $url = '', $context = false) { if (!file_exists($file)) return false; if (@chmod($file, $permission)) return true; w3_wp_request_filesystem_credentials($method, $url, $context); global $wp_filesystem; if (!$wp_filesystem->chmod($file, $permission)) { throw new FileOperationException('Could not chmod file: ' . $file, 'chmod', 'file', $file); } return true; } /** * Creates maintenance mode file * @param $time */ function w3_enable_maintenance_mode($time = null) { if (is_null($time)) $time = 'time()'; w3_write_to_file(w3_get_site_root() . '/.maintenance', ""); } /** * Deletes maintenance mode file */ function w3_disable_maintenance_mode() { w3_wp_delete_file(w3_get_site_root() . '/.maintenance'); } /** * Thrown when the plugin fails to get correct filesystem rights when it tries to modify manipulate filesystem. */ class FilesystemCredentialException extends Exception { private $method_used; private $ftp_form; public function __construct($message, $method_used = 'direct', $ftp_form = '') { parent::__construct($message); $this->method_used = $method_used; $this->ftp_form = $ftp_form; } public function method_used() { return $this->method_used; } public function ftp_form() { return $this->ftp_form; } } /** * Thrown when the plugin fails to read, create, delete files and folders. */ class FileOperationException extends Exception { private $operation; private $file_type; private $filename; public function __construct($message, $operation = '', $file_type = '', $filename = '') { parent::__construct($message); $this->operation = $operation; $this->file_type = $file_type; $this->filename = $filename; } public function getFileType() { return $this->file_type; } public function getFilename() { return $this->filename; } public function getOperation() { return $this->operation; } }