rpicms

A CMS for the Raspberry Pi
git clone git://archive.git.mtrnord.blog/RpicmsTeam/rpicms.git
Log | Files | Refs | README | LICENSE

commit 1a22a67bba80ca9b91e1a5b24c744a9fd065b97b
parent f338d191f333b65b62c6e4d2c14aa7e3b1bf5731
Author: MTRNord <mtrnord1@gmail.com>
Date:   Sun, 22 Feb 2015 19:35:37 +0100

white page :/

Diffstat:
Dcore/new_updater/LICENSE.md | 18------------------
Dcore/new_updater/update/index.php | 47-----------------------------------------------
Dcore/new_updater/update/update.php | 781-------------------------------------------------------------------------------
Ccore/update/LICENSE.md -> core/old_update/LICENSE.md | 0
Rcore/new_updater/index.php -> core/old_update/index.php | 0
Ccore/update/update/index.php -> core/old_update/update/index.php | 0
Ccore/update/update/update.php -> core/old_update/update/update.php | 0
Mcore/update/LICENSE.md | 5++---
Mcore/update/update/index.php | 52+++++++++++++++++++++++++++++++---------------------
Mcore/update/update/update.php | 903+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Mthemes/jumbotron/update.php | 2+-
11 files changed, 692 insertions(+), 1116 deletions(-)

diff --git a/core/new_updater/LICENSE.md b/core/new_updater/LICENSE.md @@ -1,18 +0,0 @@ -License -== - -PHP AutoUpdate --- -Copyright 2015 - VisualAppeal GbR - www.visualappeal.de - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -`http://www.apache.org/licenses/LICENSE-2.0` - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/core/new_updater/update/index.php b/core/new_updater/update/index.php @@ -1,46 +0,0 @@ -<?php -####################### -# flush browser cache # -####################### -header("Cache-Control: no-cache, must-revalidate, no-store"); - -require('update.php'); - -use \VisualAppeal\AutoUpdate; - -$update = new AutoUpdate($root . '/temp/', $root . '/', 60); -$update->setCurrentVersion('1.0.0'); -$update->setUpdateUrl('http://media.nordgedanken.de/rpicms/server'); - -// Optional: -$update->addLogHandler(new Monolog\Handler\StreamHandler($root . 'core/update/update.log')); - - -//Check for a new update -if ($update->checkUpdate() === false) - die('Could not check for updates! See log file for details.'); -if ($update->newVersionAvailable()) { - //Install new update - echo 'New Version: ' . $update->getLatestVersion() . '<br>'; - echo 'Installing Updates: <br>'; - echo '<pre>'; - var_dump(array_map(function($version) { - return (string) $version; - }, $update->getVersionsToUpdate())); - echo '</pre>'; - $result = $update->update(); - if ($result === true) { - echo 'Update successful<br>'; - } else { - echo 'Update failed: ' . $result . '!<br>'; - if ($result = AutoUpdate::ERROR_SIMULATE) { - echo '<pre>'; - var_dump($update->getSimulationResults()); - echo '</pre>'; - } - } -} else { - echo 'Current Version is up to date<br>'; -} - -?> -\ No newline at end of file diff --git a/core/new_updater/update/update.php b/core/new_updater/update/update.php @@ -1,781 +0,0 @@ -<?php namespace VisualAppeal; - -use vierbergenlars\SemVer\version; -use vierbergenlars\SemVer\expression; -use vierbergenlars\SemVer\SemVerException; - -use Desarrolla2\Cache\Cache; -use Desarrolla2\Cache\Adapter\NotCache; - -use Monolog\Logger; -use Monolog\Handler\NullHandler; - - -############################### -# include files from root dir # -############################### -$root_1 = realpath($_SERVER["DOCUMENT_ROOT"]); -$currentdir = getcwd(); -$root_2 = str_replace($root_1, '', $currentdir); -$root_3 = explode("/", $root_2); -if ($root_3[1] == 'core') { - echo $root_3[1]; - $root = realpath($_SERVER["DOCUMENT_ROOT"]); -}else{ - $root = $root_1 . '/' . $root_3[1]; -} - - -/** - * Auto update class. - */ -class AutoUpdate -{ - /** - * The latest version. - * - * @var vierbergenlars\SemVer\version - */ - private $_latestVersion = null; - - /** - * Updates not yet installed. - * - * @var array - */ - private $_updates = null; - - /** - * Cache for update requests. - * - * @var Desarrolla2\Cache\Cache - */ - private $_cache = null; - - /** - * Result of simulated install. - * - * @var array - */ - private $_simulationResults = array(); - - /** - * Url to the update folder on the server. - * - * @var string - */ - protected $_updateUrl = 'http://media.nordgedanken.de/rpicms/update/server/'; - - /** - * Version filename on the server. - * - * @var string - */ - protected $_updateFile = 'update.json.$this->branch'; - - /* - * branch on the server - */ - public $branch = 'stable'; - - /** - * Current version. - * - * @var vierbergenlars\SemVer\version - */ - protected $_currentVersion = null; - - /** - * Temporary download directory. - * - * @var string - */ - private $_tempDir = ''; - - /** - * Install directory. - * - * @var string - */ - private $_installDir = ''; - - /** - * Create new folders with this privileges. - * - * @var int - */ - public $dirPermissions = 0755; - - /** - * Update script filename. - * - * @var string - */ - public $updateScriptName = '_upgrade.php'; - - /** - * No update available. - */ - const NO_UPDATE_AVAILABLE = 0; - - /** - * Zip file could not be opened. - */ - const ERROR_INVALID_ZIP = 10; - - /** - * Could not check for last version. - */ - const ERROR_VERSION_CHECK = 20; - - /** - * Temp directory does not exist or is not writable. - */ - const ERROR_TEMP_DIR = 30; - - /** - * Install directory does not exist or is not writable. - */ - const ERROR_INSTALL_DIR = 35; - - /** - * Could not download update. - */ - const ERROR_DOWNLOAD_UPDATE = 40; - - /** - * Could not delete zip update file. - */ - const ERROR_DELETE_TEMP_UPDATE = 50; - - /** - * Error while installing the update. - */ - const ERROR_INSTALL = 60; - - /** - * Error in simulated install. - */ - const ERROR_SIMULATE = 70; - - /** - * Create new instance - * - * @param string $tempDir - * @param string $installDir - * @param int $maxExecutionTime - */ - public function __construct($tempDir = null, $installDir = null, $maxExecutionTime = 60) { - $this->setTempDir(($tempDir !== null) ? $tempDir : __DIR__ . '/temp/'); - $this->setInstallDir(($installDir !== null) ? $installDir : __DIR__ . '/../../'); - - $this->_latestVersion = new version('0.0.0'); - $this->_currentVersion = new version('0.0.0'); - - // Init cache - $this->_cache = new Cache(new NotCache()); - - // Init logger - $this->_log = new Logger('auto-update'); - $this->_log->pushHandler(new NullHandler()); - - ini_set('max_execution_time', $maxExecutionTime); - } - - /** - * Set the temporary download directory. - * - * @param string $dir - */ - public function setTempDir($dir) - { - // Add slash at the end of the path - if (substr($dir, -1 != '/')) - $dir = $dir . '/'; - - if (!is_dir($dir)) { - if (!mkdir($dir, 0755, true)) { - $this->_log->addCritical(sprintf('Could not create temporary directory "%s"', $dir)); - return; - } - } - - $this->_tempDir = $dir; - } - - /** - * Set the install directory. - * - * @param string $dir - */ - public function setInstallDir($dir) - { - // Add slash at the end of the path - if (substr($dir, -1 != '/')) - $dir = $dir . '/'; - - if (!is_dir($dir)) { - if (!mkdir($dir, 0755, true)) { - $this->_log->addCritical(sprintf('Could not create temporary directory "%s"', $dir)); - return; - } - } - - $this->_installDir = $dir; - } - - /** - * Set the update filename. - * - * @param string $updateFile - */ - public function setUpdateFile($updateFile) - { - $this->_updateFile = $updateFile; - } - - /** - * Set the update filename. - * - * @param string $updateUrl - */ - public function setUpdateUrl($updateUrl) - { - $this->_updateUrl = $updateUrl; - } - - /** - * Set the cache component. - * - * @param Desarrolla2\Cache\Adapter\AdapterInterface $adapter See https://github.com/desarrolla2/Cache - * @param int $ttl Time to live in seconds - */ - public function setCache($adapter, $ttl = 3600) - { - $adapter->setOption('ttl', $ttl); - $this->_cache = new Cache($adapter); - } - - /** - * Set the version of the current installed software. - * - * @param string $currentVersion - * - * @return bool - */ - public function setCurrentVersion($currentVersion) - { - $version = new version($currentVersion); - if ($version->valid() === null) { - $this->_log->addError(sprintf('Invalid current version "%s"', $currentVersion)); - return false; - } - - $this->_currentVersion = $version; - return true; - } - - /** - * Add a new logging handler. - * - * @param Monolog\Handler\HandlerInterface $handler See https://github.com/Seldaek/monolog - */ - public function addLogHandler(\Monolog\Handler\HandlerInterface $handler) - { - $this->_log->pushHandler($handler); - } - - /** - * Get the name of the latest version. - * - * @return vierbergenlars\SemVer\version - */ - public function getLatestVersion() - { - return $this->_latestVersion; - } - - /** - * Get an array of versions which will be installed. - * - * @return array - */ - public function getVersionsToUpdate() - { - return array_map(function($update) { - return $update['version']; - }, $this->_updates); - } - - /** - * Get the results of the last simulation. - * - * @return array - */ - public function getSimulationResults() - { - return $this->_simulationResults; - } - - /** - * Remove directory recursively. - * - * @param string $dir - * - * @return void - */ - private function _removeDir($dir) { - $this->_log->addDebug(sprintf('Remove directory "%s"', $dir)); - - if (!is_dir($dir)) { - $this->_log->addWarning(sprintf('"%s" is not a directory!', $dir)); - return false; - } - - $objects = array_diff(scandir($dir), array('.', '..')); - foreach ($objects as $object) { - if (is_dir($dir . '/' . $object)) - $this->_removeDir($dir . '/' . $object); - else - unlink($dir . '/' . $object); - } - - return rmdir($dir); - } - - /** - * Check for a new version - * - * @return int|bool - * true: New version is available - * false: Error while checking for update - * int: Status code (i.e. AutoUpdate::NO_UPDATE_AVAILABLE) - */ - public function checkUpdate() { - $this->_log->addNotice('Checking for a new update...'); - - // Reset previous updates - $this->_latestVersion = new version('0.0.0'); - $this->_updates = []; - - $versions = $this->_cache->get('update-versions'); - - // Check if cache is empty - if ($versions === false) { - $updateFile = $this->_updateUrl . '/' . $this->_updateFile; - $this->_log->addDebug(sprintf('Get new updates from %s', $updateFile)); - - // Read update file from update server - $update = @file_get_contents($updateFile); - if ($update === false) { - $this->_log->addInfo(sprintf('Could not download update file "%s"!', $updateFile)); - return false; - } - - // Parse update file - $updateFileExtension = substr(strrchr($this->_updateFile, '.'), 1); - switch ($updateFileExtension) { - case 'ini': - $versions = parse_ini_string($update, true); - if (!is_array($versions)) { - $this->_log->addInfo('Unable to parse update file!'); - return false; - } - - $versions = array_map(function($block) { - return isset($block['url']) ? $block['url'] : false; - }, $versions); - - break; - case 'json': - $versions = json_decode($update); - - break; - default: - $this->_log->addInfo(sprintf('Unknown file extension "%s"', $updateFileExtension)); - return false; - } - - $this->_cache->set('update-versions', $versions); - } else { - $this->_log->addDebug('Got updates from cache'); - } - - // Check for latest version - foreach ($versions as $versionRaw => $updateUrl) { - $version = new version($versionRaw); - if ($version->valid() === null) { - $this->_log->addInfo(sprintf('Could not parse version "%s" from update server "%s"', $versionRaw, $updateFile)); - continue; - } - - if (version::gt($version, $this->_currentVersion)) { - if (version::gt($version, $this->_latestVersion)) - $this->_latestVersion = $version; - - $this->_updates[] = [ - 'version' => $version, - 'url' => $updateUrl, - ]; - } - } - - // Sort versions to install - usort($this->_updates, function($a, $b) { - return version::compare($a['version'], $b['version']); - }); - - if ($this->newVersionAvailable()) { - $this->_log->addDebug(sprintf('New version "%s" available', $this->_latestVersion)); - return true; - } else { - $this->_log->addDebug('No new version available'); - return self::NO_UPDATE_AVAILABLE; - } - } - - /** - * Check if a new version is available. - * - * @return bool - */ - public function newVersionAvailable() - { - return version::gt($this->_latestVersion, $this->_currentVersion); - } - - /** - * Download the update - * - * @param string $updateUrl Url where to download from - * @param string $updateFile Path where to save the download - * - * @return bool - */ - protected function _downloadUpdate($updateUrl, $updateFile) { - $this->_log->addInfo(sprintf('Downloading update "%s" to "%s"', $updateUrl, $updateFile)); - $update = @file_get_contents($updateUrl); - - if ($update === false) { - $this->_log->addError(sprintf('Could not download update "%s"!', $updateUrl)); - return false; - } - - $handle = fopen($updateFile, 'w'); - - if (!$handle) { - $this->_log->addError(sprintf('Could not open file handle to save update to "%s"!', $updateFile)); - return false; - } - - if (!fwrite($handle, $update)) { - $this->_log->addError(sprintf('Could not write update to file "%s"!', $updateFile)); - fclose($handle); - return false; - } - - fclose($handle); - - return true; - } - - /** - * Simulate update process. - * - * @param string $updateFile - * - * @return bool - */ - protected function _simulateInstall($updateFile) - { - $this->_log->addNotice('[SIMULATE] Install new version'); - clearstatcache(); - - // Check if zip file could be opened - $zip = zip_open($updateFile); - if (!is_resource($zip)) { - $this->_log->addError(sprintf('Could not open zip file "%s", error: %d', $updateFile, $zip)); - return false; - } - - $i = -1; - $files = []; - $simulateSuccess = true; - - while ($file = zip_read($zip)) { - $i++; - - $filename = zip_entry_name($file); - $foldername = $this->_installDir . dirname($filename); - $absoluteFilename = $this->_installDir . $filename; - - $files[$i] = [ - 'filename' => $filename, - 'foldername' => $foldername, - 'absolute_filename' => $absoluteFilename, - ]; - - $this->_log->addDebug(sprintf('[SIMULATE] Updating file "%s"', $filename)); - - // Check if parent directory is writable - if (!is_dir($foldername)) { - $this->_log->addDebug(sprintf('[SIMULATE] Create directory "%s"', $foldername)); - $files[$i]['parent_folder_exists'] = false; - - $parent = dirname($foldername); - if (!is_writable($parent)) { - $files[$i]['parent_folder_writable'] = false; - - $simulateSuccess = false; - $this->_log->addWarning(sprintf('[SIMULATE] Directory "%s" has to be writeable!', $parent)); - } else { - $files[$i]['parent_folder_writable'] = true; - } - } - - // Skip if entry is a directory - if (substr($filename, -1, 1) == '/') - continue; - - // Read file contents from archive - $contents = zip_entry_read($file, zip_entry_filesize($file)); - if ($contents === false) { - $files[$i]['extractable'] = false; - - $simulateSuccess = false; - $this->_log->addWarning(sprintf('[SIMULATE] Coud not read contents of file "%s" from zip file!', $filename)); - } - - // Write to file - if (file_exists($absoluteFilename)) { - $files[$i]['file_exists'] = true; - if (!is_writable($absoluteFilename)) { - $files[$i]['file_writable'] = false; - - $simulateSuccess = false; - $this->_log->addWarning('[SIMULATE] Could not overwrite "%s"!', $absoluteFilename); - } - } else { - $files[$i]['file_exists'] = false; - - if (is_dir($foldername)) { - if (!is_writable($foldername)) { - $files[$i]['file_writable'] = false; - - $simulateSuccess = false; - $this->_log->addWarning(sprintf('[SIMULATE] The file "%s" could not be created!', $absoluteFilename)); - } else { - $files[$i]['file_writable'] = true; - } - } else { - $files[$i]['file_writable'] = true; - - $this->_log->addDebug(sprintf('[SIMULATE] The file "%s" could be created', $absoluteFilename)); - } - } - - if ($filename == $this->updateScriptName) { - $this->_log->addDebug('[SIMULATE] Update script "%s" found', $absoluteFilename); - $files[$i]['update_script'] = true; - } else { - $files[$i]['update_script'] = false; - } - } - - $this->_simulationResults = $files; - return $simulateSuccess; - } - - /** - * Install update. - * - * @param string $updateFile Path to the update file - * @param bool $simulateInstall Check for directory and file permissions before copying files - * - * @return bool - */ - protected function _install($updateFile, $simulateInstall, $version) { - $this->_log->addNotice(sprintf('Trying to install update "%s"', $updateFile)); - - // Check if install should be simulated - if ($simulateInstall && !$this->_simulateInstall($updateFile)) { - $this->_log->addCritical('Simulation of update process failed!'); - zip_close($zip); - return self::ERROR_SIMULATE; - } - - clearstatcache(); - - // Check if zip file could be opened - $zip = zip_open($updateFile); - if (!is_resource($zip)) { - $this->_log->addError(sprintf('Could not open zip file "%s", error: %d', $updateFile, $zip)); - return false; - } - - // Read every file from archive - while ($file = zip_read($zip)) { - $filename = zip_entry_name($file); - $foldername = $this->_installDir . dirname($filename); - $absoluteFilename = $this->_installDir . $filename; - - $this->_log->addDebug(sprintf('Updating file "%s"', $filename)); - - if (!is_dir($foldername)) { - if (!mkdir($foldername, $this->dirPermissions, true)) { - $this->_log->addError(sprintf('Directory "%s" has to be writeable!', $parent)); - return false; - } - } - - // Skip if entry is a directory - if (substr($filename, -1, 1) == '/') - continue; - - // Read file contents from archive - $contents = zip_entry_read($file, zip_entry_filesize($file)); - - if ($contents === false) { - $this->_log->addError(sprintf('Coud not read zip entry "%s"', $file)); - continue; - } - - // Write to file - if (file_exists($absoluteFilename)) { - if (!is_writable($absoluteFilename)) { - $this->_log->addError('Could not overwrite "%s"!', $absoluteFilename); - - zip_close($zip); - return false; - } - } else { - if (!touch($absoluteFilename)) { - $this->_log->addError(sprintf('[SIMULATE] The file "%s" could not be created!', $absoluteFilename)); - zip_close($zip); - return false; - } - - $this->_log->addDebug(sprintf('File "%s" created', $absoluteFilename)); - } - - $updateHandle = @fopen($absoluteFilename, 'w'); - - if (!$updateHandle) { - $this->_log->addError(sprintf('Could not open file "%s"!', $absoluteFilename)); - zip_close($zip); - return false; - } - - if (!fwrite($updateHandle, $contents)) { - $this->_log->addError(sprintf('Could not write to file "%s"!', $absoluteFilename)); - zip_close($zip); - return false; - } - - fclose($updateHandle); - - //If file is a update script, include - if ($filename == $this->updateScriptName) { - $this->_log->addDebug(sprintf('Try to include update script "%s"', $absoluteFilename)); - require($absoluteFilename); - - $this->_log->addInfo(sprintf('Update script "%s" included!', $absoluteFilename)); - if (!unlink($absoluteFilename)) { - $this->_log->addWarning(sprintf('Could not delete update script "%s"!', $absoluteFilename)); - } - } - } - - zip_close($zip); - - // TODO - $this->_log->addNotice(sprintf('Update "%s" successfully installed', $version)); - - return true; - } - - - /** - * Update to the latest version - * - * @param bool $simulateInstall Check for directory and file permissions before copying files (Default: true) - * @param bool $deleteDownload Delete download after update (Default: true) - * - * @return mixed integer|bool - */ - public function update($simulateInstall = true, $deleteDownload = true) { - $this->_log->addInfo('Trying to perform update'); - - // Check for latest version - if ($this->_latestVersion === null || count($this->_updates) === 0) - $this->checkUpdate(); - - if ($this->_latestVersion === null || count($this->_updates) === 0) { - $this->_log->addError('Could not get latest version from server!'); - return self::ERROR_VERSION_CHECK; - } - - // Check if current version is up to date - if (!$this->newVersionAvailable()) { - $this->_log->addWarning('No update available!'); - return self::NO_UPDATE_AVAILABLE; - } - - foreach ($this->_updates as $update) { - $this->_log->addDebug(sprintf('Update to version "%s"', $update['version'])); - - // Check for temp directory - if (empty($this->_tempDir) || !is_dir($this->_tempDir) || !is_writable($this->_tempDir)) { - $this->_log->addCritical(sprintf('Temporary directory "%s" does not exist or is not writeable!', $this->_tempDir)); - return self::ERROR_TEMP_DIR; - } - - // Check for install directory - if (empty($this->_installDir) || !is_dir($this->_installDir) || !is_writable($this->_installDir)) { - $this->_log->addCritical(sprintf('Install directory "%s" does not exist or is not writeable!', $this->_installDir)); - return self::ERROR_INSTALL_DIR; - } - - $updateFile = $this->_tempDir . $update['version'] . '.zip'; - - // Download update - if (!is_file($updateFile)) { - if (!$this->_downloadUpdate($update['url'], $updateFile)) { - $this->_log->addCritical(sprintf('Failed to download update from "%s" to "%s"!', $update['url'], $updateFile)); - return self::ERROR_DOWNLOAD_UPDATE; - } - - $this->_log->addDebug(sprintf('Latest update downloaded to "%s"', $updateFile)); - } else { - $this->_log->addInfo(sprintf('Latest update already downloaded to "%s"', $updateFile)); - } - - // Install update - $result = $this->_install($updateFile, $simulateInstall, $update['version']); - if ($result === true) { - if ($deleteDownload) { - $this->_log->addDebug(sprintf('Trying to delete update file "%s" after successfull update', $updateFile)); - if (@unlink($updateFile)) { - $this->_log->addInfo(sprintf('Update file "%s" deleted after successfull update', $updateFile)); - } else { - $this->_log->addError(sprintf('Could not delete update file "%s" after successfull update!', $updateFile)); - return self::ERROR_DELETE_TEMP_UPDATE; - } - } - } else { - if ($deleteDownload) { - $this->_log->addDebug(sprintf('Trying to delete update file "%s" after failed update', $updateFile)); - if (@unlink($updateFile)) { - $this->_log->addInfo(sprintf('Update file "%s" deleted after failed update', $updateFile)); - } else { - $this->_log->addError(sprintf('Could not delete update file "%s" after failed update!', $updateFile)); - } - } - - return $result; - } - } - - return true; - } -} diff --git a/core/update/LICENSE.md b/core/old_update/LICENSE.md diff --git a/core/new_updater/index.php b/core/old_update/index.php diff --git a/core/update/update/index.php b/core/old_update/update/index.php diff --git a/core/update/update/update.php b/core/old_update/update/update.php diff --git a/core/update/LICENSE.md b/core/update/LICENSE.md @@ -3,7 +3,7 @@ License PHP AutoUpdate -- -Copyright 2012 - VisualAppeal GbR - www.visualappeal.de +Copyright 2015 - VisualAppeal GbR - www.visualappeal.de Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,4 +15,4 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and -limitations under the License. -\ No newline at end of file +limitations under the License. diff --git a/core/update/update/index.php b/core/update/update/index.php @@ -6,31 +6,41 @@ header("Cache-Control: no-cache, must-revalidate, no-store"); require('update.php'); -$update = new AutoUpdate(true); -$update->currentVersion = 1; //Must be an integer - you can't compare strings -$update->updateUrl = 'http://media.nordgedanken.de/rpicms/server'; //Replace with your server update directory +use \VisualAppeal\AutoUpdate; + +$update = new AutoUpdate($root . '/temp/', $root . '/', 60); +$update->setCurrentVersion('1.0.0'); +$update->setUpdateUrl('http://media.nordgedanken.de/rpicms/server'); + +// Optional: +$update->addLogHandler(new Monolog\Handler\StreamHandler($root . 'core/update/update.log')); + //Check for a new update -$latest = $update->checkUpdate(); -if ($latest !== false) { - if ($latest > $update->currentVersion) { - //Install new update - echo "New Version: ".$update->latestVersionName."<br>"; - echo "Installing Update...<br>"; - if ($update->update()) { - echo "Update successful!"; +if ($update->checkUpdate() === false) + die('Could not check for updates! See log file for details.'); +if ($update->newVersionAvailable()) { + //Install new update + echo 'New Version: ' . $update->getLatestVersion() . '<br>'; + echo 'Installing Updates: <br>'; + echo '<pre>'; + var_dump(array_map(function($version) { + return (string) $version; + }, $update->getVersionsToUpdate())); + echo '</pre>'; + $result = $update->update(); + if ($result === true) { + echo 'Update successful<br>'; + } else { + echo 'Update failed: ' . $result . '!<br>'; + if ($result = AutoUpdate::ERROR_SIMULATE) { + echo '<pre>'; + var_dump($update->getSimulationResults()); + echo '</pre>'; } - else { - echo "Update failed!"; - } - - } - else { - echo "Current Version is up to date"; } -} -else { - echo $update->getLastError(); +} else { + echo 'Current Version is up to date<br>'; } ?> \ No newline at end of file diff --git a/core/update/update/update.php b/core/update/update/update.php @@ -1,4 +1,15 @@ -<?php +<?php namespace VisualAppeal; + +use vierbergenlars\SemVer\version; +use vierbergenlars\SemVer\expression; +use vierbergenlars\SemVer\SemVerException; + +use Desarrolla2\Cache\Cache; +use Desarrolla2\Cache\Adapter\NotCache; + +use Monolog\Logger; +use Monolog\Handler\NullHandler; + ############################### # include files from root dir # @@ -14,354 +25,757 @@ if ($root_3[1] == 'core') { $root = $root_1 . '/' . $root_3[1]; } -/* - * Set the script max execution time + +/** + * Auto update class. */ -ini_set('max_execution_time', 60); +class AutoUpdate +{ + /** + * The latest version. + * + * @var vierbergenlars\SemVer\version + */ + private $_latestVersion = null; -define('UPDATE_DIR_TEMP', $root . '/temp/'); -define('UPDATE_DIR_INSTALL', $root . '/'); + /** + * Updates not yet installed. + * + * @var array + */ + private $_updates = null; -class AutoUpdate { - /* - * Enable logging + /** + * Cache for update requests. + * + * @var Desarrolla2\Cache\Cache */ - private $_log = true; - - /* - * Log file + private $_cache = null; + + /** + * Result of simulated install. + * + * @var array */ - public $logFile = '.updatelog'; - - /* - * The last error + private $_simulationResults = array(); + + /** + * Url to the update folder on the server. + * + * @var string */ - private $_lastError = null; - - /* - * Current version + protected $_updateUrl = 'http://media.nordgedanken.de/rpicms/update/server/'; + + /** + * Version filename on the server. + * + * @var string */ - public $currentVersion = 0; + protected $_updateFile = 'update.json.$this->branch'; /* - * Name of the latest version + * branch on the server */ - public $latestVersionName = ''; - - /* - * The latest version + public $branch = 'stable'; + + /** + * Current version. + * + * @var vierbergenlars\SemVer\version */ - public $latestVersion = null; - - /* - * Url to the latest version of the update + protected $_currentVersion = null; + + /** + * Temporary download directory. + * + * @var string */ - public $latestUpdate = null; - - /* - * Url to the update folder on the server + private $_tempDir = ''; + + /** + * Install directory. + * + * @var string */ - public $updateUrl = 'http://media.nordgedanken.de/rpicms/update/server/'; - - /* - * Version filename on the server + private $_installDir = ''; + + /** + * Create new folders with this privileges. + * + * @var int */ - public $updateIni = 'update.ini.$this->branch'; + public $dirPermissions = 0755; - /* - * branch on the server + /** + * Update script filename. + * + * @var string */ - public $branch = 'stable'; - - /* - * Temporary download directory + public $updateScriptName = '_upgrade.php'; + + /** + * No update available. */ - public $tempDir = UPDATE_DIR_TEMP; - - /* - * Remove temprary directory after installation + const NO_UPDATE_AVAILABLE = 0; + + /** + * Zip file could not be opened. */ - public $removeTempDir = true; - - /* - * Install directory + const ERROR_INVALID_ZIP = 10; + + /** + * Could not check for last version. */ - public $installDir = UPDATE_DIR_INSTALL; - - /* - * Create new folders with this privileges + const ERROR_VERSION_CHECK = 20; + + /** + * Temp directory does not exist or is not writable. */ - public $dirPermissions = 0775; - - /* - * Update script filename + const ERROR_TEMP_DIR = 30; + + /** + * Install directory does not exist or is not writable. */ - public $updateScriptName = '_upgrade.php'; - - /* + const ERROR_INSTALL_DIR = 35; + + /** + * Could not download update. + */ + const ERROR_DOWNLOAD_UPDATE = 40; + + /** + * Could not delete zip update file. + */ + const ERROR_DELETE_TEMP_UPDATE = 50; + + /** + * Error while installing the update. + */ + const ERROR_INSTALL = 60; + + /** + * Error in simulated install. + */ + const ERROR_SIMULATE = 70; + + /** * Create new instance * - * @param bool $log Default: false + * @param string $tempDir + * @param string $installDir + * @param int $maxExecutionTime */ - public function __construct($log = false) { - $this->_log = $log; + public function __construct($tempDir = null, $installDir = null, $maxExecutionTime = 60) { + $this->setTempDir(($tempDir !== null) ? $tempDir : __DIR__ . '/temp/'); + $this->setInstallDir(($installDir !== null) ? $installDir : __DIR__ . '/../../'); + + $this->_latestVersion = new version('0.0.0'); + $this->_currentVersion = new version('0.0.0'); + + // Init cache + $this->_cache = new Cache(new NotCache()); + + // Init logger + $this->_log = new Logger('auto-update'); + $this->_log->pushHandler(new NullHandler()); + + ini_set('max_execution_time', $maxExecutionTime); } - - /* - * Log a message if logging is enabled - * - * @param string $message The message + + /** + * Set the temporary download directory. * - * @return void + * @param string $dir */ - public function log($message) { - if ($this->_log) { - $this->_lastError = $message; - - $log = fopen($this->logFile, 'a'); - - if ($log) { - $message = date('<Y-m-d H:i:s>').$message."\n"; - fputs($log, $message); - fclose($log); + public function setTempDir($dir) + { + // Add slash at the end of the path + if (substr($dir, -1 != '/')) + $dir = $dir . '/'; + + if (!is_dir($dir)) { + if (!mkdir($dir, 0755, true)) { + $this->_log->addCritical(sprintf('Could not create temporary directory "%s"', $dir)); + return; } - else { - die('Could not write log file!'); + } + + $this->_tempDir = $dir; + } + + /** + * Set the install directory. + * + * @param string $dir + */ + public function setInstallDir($dir) + { + // Add slash at the end of the path + if (substr($dir, -1 != '/')) + $dir = $dir . '/'; + + if (!is_dir($dir)) { + if (!mkdir($dir, 0755, true)) { + $this->_log->addCritical(sprintf('Could not create temporary directory "%s"', $dir)); + return; } } + + $this->_installDir = $dir; } - - /* - * Get the latest error + + /** + * Set the update filename. + * + * @param string $updateFile + */ + public function setUpdateFile($updateFile) + { + $this->_updateFile = $updateFile; + } + + /** + * Set the update filename. + * + * @param string $updateUrl + */ + public function setUpdateUrl($updateUrl) + { + $this->_updateUrl = $updateUrl; + } + + /** + * Set the cache component. * - * @return string Last error + * @param Desarrolla2\Cache\Adapter\AdapterInterface $adapter See https://github.com/desarrolla2/Cache + * @param int $ttl Time to live in seconds */ - public function getLastError() { - if (!is_null($this->_lastError)) - return $this->_lastError; - else + public function setCache($adapter, $ttl = 3600) + { + $adapter->setOption('ttl', $ttl); + $this->_cache = new Cache($adapter); + } + + /** + * Set the version of the current installed software. + * + * @param string $currentVersion + * + * @return bool + */ + public function setCurrentVersion($currentVersion) + { + $version = new version($currentVersion); + if ($version->valid() === null) { + $this->_log->addError(sprintf('Invalid current version "%s"', $currentVersion)); return false; + } + + $this->_currentVersion = $version; + return true; + } + + /** + * Add a new logging handler. + * + * @param Monolog\Handler\HandlerInterface $handler See https://github.com/Seldaek/monolog + */ + public function addLogHandler(\Monolog\Handler\HandlerInterface $handler) + { + $this->_log->pushHandler($handler); + } + + /** + * Get the name of the latest version. + * + * @return vierbergenlars\SemVer\version + */ + public function getLatestVersion() + { + return $this->_latestVersion; } - + + /** + * Get an array of versions which will be installed. + * + * @return array + */ + public function getVersionsToUpdate() + { + return array_map(function($update) { + return $update['version']; + }, $this->_updates); + } + + /** + * Get the results of the last simulation. + * + * @return array + */ + public function getSimulationResults() + { + return $this->_simulationResults; + } + + /** + * Remove directory recursively. + * + * @param string $dir + * + * @return void + */ private function _removeDir($dir) { - if (is_dir($dir)) { - $objects = scandir($dir); - foreach ($objects as $object) { - if ($object != "." && $object != "..") { - if (filetype($dir."/".$object) == "dir") - $this->_removeDir($dir."/".$object); - else - unlink($dir."/".$object); - } - } - reset($objects); - rmdir($dir); + $this->_log->addDebug(sprintf('Remove directory "%s"', $dir)); + + if (!is_dir($dir)) { + $this->_log->addWarning(sprintf('"%s" is not a directory!', $dir)); + return false; } + + $objects = array_diff(scandir($dir), array('.', '..')); + foreach ($objects as $object) { + if (is_dir($dir . '/' . $object)) + $this->_removeDir($dir . '/' . $object); + else + unlink($dir . '/' . $object); + } + + return rmdir($dir); } - - /* + + /** * Check for a new version * - * @return string The latest version + * @return int|bool + * true: New version is available + * false: Error while checking for update + * int: Status code (i.e. AutoUpdate::NO_UPDATE_AVAILABLE) */ public function checkUpdate() { - $this->log('Checking for a new update. . .'); - - $updateFile = $this->updateUrl.'/'.$this->updateIni; - - $update = @file_get_contents($updateFile); - if ($update === false) { - $this->log('Could not retrieve update file `'.$updateFile.'`!'); - return false; + $this->_log->addNotice('Checking for a new update...'); + + // Reset previous updates + $this->_latestVersion = new version('0.0.0'); + $this->_updates = []; + + $versions = $this->_cache->get('update-versions'); + + // Check if cache is empty + if ($versions === false) { + $updateFile = $this->_updateUrl . '/' . $this->_updateFile; + $this->_log->addDebug(sprintf('Get new updates from %s', $updateFile)); + + // Read update file from update server + $update = @file_get_contents($updateFile); + if ($update === false) { + $this->_log->addInfo(sprintf('Could not download update file "%s"!', $updateFile)); + return false; + } + + // Parse update file + $updateFileExtension = substr(strrchr($this->_updateFile, '.'), 1); + switch ($updateFileExtension) { + case 'ini': + $versions = parse_ini_string($update, true); + if (!is_array($versions)) { + $this->_log->addInfo('Unable to parse update file!'); + return false; + } + + $versions = array_map(function($block) { + return isset($block['url']) ? $block['url'] : false; + }, $versions); + + break; + case 'json': + $versions = json_decode($update); + + break; + default: + $this->_log->addInfo(sprintf('Unknown file extension "%s"', $updateFileExtension)); + return false; + } + + $this->_cache->set('update-versions', $versions); + } else { + $this->_log->addDebug('Got updates from cache'); } - else { - $versions = parse_ini_string($update, true); - if (is_array($versions)) { - $keyOld = 0; - $latest = 0; - $update = ''; - foreach ($versions as $key => $version) { - if ($key > $keyOld) { - $keyOld = $key; - $latest = $version['version']; - $update = $version['url']; - } - } - - $this->log('New version found `'.$latest.'`.'); - $this->latestVersion = $keyOld; - $this->latestVersionName = $latest; - $this->latestUpdate = $update; - - return $keyOld; + + // Check for latest version + foreach ($versions as $versionRaw => $updateUrl) { + $version = new version($versionRaw); + if ($version->valid() === null) { + $this->_log->addInfo(sprintf('Could not parse version "%s" from update server "%s"', $versionRaw, $updateFile)); + continue; } - else { - $this->log('Unable to parse update file!'); - return false; + + if (version::gt($version, $this->_currentVersion)) { + if (version::gt($version, $this->_latestVersion)) + $this->_latestVersion = $version; + + $this->_updates[] = [ + 'version' => $version, + 'url' => $updateUrl, + ]; } } + + // Sort versions to install + usort($this->_updates, function($a, $b) { + return version::compare($a['version'], $b['version']); + }); + + if ($this->newVersionAvailable()) { + $this->_log->addDebug(sprintf('New version "%s" available', $this->_latestVersion)); + return true; + } else { + $this->_log->addDebug('No new version available'); + return self::NO_UPDATE_AVAILABLE; + } } - - /* + + /** + * Check if a new version is available. + * + * @return bool + */ + public function newVersionAvailable() + { + return version::gt($this->_latestVersion, $this->_currentVersion); + } + + /** * Download the update * * @param string $updateUrl Url where to download from * @param string $updateFile Path where to save the download + * + * @return bool */ - public function downloadUpdate($updateUrl, $updateFile) { - $this->log('Downloading update...'); + protected function _downloadUpdate($updateUrl, $updateFile) { + $this->_log->addInfo(sprintf('Downloading update "%s" to "%s"', $updateUrl, $updateFile)); $update = @file_get_contents($updateUrl); - + if ($update === false) { - $this->log('Could not download update `'.$updateUrl.'`!'); + $this->_log->addError(sprintf('Could not download update "%s"!', $updateUrl)); return false; } - + $handle = fopen($updateFile, 'w'); - + if (!$handle) { - $this->log('Could not save update file `'.$updateFile.'`!'); + $this->_log->addError(sprintf('Could not open file handle to save update to "%s"!', $updateFile)); return false; } - + if (!fwrite($handle, $update)) { - $this->log('Could not write to update file `'.$updateFile.'`!'); + $this->_log->addError(sprintf('Could not write update to file "%s"!', $updateFile)); + fclose($handle); return false; } - + fclose($handle); - + return true; } - - /* - * Install update + + /** + * Simulate update process. + * + * @param string $updateFile + * + * @return bool + */ + protected function _simulateInstall($updateFile) + { + $this->_log->addNotice('[SIMULATE] Install new version'); + clearstatcache(); + + // Check if zip file could be opened + $zip = zip_open($updateFile); + if (!is_resource($zip)) { + $this->_log->addError(sprintf('Could not open zip file "%s", error: %d', $updateFile, $zip)); + return false; + } + + $i = -1; + $files = []; + $simulateSuccess = true; + + while ($file = zip_read($zip)) { + $i++; + + $filename = zip_entry_name($file); + $foldername = $this->_installDir . dirname($filename); + $absoluteFilename = $this->_installDir . $filename; + + $files[$i] = [ + 'filename' => $filename, + 'foldername' => $foldername, + 'absolute_filename' => $absoluteFilename, + ]; + + $this->_log->addDebug(sprintf('[SIMULATE] Updating file "%s"', $filename)); + + // Check if parent directory is writable + if (!is_dir($foldername)) { + $this->_log->addDebug(sprintf('[SIMULATE] Create directory "%s"', $foldername)); + $files[$i]['parent_folder_exists'] = false; + + $parent = dirname($foldername); + if (!is_writable($parent)) { + $files[$i]['parent_folder_writable'] = false; + + $simulateSuccess = false; + $this->_log->addWarning(sprintf('[SIMULATE] Directory "%s" has to be writeable!', $parent)); + } else { + $files[$i]['parent_folder_writable'] = true; + } + } + + // Skip if entry is a directory + if (substr($filename, -1, 1) == '/') + continue; + + // Read file contents from archive + $contents = zip_entry_read($file, zip_entry_filesize($file)); + if ($contents === false) { + $files[$i]['extractable'] = false; + + $simulateSuccess = false; + $this->_log->addWarning(sprintf('[SIMULATE] Coud not read contents of file "%s" from zip file!', $filename)); + } + + // Write to file + if (file_exists($absoluteFilename)) { + $files[$i]['file_exists'] = true; + if (!is_writable($absoluteFilename)) { + $files[$i]['file_writable'] = false; + + $simulateSuccess = false; + $this->_log->addWarning('[SIMULATE] Could not overwrite "%s"!', $absoluteFilename); + } + } else { + $files[$i]['file_exists'] = false; + + if (is_dir($foldername)) { + if (!is_writable($foldername)) { + $files[$i]['file_writable'] = false; + + $simulateSuccess = false; + $this->_log->addWarning(sprintf('[SIMULATE] The file "%s" could not be created!', $absoluteFilename)); + } else { + $files[$i]['file_writable'] = true; + } + } else { + $files[$i]['file_writable'] = true; + + $this->_log->addDebug(sprintf('[SIMULATE] The file "%s" could be created', $absoluteFilename)); + } + } + + if ($filename == $this->updateScriptName) { + $this->_log->addDebug('[SIMULATE] Update script "%s" found', $absoluteFilename); + $files[$i]['update_script'] = true; + } else { + $files[$i]['update_script'] = false; + } + } + + $this->_simulationResults = $files; + return $simulateSuccess; + } + + /** + * Install update. * * @param string $updateFile Path to the update file + * @param bool $simulateInstall Check for directory and file permissions before copying files + * + * @return bool */ - public function install($updateFile) { + protected function _install($updateFile, $simulateInstall, $version) { + $this->_log->addNotice(sprintf('Trying to install update "%s"', $updateFile)); + + // Check if install should be simulated + if ($simulateInstall && !$this->_simulateInstall($updateFile)) { + $this->_log->addCritical('Simulation of update process failed!'); + zip_close($zip); + return self::ERROR_SIMULATE; + } + + clearstatcache(); + + // Check if zip file could be opened $zip = zip_open($updateFile); - - while ($file = zip_read($zip)) { + if (!is_resource($zip)) { + $this->_log->addError(sprintf('Could not open zip file "%s", error: %d', $updateFile, $zip)); + return false; + } + + // Read every file from archive + while ($file = zip_read($zip)) { $filename = zip_entry_name($file); - $foldername = $this->installDir.dirname($filename); - - $this->log('Updating `'.$filename.'`!'); - + $foldername = $this->_installDir . dirname($filename); + $absoluteFilename = $this->_installDir . $filename; + + $this->_log->addDebug(sprintf('Updating file "%s"', $filename)); + if (!is_dir($foldername)) { if (!mkdir($foldername, $this->dirPermissions, true)) { - $this->log('Could not create folder `'.$foldername.'`!'); + $this->_log->addError(sprintf('Directory "%s" has to be writeable!', $parent)); + return false; } } - - $contents = zip_entry_read($file, zip_entry_filesize($file)); - - //Skip if entry is a directory + + // Skip if entry is a directory if (substr($filename, -1, 1) == '/') continue; - - //Write to file - if (file_exists($this->installDir.$filename)) { - if (!is_writable($this->installDir.$filename)) { - $this->log('Could not update `'.$this->installDir.$filename.'`, not writable!'); + + // Read file contents from archive + $contents = zip_entry_read($file, zip_entry_filesize($file)); + + if ($contents === false) { + $this->_log->addError(sprintf('Coud not read zip entry "%s"', $file)); + continue; + } + + // Write to file + if (file_exists($absoluteFilename)) { + if (!is_writable($absoluteFilename)) { + $this->_log->addError('Could not overwrite "%s"!', $absoluteFilename); + + zip_close($zip); return false; } } else { - $this->log('The file `'.$this->installDir.$filename.'`, does not exist!'); - $new_file = fopen($this->installDir.$filename, "w") or $this->log('The file `'.$this->installDir.$filename.'`, could not be created!'); - fclose($new_file); - $this->log('The file `'.$this->installDir.$filename.'`, was succesfully created.'); + if (!touch($absoluteFilename)) { + $this->_log->addError(sprintf('[SIMULATE] The file "%s" could not be created!', $absoluteFilename)); + zip_close($zip); + return false; + } + + $this->_log->addDebug(sprintf('File "%s" created', $absoluteFilename)); } - - $updateHandle = @fopen($this->installDir.$filename, 'w'); - + + $updateHandle = @fopen($absoluteFilename, 'w'); + if (!$updateHandle) { - $this->log('Could not update file `'.$this->installDir.$filename.'`!'); + $this->_log->addError(sprintf('Could not open file "%s"!', $absoluteFilename)); + zip_close($zip); return false; } - + if (!fwrite($updateHandle, $contents)) { - $this->log('Could not write to file `'.$this->installDir.$filename.'`!'); + $this->_log->addError(sprintf('Could not write to file "%s"!', $absoluteFilename)); + zip_close($zip); return false; } - + fclose($updateHandle); - + //If file is a update script, include if ($filename == $this->updateScriptName) { - $this->log('Try to include update script `'.$this->installDir.$filename.'`.'); - require($this->installDir.$filename); - $this->log('Update script `'.$this->installDir.$filename.'` included!'); - unlink($this->installDir.$filename); + $this->_log->addDebug(sprintf('Try to include update script "%s"', $absoluteFilename)); + require($absoluteFilename); + + $this->_log->addInfo(sprintf('Update script "%s" included!', $absoluteFilename)); + if (!unlink($absoluteFilename)) { + $this->_log->addWarning(sprintf('Could not delete update script "%s"!', $absoluteFilename)); + } } } - + zip_close($zip); - - if ($this->removeTempDir) { - $this->log('Temporary directory `'.$this->tempDir.'` deleted.'); - $this->_removeDir($this->tempDir); - } - - $this->log('Update `'.$this->latestVersion.'` installed.'); - + + // TODO + $this->_log->addNotice(sprintf('Update "%s" successfully installed', $version)); + return true; } - - - /* + + + /** * Update to the latest version + * + * @param bool $simulateInstall Check for directory and file permissions before copying files (Default: true) + * @param bool $deleteDownload Delete download after update (Default: true) + * + * @return mixed integer|bool */ - public function update() { - //Check for latest version - if ((is_null($this->latestVersion)) or (is_null($this->latestUpdate))) { + public function update($simulateInstall = true, $deleteDownload = true) { + $this->_log->addInfo('Trying to perform update'); + + // Check for latest version + if ($this->_latestVersion === null || count($this->_updates) === 0) $this->checkUpdate(); + + if ($this->_latestVersion === null || count($this->_updates) === 0) { + $this->_log->addError('Could not get latest version from server!'); + return self::ERROR_VERSION_CHECK; } - - if ((is_null($this->latestVersion)) or (is_null($this->latestUpdate))) { - return false; + + // Check if current version is up to date + if (!$this->newVersionAvailable()) { + $this->_log->addWarning('No update available!'); + return self::NO_UPDATE_AVAILABLE; } - - //Update - if ($this->latestVersion > $this->currentVersion) { - $this->log('Updating...'); - - //Add slash at the end of the path - if ($this->tempDir[strlen($this->tempDir)-1] != '/'); - $this->tempDir = $this->tempDir.'/'; - - if ((!is_dir($this->tempDir)) and (!mkdir($this->tempDir, 0777, true))) { - $this->log('Temporary directory `'.$this->tempDir.'` does not exist and could not be created!'); - return false; + + foreach ($this->_updates as $update) { + $this->_log->addDebug(sprintf('Update to version "%s"', $update['version'])); + + // Check for temp directory + if (empty($this->_tempDir) || !is_dir($this->_tempDir) || !is_writable($this->_tempDir)) { + $this->_log->addCritical(sprintf('Temporary directory "%s" does not exist or is not writeable!', $this->_tempDir)); + return self::ERROR_TEMP_DIR; } - - if (!is_writable($this->tempDir)) { - $this->log('Temporary directory `'.$this->tempDir.'` is not writeable!'); - return false; + + // Check for install directory + if (empty($this->_installDir) || !is_dir($this->_installDir) || !is_writable($this->_installDir)) { + $this->_log->addCritical(sprintf('Install directory "%s" does not exist or is not writeable!', $this->_installDir)); + return self::ERROR_INSTALL_DIR; } - - $updateFile = $this->tempDir.'/'.$this->latestVersion.'.zip'; - $updateUrl = $this->updateUrl.'/'.$this->branch.'/'.$this->latestVersion.'.zip'; - - //Download update + + $updateFile = $this->_tempDir . $update['version'] . '.zip'; + + // Download update if (!is_file($updateFile)) { - if (!$this->downloadUpdate($updateUrl, $updateFile)) { - $this->log('Failed to download update!'); - return false; + if (!$this->_downloadUpdate($update['url'], $updateFile)) { + $this->_log->addCritical(sprintf('Failed to download update from "%s" to "%s"!', $update['url'], $updateFile)); + return self::ERROR_DOWNLOAD_UPDATE; } - - $this->log('Latest update downloaded to `'.$updateFile.'`.'); + + $this->_log->addDebug(sprintf('Latest update downloaded to "%s"', $updateFile)); + } else { + $this->_log->addInfo(sprintf('Latest update already downloaded to "%s"', $updateFile)); } - else { - $this->log('Latest update already downloaded to `'.$updateFile.'`.'); + + // Install update + $result = $this->_install($updateFile, $simulateInstall, $update['version']); + if ($result === true) { + if ($deleteDownload) { + $this->_log->addDebug(sprintf('Trying to delete update file "%s" after successfull update', $updateFile)); + if (@unlink($updateFile)) { + $this->_log->addInfo(sprintf('Update file "%s" deleted after successfull update', $updateFile)); + } else { + $this->_log->addError(sprintf('Could not delete update file "%s" after successfull update!', $updateFile)); + return self::ERROR_DELETE_TEMP_UPDATE; + } + } + } else { + if ($deleteDownload) { + $this->_log->addDebug(sprintf('Trying to delete update file "%s" after failed update', $updateFile)); + if (@unlink($updateFile)) { + $this->_log->addInfo(sprintf('Update file "%s" deleted after failed update', $updateFile)); + } else { + $this->_log->addError(sprintf('Could not delete update file "%s" after failed update!', $updateFile)); + } + } + + return $result; } - - //Unzip - return $this->install($updateFile); - } - else { - $this->log('No update available!'); - return false; } + + return true; } -} -\ No newline at end of file +} diff --git a/themes/jumbotron/update.php b/themes/jumbotron/update.php @@ -24,7 +24,7 @@ if ($root_3[1] == 'core') { $root = $root_1 . '/' . $root_3[1]; } include($root . '/core/config/variables.config.php'); -require($root . '/core/update/update/update.php'); +include($root . '/core/update/update/update.php'); use \VisualAppeal\AutoUpdate; $update = new AutoUpdate($root . '/temp/', $root . '/', 60);