(.+)<\/div>/", $form, $matches)) {
$error = $matches[2];
$form = str_replace($matches[0], '', $form);
}
if (!$success) {
throw new FilesystemOperationException($error, $form);
}
}
/**
* @param string $method
* @param string $url
* @param bool|string $context
* @return FilesystemOperationException with S/FTP form
*/
function w3_get_filesystem_credentials_form($method = '', $url = '',
$context = false) {
ob_start();
// If first check failed try again and show error message
request_filesystem_credentials($url, $method, true, false, array());
$success = false;
$form = ob_get_contents();
ob_end_clean();
$error = '';
if (preg_match("/
(.+)<\/div>/", $form, $matches)) {
$form = str_replace($matches[0], '', $form);
}
return $form;
}
/**
* Creates maintenance mode file
* @param $time
*/
function w3_enable_maintenance_mode($time = null) {
if (is_null($time))
$time = 'time()';
w3_wp_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');
}
/**
* Used to display SelfTestExceptions in UI
* @param SelfTestExceptions $exs
* @return array(before_errors = [], required_changes =>, later_errors => [])
**/
function w3_parse_selftest_exceptions($exs) {
$exceptions = $exs->exceptions();
$commands = '';
$required_changes = '';
$before_errors = array();
$later_errors = array();
$operation_error_already_shown = false;
foreach ($exceptions as $ex) {
if ($ex instanceof FilesystemOperationException) {
if (!$operation_error_already_shown) {
$m = $ex->getMessage();
if (strlen($m) > 0) {
$before_errors[] = $m;
// if multiple operations failed when
// they tried to fix environment - show only first
// otherwise can duplication information about
// absense of permissions
$operation_error_already_shown = true;
}
if ($ex instanceof FilesystemWriteException) {
$required_changes .=
sprintf(__('Create the
%s file and paste the following text into it:
', 'w3-total-cache'), $ex->filename(), esc_textarea($ex->file_contents()));
} else if ($ex instanceof FilesystemModifyException) {
$modification_content = $ex->file_contents();
if (strlen($modification_content) > 0)
$modification_content =
'
';
$required_changes .=
$ex->modification_description() .
$modification_content .
'
';
} else if ($ex instanceof FilesystemCopyException) {
$commands .= 'cp ' . $ex->source_filename() . ' ' .
$ex->destination_filename() . '
';
} else if ($ex instanceof FilesystemMkdirException) {
$commands .= 'mkdir ' . $ex->folder() . '
';
$commands .= 'chmod 777 ' . $ex->folder() . '
';
} else if ($ex instanceof FilesystemRmException) {
$commands .= 'rm ' . $ex->filename() . '
';
} else if ($ex instanceof FilesystemRmdirException) {
$commands .= 'rm -rf ' . $ex->folder() . '
';
} else if ($ex instanceof FilesystemChmodException) {
$commands .= 'chmod 777 ' . $ex->filename() . '
';
}
}
} else if ($ex instanceof SelfTestFailedException) {
$t = $ex->technical_message();
if (strlen($t) > 0) {
$t = '
' .
'
' .
__('Technical info', 'w3-total-cache').'' .
'
' .
$t . '
';
}
$later_errors[] = $ex->getMessage() . $t;
} else {
// unknown command
$later_errors[] = $ex->getMessage();
}
}
if (strlen($commands) > 0) {
$required_changes .= __('Execute next commands in a shell:', 'w3-total-cache') .
'
' . $commands . '';
}
return array(
'before_errors' => $before_errors,
'required_changes' => $required_changes,
'later_errors' => $later_errors
);
}
/**
* Thrown when the plugin fails to get correct filesystem rights when it tries to modify manipulate filesystem.
*/
class FilesystemOperationException extends Exception {
private $credentials_form;
public function __construct($message, $credentials_form = null) {
parent::__construct($message);
$this->credentials_form = $credentials_form;
}
public function credentials_form() {
return $this->credentials_form;
}
}
class FilesystemWriteException extends FilesystemOperationException {
private $filename;
private $file_contents;
public function __construct($message, $credentials_form, $filename,
$file_contents) {
parent::__construct($message, $credentials_form);
$this->filename = $filename;
$this->file_contents = $file_contents;
}
public function filename() {
return $this->filename;
}
public function file_contents() {
return $this->file_contents;
}
}
class FilesystemModifyException extends FilesystemOperationException {
private $modification_description;
private $filename;
private $file_contents;
public function __construct($message, $credentials_form,
$modification_description, $filename, $file_contents = '') {
parent::__construct($message, $credentials_form);
$this->modification_description = $modification_description;
$this->filename = $filename;
$this->file_contents = $file_contents;
}
function modification_description() {
return $this->modification_description;
}
public function filename() {
return $this->filename;
}
public function file_contents() {
return $this->file_contents;
}
}
class FilesystemCopyException extends FilesystemOperationException {
private $source_filename;
private $destination_filename;
public function __construct($message, $credentials_form,
$source_filename, $destination_filename) {
parent::__construct($message, $credentials_form);
$this->source_filename = $source_filename;
$this->destination_filename = $destination_filename;
}
public function source_filename() {
return $this->source_filename;
}
public function destination_filename() {
return $this->destination_filename;
}
}
class FilesystemMkdirException extends FilesystemOperationException {
private $folder;
public function __construct($message, $credentials_form, $folder) {
parent::__construct($message, $credentials_form);
$this->folder = $folder;
}
public function folder() {
return $this->folder;
}
}
class FilesystemChmodException extends FilesystemOperationException {
private $filename;
private $permission;
public function __construct($message, $credentials_form, $filename, $permission) {
parent::__construct($message, $credentials_form);
$this->filename = $filename;
$this->permission = $permission;
}
public function filename() {
return $this->filename;
}
public function permission() {
return $this->permission;
}
}
class FilesystemRmException extends FilesystemOperationException {
private $filename;
public function __construct($message, $credentials_form, $filename) {
parent::__construct($message, $credentials_form);
$this->filename = $filename;
}
public function filename() {
return $this->filename;
}
}
class FilesystemRmdirException extends FilesystemOperationException {
private $folder;
public function __construct($message, $credentials_form, $folder) {
parent::__construct($message, $credentials_form);
$this->folder = $folder;
}
public function folder() {
return $this->folder;
}
}
class SelfTestFailedException extends Exception {
private $technical_message;
public function __construct($message, $technical_message = '') {
parent::__construct($message);
$this->technical_message = $technical_message;
}
public function technical_message() {
return $this->technical_message;
}
}
class SelfTestExceptions extends Exception {
private $exceptions;
private $credentials_form;
public function __construct() {
parent::__construct();
$this->exceptions = array();
}
public function push($ex) {
if ($ex instanceof SelfTestExceptions) {
foreach ($ex->exceptions() as $ex2)
$this->push($ex2);
} else {
if ($this->credentials_form == null &&
$ex instanceof FilesystemOperationException &&
$ex->credentials_form() != null)
$this->credentials_form = $ex->credentials_form();
$this->exceptions[] = $ex;
}
}
/**
* @return Exception[]
*/
public function exceptions() {
return $this->exceptions;
}
public function credentials_form() {
return $this->credentials_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;
}
}
/**
* @return string[] error messages
*/
function w3_deactivate_plugin() {
$errors = array();
try {
$environment = w3_instance('W3_AdminEnvironment');
$environment->fix_after_deactivation();
deactivate_plugins(plugin_basename(W3TC_FILE));
} catch (SelfTestExceptions $exs) {
$r = w3_parse_selftest_exceptions($exs);
foreach ($r['before_errors'] as $e)
$errors[] = $e;
if (strlen($r['required_changes']) > 0) {
$changes_style = 'border: 1px solid black; ' .
'background: white; ' .
'margin: 10px 30px 10px 30px; ' .
'padding: 10px; display: none';
$ftp_style = 'border: 1px solid black; background: white; ' .
'margin: 10px 30px 10px 30px; ' .
'padding: 10px; display: none';
$ftp_form = str_replace('class="wrap"', '',
$exs->credentials_form());
$ftp_form = str_replace('
', '', $ftp_form);
$ftp_form = str_replace('id="upgrade" class="button"',
'id="upgrade" class="button w3tc-button-save"', $ftp_form);
$error = sprintf( __('
W3 Total Cache Error:
Files and directories could not be automatically
deleted.
| Please execute commands manually |
%s
|
| or use FTP form to allow
W3 Total Cache make it automatically.
|
%s
|
', 'w3-total-cache'),
w3_button(__('View required changes', 'w3-total-cache'), '', 'w3tc-show-required-changes'),
w3_button(__('Update via FTP', 'w3-total-cache'), '', 'w3tc-show-ftp-form')
) . '
' . $r['required_changes'] . '
' .
'
' .
$ftp_form . '
';
$errors[] = $error;
}
return $errors;
}
}