1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-09 00:06:55 +02:00

Improvements to SystemUpdater module so that it can support manual API calls

This commit is contained in:
Ryan Cramer
2019-07-03 12:20:27 -04:00
parent 0e00f24004
commit a336acfaa4
2 changed files with 138 additions and 30 deletions

View File

@@ -8,8 +8,18 @@
*/ */
abstract class SystemUpdate extends Wire { abstract class SystemUpdate extends Wire {
/**
* @var SystemUpdater
*
*/
protected $updater; protected $updater;
/**
* Construct
*
* @param SystemUpdater $updater
*
*/
public function __construct(SystemUpdater $updater) { public function __construct(SystemUpdater $updater) {
$this->updater = $updater; $this->updater = $updater;
} }
@@ -24,20 +34,41 @@ abstract class SystemUpdate extends Wire {
*/ */
abstract public function execute(); abstract public function execute();
/**
* Get update name that appears in notices
*
* @return string
*
*/
public function getName() { public function getName() {
$name = str_replace(__NAMESPACE__ . "\\SystemUpdate", "", get_class($this)); $name = "Update #" . $this->getVersion();
$name = "Update #$name";
return $name; return $name;
} }
/**
* Get update version number
*
* @return int
*
*/
public function getVersion() {
return (int) str_replace('SystemUpdate', '', $this->className());
}
public function message($text, $flags = 0) { public function message($text, $flags = 0) {
$text = $this->getName() . ": $text"; $text = $this->getName() . ": $text";
$this->updater->message($text, $flags); $this->updater->message($text, $flags);
return $this; return $this;
} }
public function warning($text, $flags = 0) {
$text = $this->getName() . ": $text";
$this->updater->warning($text, $flags);
return $this;
}
public function error($text, $flags = 0) { public function error($text, $flags = 0) {
$text = $this->getName() . " ERROR: $text"; $text = $this->getName() . ": $text";
$this->updater->error($text, $flags); $this->updater->error($text, $flags);
return $this; return $this;
} }

View File

@@ -5,7 +5,7 @@
* *
* ProcessWire System Helper Module * ProcessWire System Helper Module
* *
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer * ProcessWire 3.x, Copyright 2019 by Ryan Cramer
* https://processwire.com * https://processwire.com
* *
* @method coreVersionChange($fromVersion, $toVersion) * @method coreVersionChange($fromVersion, $toVersion)
@@ -43,6 +43,14 @@ class SystemUpdater extends WireData implements Module, ConfigurableModule {
*/ */
protected $numUpdatesApplied = 0; protected $numUpdatesApplied = 0;
/**
* Is an update being applied manually?
*
* @var bool|int Contains update number when one is being manually applied
*
*/
protected $manualVersion = false;
/** /**
* Part of the ConfigurableModule interface, sets config data to the module * Part of the ConfigurableModule interface, sets config data to the module
* *
@@ -159,21 +167,24 @@ class SystemUpdater extends WireData implements Module, ConfigurableModule {
* Save the system version as the given version number * Save the system version as the given version number
* *
* @param int $version * @param int $version
* @return bool
* *
*/ */
public function saveSystemVersion($version) { public function saveSystemVersion($version) {
if($this->manualVersion == $version) return false;
$version = (int) $version; $version = (int) $version;
$this->wire('config')->systemVersion = $version; $this->wire('config')->systemVersion = $version;
$this->configData['systemVersion'] = $version; $this->configData['systemVersion'] = $version;
$this->configData['coreVersion'] = $this->wire('config')->version; $this->configData['coreVersion'] = $this->wire('config')->version;
$this->wire('modules')->saveModuleConfigData($this, $this->configData); $this->wire('modules')->saveModuleConfigData($this, $this->configData);
$this->message("Update #$version: Completed!"); $this->message("Update #$version: Completed!");
return true;
} }
/** /**
* Check for an update file in the format: SystemUpdater123 where '123' is the version it upgrades to * Check for an update file in the format: SystemUpdater123 where '123' is the version it upgrades to
* *
* If found, instantiate the class and it's constructor should perform the update or add any hooks necessary to perform the update * If found, instantiate the class and its constructor should perform the update or add any hooks necessary to perform the update
* *
* @param int $version * @param int $version
* @return bool * @return bool
@@ -181,35 +192,85 @@ class SystemUpdater extends WireData implements Module, ConfigurableModule {
*/ */
protected function update($version) { protected function update($version) {
require_once(dirname(__FILE__) . '/SystemUpdate.php');
$className = 'SystemUpdate' . $version;
$filename = $this->config->paths('SystemUpdater') . $className . '.php';
$className = wireClassName($className, true);
$errorMessage = sprintf('Failed to apply update %d', $version); $errorMessage = sprintf('Failed to apply update %d', $version);
$update = null;
if(is_file($filename)) { try {
$update = null; $update = $this->getUpdate($version);
try { if(!$update) return true;
include($filename); $update->message('Initializing update');
/** @var SystemUpdate $update */ $success = $update->execute();
$update = $this->wire(new $className($this)); if($success === false) $update->error($errorMessage);
$update->message('Initializing update'); } catch(\Exception $e) {
$success = $update->execute(); $msg = $errorMessage . " - " . $e->getMessage();
if($success === false) $update->error($errorMessage); $messenger = $update ? $update : $this;
} catch(\Exception $e) { $messenger->error($msg);
$msg = $errorMessage . " - " . $e->getMessage(); $success = false;
if($update) {
$update->error($msg);
} else {
$this->error($msg);
}
$success = false;
}
if(!$success) return false;
} }
return true; return $success;
}
/**
* Get a specific SystemUpdate class instance by version number and return it (without executing it)
*
* @param int $version Update version number
* @return null|SystemUpdate Returns SystemUpdate instance of available or null if not
*
*/
public function getUpdate($version) {
$path = dirname(__FILE__) . '/';
require_once($path . 'SystemUpdate.php');
$className = 'SystemUpdate' . $version;
$filename = $path . $className . '.php';
if(!is_file($filename)) return null;
require_once($filename);
$className = wireClassName($className, true);
/** @var SystemUpdate $update */
$update = $this->wire(new $className($this));
return $update;
}
/**
* Manually apply a update
*
* The system version is not changed when applying an update manually.
*
* @param int|SystemUpdate $version Update version number or instance of SystemUpdate you want to apply
* @return bool True on success, false on fail
*
*/
public function apply($version) {
if(is_object($version)) {
$update = $version;
$version = $update->getVersion();
} else {
$update = null;
$version = (int) $version;
}
$this->manualVersion = $version;
try {
if(!$update) $update = $this->getUpdate($version);
$success = $update ? $update->execute() : true;
} catch(\Exception $e) {
$this->error($e->getMessage());
$success = false;
}
$this->manualVersion = false;
return $success;
} }
/** /**
@@ -224,6 +285,21 @@ class SystemUpdater extends WireData implements Module, ConfigurableModule {
$this->log($text); $this->log($text);
return parent::message($text, $flags); return parent::message($text, $flags);
} }
/**
* Warning notice
*
* @param string $text
* @param int $flags
* @return SystemUpdater|WireData
*
*/
public function warning($text, $flags = 0) {
$text = "WARNING: $text";
$this->log($text);
return parent::warning($text, $flags);
}
/** /**
* Error notice * Error notice
@@ -267,6 +343,7 @@ class SystemUpdater extends WireData implements Module, ConfigurableModule {
$f->attr('name', '_log'); $f->attr('name', '_log');
$f->label = $this->_('System Update Log'); $f->label = $this->_('System Update Log');
$logContent = $this->wire('sanitizer')->unentities(file_get_contents($logfile)); $logContent = $this->wire('sanitizer')->unentities(file_get_contents($logfile));
$logContent = preg_replace('!<a href=.+?>(.+?)</a>!', '$1', $logContent);
$f->value = '<pre>' . $this->wire('sanitizer')->entities($logContent) . '</pre>'; $f->value = '<pre>' . $this->wire('sanitizer')->entities($logContent) . '</pre>';
$inputfields->add($f); $inputfields->add($f);
} }