diff --git a/core/Common.php b/core/Common.php index 670c25174f768f4fa9e4e494c2a64f217368b323..858c9fce288c274654624cb8697dbc9e8a1d254c 100644 --- a/core/Common.php +++ b/core/Common.php @@ -128,6 +128,18 @@ class Common (!strncmp(PHP_SAPI, 'cgi', 3) && empty($remoteAddr)); } + /** + * Returns true if the current request is a console command, eg. ./console xx:yy + * @return bool + */ + public static function isRunningConsoleCommand() + { + $searched = '/console'; + $consolePos = strpos($_SERVER['SCRIPT_NAME'], $searched); + $expectedConsolePos = strlen($_SERVER['SCRIPT_NAME']) - strlen($searched); + $isScriptIsConsole = $consolePos == $expectedConsolePos; + return self::isPhpCliMode() && $isScriptIsConsole; + } /* * String operations diff --git a/core/Updater.php b/core/Updater.php index f63131aeb1a2764c0fb37b845d65c1990a21312e..59587cb19b883d22e38ea2c13751e0388e035380 100644 --- a/core/Updater.php +++ b/core/Updater.php @@ -126,9 +126,9 @@ class Updater $this->hasMajorDbUpdate = $this->hasMajorDbUpdate || call_user_func(array($className, 'isMajorUpdate')); } // unfortunately had to extract this query from the Option class - $queries[] = 'UPDATE `' . Common::prefixTable('option') . '` - SET option_value = \'' . $fileVersion . '\' - WHERE option_name = \'' . self::getNameInOptionTable($componentName) . '\';'; + $queries[] = 'UPDATE `' . Common::prefixTable('option') . '` '. + 'SET option_value = \'' . $fileVersion . '\' '. + 'WHERE option_name = \'' . self::getNameInOptionTable($componentName) . '\';'; } return $queries; } diff --git a/core/Url.php b/core/Url.php index c023228fac3fbeca670957155811aaf4ee5c7a21..26e4249ec3e0d05e37acf4dd196a50e280acec52 100644 --- a/core/Url.php +++ b/core/Url.php @@ -469,6 +469,10 @@ class Url } else { echo "Invalid URL to redirect to."; } + + if(Common::isPhpCliMode()) { + die("If you were using a browser, Piwik would redirect you to this URL: $url \n\n"); + } exit; } diff --git a/core/Version.php b/core/Version.php index e07a0f49ad5af3f77780c79c69e4ceb18302efd2..40309b41b4587f0ee655c69dedfc319772b552f1 100644 --- a/core/Version.php +++ b/core/Version.php @@ -21,5 +21,5 @@ final class Version * The current Piwik version. * @var string */ - const VERSION = '2.1-rc5'; + const VERSION = '2.1-rc6'; } diff --git a/plugins/CoreUpdater/Commands/Update.php b/plugins/CoreUpdater/Commands/Update.php new file mode 100644 index 0000000000000000000000000000000000000000..226117df1ef5987897bafb3841c66c469a41cbf1 --- /dev/null +++ b/plugins/CoreUpdater/Commands/Update.php @@ -0,0 +1,61 @@ +<?php +/** + * Piwik - Open source web analytics + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Plugins\CoreUpdater\Commands; + +use Piwik\Plugin\ConsoleCommand; +use Piwik\Plugins\CoreUpdater\Controller; +use Piwik\Plugins\CoreUpdater\NoUpdatesFoundException; +use Piwik\Plugins\UserCountry\LocationProvider; +use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * @package CloudAdmin + */ +class Update extends ConsoleCommand +{ + protected function configure() + { + $this->setName('core:update'); + $this->setDescription('Triggers the upgrades for Piwik core and plugins. Useful after Piwik core files or some plugins were updated to latest files.'); + + $this->addOption('dry-run', null, InputOption::VALUE_NONE, 'Only prints out the SQL requests that would be executed during the upgrade'); + } + + /** + * Execute command like: ./console core:update --dry-run + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $doDryRun = $input->getOption('dry-run'); + + try { + $this->makeUpdate($input, $output, $doDryRun); + } catch(NoUpdatesFoundException $e) { + // Do not fail if no updates were found + $output->writeln("<info>".$e->getMessage()."</info>"); + } catch (\Exception $e) { + // Fail in case of any other error during upgrade + $output->writeln("<error>" . $e->getMessage() . "</error>"); + throw $e; + } + } + + protected function makeUpdate(InputInterface $input, OutputInterface $output, $doDryRun) + { + $this->checkAllRequiredOptionsAreNotEmpty($input); + + $updateController = new Controller(); + echo $updateController->runUpdaterAndExit($doDryRun); + } +} \ No newline at end of file diff --git a/plugins/CoreUpdater/Controller.php b/plugins/CoreUpdater/Controller.php index ab578bad5c308c42e1020415ee39a309e02797ad..f9369896fbbf7927754780138bbbd31a9fd380a5 100644 --- a/plugins/CoreUpdater/Controller.php +++ b/plugins/CoreUpdater/Controller.php @@ -13,6 +13,7 @@ use Piwik\API\Request; use Piwik\ArchiveProcessor\Rules; use Piwik\Common; use Piwik\Config; +use Piwik\DataTable\Renderer\Console; use Piwik\DbHelper; use Piwik\Filechecks; use Piwik\Filesystem; @@ -265,15 +266,19 @@ class Controller extends \Piwik\Plugin\Controller LanguagesManager::setLanguageForSession($language); } - return $this->runUpdaterAndExit(); + try { + return $this->runUpdaterAndExit(); + } catch(NoUpdatesFoundException $e) { + Piwik::redirectToModule('CoreHome'); + } } - protected function runUpdaterAndExit() + public function runUpdaterAndExit($doDryRun = null) { $updater = new Updater(); $componentsWithUpdateFile = CoreUpdater::getComponentUpdates($updater); if (empty($componentsWithUpdateFile)) { - Piwik::redirectToModule('CoreHome'); + throw new NoUpdatesFoundException("Everything is already up to date."); } SettingsServer::setMaxExecutionTime(0); @@ -283,33 +288,44 @@ class Controller extends \Piwik\Plugin\Controller $doneTemplate = '@CoreUpdater/runUpdaterAndExit_done' . $cli; $viewWelcome = new View($welcomeTemplate); $viewDone = new View($doneTemplate); + $doExecuteUpdates = Common::getRequestVar('updateCorePlugins', 0, 'integer') == 1; + + if(is_null($doDryRun)) { + $doDryRun = !$doExecuteUpdates; + } + + if($doDryRun) { + $viewWelcome->queries = $updater->getSqlQueriesToExecute(); + $viewWelcome->isMajor = $updater->hasMajorDbUpdate(); + $this->doWelcomeUpdates($viewWelcome, $componentsWithUpdateFile); + return $viewWelcome->render(); + } + // CLI if (Common::isPhpCliMode()) { $this->doWelcomeUpdates($viewWelcome, $componentsWithUpdateFile); $output = $viewWelcome->render(); - if (!$this->coreError && Piwik::getModule() == 'CoreUpdater') { + // Proceed with upgrade in CLI only if user specifically asked for it, or if running console command + $isUpdateRequested = Common::isRunningConsoleCommand() || Piwik::getModule() == 'CoreUpdater'; + + if (!$this->coreError && $isUpdateRequested) { $this->doExecuteUpdates($viewDone, $updater, $componentsWithUpdateFile); $output .= $viewDone->render(); } - return $output; + } - } else { - if (Common::getRequestVar('updateCorePlugins', 0, 'integer') == 1) { - $this->warningMessages = array(); - $this->doExecuteUpdates($viewDone, $updater, $componentsWithUpdateFile); + // Web + if ($doExecuteUpdates) { + $this->warningMessages = array(); + $this->doExecuteUpdates($viewDone, $updater, $componentsWithUpdateFile); - $this->redirectToDashboardWhenNoError($updater); + $this->redirectToDashboardWhenNoError($updater); - return $viewDone->render(); - } else { - $viewWelcome->queries = $updater->getSqlQueriesToExecute(); - $viewWelcome->isMajor = $updater->hasMajorDbUpdate(); - $this->doWelcomeUpdates($viewWelcome, $componentsWithUpdateFile); - return $viewWelcome->render(); - } + return $viewDone->render(); } + exit; } diff --git a/plugins/CoreUpdater/CoreUpdater.php b/plugins/CoreUpdater/CoreUpdater.php index 4593c42a06cd1471b34baf5bee054e6550cda796..8cde10a7bcb546518ccc4fb15bde15ac40a6a915 100644 --- a/plugins/CoreUpdater/CoreUpdater.php +++ b/plugins/CoreUpdater/CoreUpdater.php @@ -32,10 +32,16 @@ class CoreUpdater extends \Piwik\Plugin $hooks = array( 'Request.dispatchCoreAndPluginUpdatesScreen' => 'dispatch', 'Updater.checkForUpdates' => 'updateCheck', + 'Console.addCommands' => 'addConsoleCommands', ); return $hooks; } + public function addConsoleCommands(&$commands) + { + $commands[] = 'Piwik\Plugins\CoreUpdater\Commands\Update'; + } + public static function updateComponents(Updater $updater, $componentsWithUpdateFile) { $warnings = array(); diff --git a/plugins/CoreUpdater/NoUpdatesFoundException.php b/plugins/CoreUpdater/NoUpdatesFoundException.php new file mode 100644 index 0000000000000000000000000000000000000000..1fd3ef116047ae5b430a245d7d29dadbfb35c685 --- /dev/null +++ b/plugins/CoreUpdater/NoUpdatesFoundException.php @@ -0,0 +1,13 @@ +<?php +/** + * Piwik - Open source web analytics + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ +namespace Piwik\Plugins\CoreUpdater; + +class NoUpdatesFoundException extends \Exception { + +} \ No newline at end of file diff --git a/plugins/CoreUpdater/templates/runUpdaterAndExit_done_cli.twig b/plugins/CoreUpdater/templates/runUpdaterAndExit_done_cli.twig index 9d1a5ae357a17affc198bc3adf1af9afa3624e50..3f6f2cd6f399c9c5f891e98368f859e5a6879e02 100644 --- a/plugins/CoreUpdater/templates/runUpdaterAndExit_done_cli.twig +++ b/plugins/CoreUpdater/templates/runUpdaterAndExit_done_cli.twig @@ -47,7 +47,7 @@ * {{ helpMessage }} {% else %} - {{ 'CoreUpdater_PiwikHasBeenSuccessfullyUpgraded'|translate }} +*** {{ 'CoreUpdater_PiwikHasBeenSuccessfullyUpgraded'|translate }} *** {% endif %} {% endif %} diff --git a/plugins/CoreUpdater/templates/runUpdaterAndExit_welcome_cli.twig b/plugins/CoreUpdater/templates/runUpdaterAndExit_welcome_cli.twig index 7ab452913e542b55e041f0ee4f3977cf7dea89ba..b9126329719ebf773ec456698db8ceb75d70527f 100644 --- a/plugins/CoreUpdater/templates/runUpdaterAndExit_welcome_cli.twig +++ b/plugins/CoreUpdater/templates/runUpdaterAndExit_welcome_cli.twig @@ -22,16 +22,27 @@ {{ 'CoreUpdater_YourDatabaseIsOutOfDate'|translate }} - {% if coreToUpdate %} - {{ 'CoreUpdater_PiwikWillBeUpgradedFromVersionXToVersionY'|translate(current_piwik_version, new_piwik_version) }} - {% endif %} +{% if coreToUpdate %} + {{ 'CoreUpdater_PiwikWillBeUpgradedFromVersionXToVersionY'|translate(current_piwik_version, new_piwik_version) }} +{% endif %} - {% if pluginNamesToUpdate|length > 0 %} - {%- set listOfPlugins %}{{ pluginNamesToUpdate|implode(', ') }}{% endset %} - {{ 'CoreUpdater_TheFollowingPluginsWillBeUpgradedX'|translate( listOfPlugins) }} - {% endif %} +{%- if pluginNamesToUpdate|length > 0 %} + {%- set listOfPlugins %}{{ pluginNamesToUpdate|implode(', ') }}{% endset %} + {{ 'CoreUpdater_TheFollowingPluginsWillBeUpgradedX'|translate( listOfPlugins) }} +{% endif %} + +{# dry run #} +{% if queries is defined and queries is not empty %} +*** Note: this is a Dry Run *** + {% for query in queries %}{{ query|trim }} + {% endfor %} + +*** End of Dry Run *** +{% else %} {{ 'CoreUpdater_TheUpgradeProcessMayTakeAWhilePleaseBePatient'|translate }} +{% endif %} + {% endif %} {% endautoescape %}