/** * Performs maintenance and clean up tasks after an update. * * Called during both a manual and auto-update. * * @return null */ public function actionCleanUp() { $this->requirePostRequest(); $this->requireAjaxRequest(); $data = craft()->request->getRequiredPost('data'); if ($this->_isManualUpdate($data)) { $uid = false; } else { $uid = $data['uid']; } $handle = $this->_getFixedHandle($data); $oldVersion = false; // Grab the old version from the manifest data before we nuke it. $manifestData = UpdateHelper::getManifestData(UpdateHelper::getUnzipFolderFromUID($uid), $handle); if ($manifestData && $handle == 'craft') { $oldVersion = UpdateHelper::getLocalVersionFromManifest($manifestData); } craft()->updates->updateCleanUp($uid, $handle); if ($handle == 'craft' && $oldVersion && version_compare($oldVersion, craft()->getVersion(), '<')) { $returnUrl = UrlHelper::getUrl('whats-new'); } else { $returnUrl = craft()->config->get('postCpLoginRedirect'); } $this->returnJson(array('alive' => true, 'finished' => true, 'returnUrl' => $returnUrl)); }
/** * Attempt to backup each of the update manifest files by copying them to a file with the same name with a .bak * extension. If there is an exception thrown, we attempt to roll back all of the changes. * * @param string $unzipFolder * @param string $handle * * @return bool */ private function _backupFiles($unzipFolder, $handle) { $manifestData = UpdateHelper::getManifestData($unzipFolder, $handle); try { foreach ($manifestData as $row) { if (UpdateHelper::isManifestVersionInfoLine($row)) { continue; } // No need to back up migration files. if (UpdateHelper::isManifestMigrationLine($row)) { continue; } $rowData = explode(';', $row); $filePath = IOHelper::normalizePathSeparators(($handle == 'craft' ? craft()->path->getAppPath() : craft()->path->getPluginsPath() . $handle . '/') . $rowData[0]); // It's a folder if (UpdateHelper::isManifestLineAFolder($filePath)) { $folderPath = UpdateHelper::cleanManifestFolderLine($filePath); if (IOHelper::folderExists($folderPath)) { Craft::log('Backing up folder ' . $folderPath, LogLevel::Info, true); IOHelper::createFolder($folderPath . '.bak'); IOHelper::copyFolder($folderPath . '/', $folderPath . '.bak/'); } } else { // If the file doesn't exist, it's probably a new file. if (IOHelper::fileExists($filePath)) { Craft::log('Backing up file ' . $filePath, LogLevel::Info, true); IOHelper::copyFile($filePath, $filePath . '.bak'); } } } } catch (\Exception $e) { Craft::log('Error updating files: ' . $e->getMessage(), LogLevel::Error); UpdateHelper::rollBackFileChanges($manifestData, $handle); return false; } return true; }
/** * Performs maintenance and clean up tasks after an update. * * Called during both a manual and auto-update. * * @return null */ public function actionCleanUp() { $this->requirePostRequest(); $this->requireAjaxRequest(); $data = craft()->request->getRequiredPost('data'); if ($this->_isManualUpdate($data)) { $uid = false; } else { // If it's not a manual update, make sure they have auto-update permissions. craft()->userSession->requirePermission('performUpdates'); if (!craft()->config->get('allowAutoUpdates')) { $this->returnJson(array('alive' => true, 'errorDetails' => Craft::t('Auto-updating is disabled on this system.'), 'finished' => true)); } $uid = $data['uid']; } $handle = $this->_getFixedHandle($data); $oldVersion = false; // Grab the old version from the manifest data before we nuke it. $manifestData = UpdateHelper::getManifestData(UpdateHelper::getUnzipFolderFromUID($uid)); if ($manifestData) { $oldVersion = UpdateHelper::getLocalVersionFromManifest($manifestData); } craft()->updates->updateCleanUp($uid, $handle); if ($oldVersion && version_compare($oldVersion, craft()->getVersion(), '<')) { $returnUrl = UrlHelper::getUrl('whats-new'); } else { $returnUrl = craft()->userSession->getReturnUrl(); } $this->returnJson(array('alive' => true, 'finished' => true, 'returnUrl' => $returnUrl)); }
/** * @param $uid * @param bool $dbBackupPath * @return array */ public function rollbackUpdate($uid, $dbBackupPath = false) { try { craft()->config->maxPowerCaptain(); if ($dbBackupPath && craft()->config->get('backupDbOnUpdate') && craft()->config->get('restoreDbOnUpdateFailure')) { Craft::log('Rolling back any database changes.', LogLevel::Info, true); UpdateHelper::rollBackDatabaseChanges($dbBackupPath); Craft::log('Done rolling back any database changes.', LogLevel::Info, true); } // If uid !== false, it's an auto-update. if ($uid !== false) { Craft::log('Rolling back any file changes.', LogLevel::Info, true); $manifestData = UpdateHelper::getManifestData(UpdateHelper::getUnzipFolderFromUID($uid)); if ($manifestData) { UpdateHelper::rollBackFileChanges($manifestData); } Craft::log('Done rolling back any file changes.', LogLevel::Info, true); } Craft::log('Finished rolling back changes.', LogLevel::Info, true); return array('success' => true); } catch (\Exception $e) { return array('success' => false, 'message' => $e->getMessage()); } }
/** * @param string $uid * @param string $handle * @param bool $dbBackupPath * * @return array */ public function rollbackUpdate($uid, $handle, $dbBackupPath = false) { try { // Fire an 'onEndUpdate' event and pass in that the update failed. $this->onEndUpdate(new Event($this, array('success' => false))); craft()->config->maxPowerCaptain(); if ($dbBackupPath && craft()->config->get('backupDbOnUpdate') && craft()->config->get('restoreDbOnUpdateFailure')) { Craft::log('Rolling back any database changes.', LogLevel::Info, true); UpdateHelper::rollBackDatabaseChanges($dbBackupPath); Craft::log('Done rolling back any database changes.', LogLevel::Info, true); } // If uid !== false, it's an auto-update. if ($uid !== false) { Craft::log('Rolling back any file changes.', LogLevel::Info, true); $manifestData = UpdateHelper::getManifestData(UpdateHelper::getUnzipFolderFromUID($uid), $handle); if ($manifestData) { UpdateHelper::rollBackFileChanges($manifestData, $handle); } Craft::log('Done rolling back any file changes.', LogLevel::Info, true); } Craft::log('Finished rolling back changes.', LogLevel::Info, true); Craft::log('Taking the site out of maintenance mode.', LogLevel::Info, true); craft()->disableMaintenanceMode(); return array('success' => true); } catch (\Exception $e) { return array('success' => false, 'message' => $e->getMessage()); } }
/** * Performs maintenance and clean up tasks after an update. */ public function actionCleanUp() { $this->requirePostRequest(); $this->requireAjaxRequest(); $data = craft()->request->getRequiredPost('data'); if ($this->_isManualUpdate($data)) { $uid = false; } else { // If it's not a manual update, make sure they have auto-update permissions. craft()->userSession->requirePermission('performUpdates'); $uid = $data['uid']; } $handle = $this->_getFixedHandle($data); $oldVersion = false; // Grab the old version from the manifest data before we nuke it. $manifestData = UpdateHelper::getManifestData(UpdateHelper::getUnzipFolderFromUID($uid)); if ($manifestData) { $oldVersion = UpdateHelper::getLocalVersionFromManifest($manifestData); } $return = craft()->updates->updateCleanUp($uid, $handle); if (!$return['success']) { $this->returnJson(array('error' => $return['message'])); } if ($oldVersion && version_compare($oldVersion, '1.1', '<')) { $returnUrl = UrlHelper::getUrl('whats-new'); } else { $returnUrl = craft()->userSession->getReturnUrl(); } $this->returnJson(array('success' => true, 'finished' => true, 'returnUrl' => $returnUrl)); }
/** * Performs maintenance and clean up tasks after an update. * * Called during both a manual and auto-update. * * @return null * @throws Exception */ public function actionCleanUp() { $this->requirePostRequest(); $this->requireAjaxRequest(); $data = craft()->request->getRequiredPost('data'); if ($this->_isManualUpdate($data)) { $uid = false; } else { $uid = craft()->security->validateData($data['uid']); if (!$uid) { throw new Exception('Could not validate UID'); } } $handle = $this->_getFixedHandle($data); $oldVersion = false; // Grab the old version from the manifest data before we nuke it. $manifestData = UpdateHelper::getManifestData(UpdateHelper::getUnzipFolderFromUID($uid), $handle); if ($manifestData && $handle == 'craft') { $oldVersion = UpdateHelper::getLocalVersionFromManifest($manifestData); } craft()->updates->updateCleanUp($uid, $handle); // New major Craft CMS version? if ($handle == 'craft' && $oldVersion && AppHelper::getMajorVersion($oldVersion) < AppHelper::getMajorVersion(craft()->getVersion())) { $returnUrl = UrlHelper::getUrl('whats-new'); } else { $returnUrl = craft()->config->get('postCpLoginRedirect'); } $this->returnJson(array('alive' => true, 'finished' => true, 'returnUrl' => $returnUrl)); }