Download plugins/CoreUpdater/Controller.php from Leon4gr45/matomo: direct link, hf CLI and curl.
- Browser
- Download file 16.7 kB
-
https://huggingface.co/spaces/Leon4gr45/matomo/resolve/main/plugins/CoreUpdater/Controller.php
- Command line
-
hf download hf://spaces/Leon4gr45/matomo/plugins/CoreUpdater/Controller.php
-
curl -L -o Controller.php https://huggingface.co/spaces/Leon4gr45/matomo/resolve/main/plugins/CoreUpdater/Controller.php
16.7 kB
| /** | |
| * Matomo - free/libre analytics platform | |
| * | |
| * @link https://matomo.org | |
| * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later | |
| */ | |
| namespace Piwik\Plugins\CoreUpdater; | |
| use Exception; | |
| use Piwik\AssetManager; | |
| use Piwik\Common; | |
| use Piwik\Config; | |
| use Piwik\DataTable\Renderer\Json; | |
| use Piwik\DbHelper; | |
| use Piwik\Development; | |
| use Piwik\Filechecks; | |
| use Piwik\FileIntegrity; | |
| use Piwik\Filesystem; | |
| use Piwik\Nonce; | |
| use Piwik\Option; | |
| use Piwik\Piwik; | |
| use Piwik\Plugin\Manager as PluginManager; | |
| use Piwik\Plugins\CoreVue\CoreVue; | |
| use Piwik\Plugins\Marketplace\Plugins; | |
| use Piwik\Request; | |
| use Piwik\SettingsPiwik; | |
| use Piwik\SettingsServer; | |
| use Piwik\Updater as DbUpdater; | |
| use Piwik\Updater\Migration\Db as DbMigration; | |
| use Piwik\Url; | |
| use Piwik\Version; | |
| use Piwik\View; | |
| use Piwik\View\OneClickDone; | |
| class Controller extends \Piwik\Plugin\Controller | |
| { | |
| private $coreError = false; | |
| private $warningMessages = array(); | |
| private $errorMessages = array(); | |
| private $deactivatedPlugins = array(); | |
| /** | |
| * @var Updater | |
| */ | |
| private $updater; | |
| /** | |
| * @var Plugins | |
| */ | |
| private $marketplacePlugins; | |
| public function __construct(Updater $updater, ?Plugins $marketplacePlugins = null) | |
| { | |
| $this->updater = $updater; | |
| $this->marketplacePlugins = $marketplacePlugins; | |
| parent::__construct(); | |
| } | |
| /** | |
| * Return the base.less compiled to css | |
| * | |
| * @return string | |
| */ | |
| public function getUpdaterCss() | |
| { | |
| Common::sendHeader('Content-Type: text/css'); | |
| Common::sendHeader('Cache-Control: max-age=' . (60 * 60)); | |
| $files = array( | |
| 'plugins/Morpheus/stylesheets/base/bootstrap.css', | |
| 'plugins/Morpheus/stylesheets/base/icons.css', | |
| "node_modules/jquery-ui-dist/jquery-ui.theme.min.css", | |
| "node_modules/jquery-ui-dist/jquery-ui.structure.min.css", | |
| 'node_modules/@materializecss/materialize/dist/css/materialize.min.css', | |
| 'plugins/Morpheus/stylesheets/base.less', | |
| 'plugins/Morpheus/stylesheets/general/_forms.less', | |
| 'plugins/Morpheus/stylesheets/simple_structure.css', | |
| 'plugins/CoreHome/stylesheets/jquery.ui.autocomplete.css', | |
| 'plugins/Dashboard/stylesheets/dashboard.less', | |
| 'plugins/CoreUpdater/stylesheets/updateLayout.css', | |
| ); | |
| return AssetManager::compileCustomStylesheets($files); | |
| } | |
| /** | |
| * Return the compiled JavaScript for the updater screen. | |
| * | |
| * @return string | |
| */ | |
| public function getUpdaterJs() | |
| { | |
| Common::sendHeader('Content-Type: application/javascript; charset=UTF-8'); | |
| Common::sendHeader('Cache-Control: max-age=' . (60 * 60)); | |
| $files = array( | |
| "node_modules/jquery/dist/jquery.min.js", | |
| "node_modules/jquery-ui-dist/jquery-ui.min.js", | |
| 'node_modules/@materializecss/materialize/dist/js/materialize.min.js', | |
| "plugins/CoreHome/javascripts/materialize-bc.js", | |
| 'plugins/Morpheus/javascripts/piwikHelper.js', | |
| "plugins/CoreHome/javascripts/broadcast.js", | |
| 'plugins/CoreUpdater/javascripts/updateLayout.js', | |
| 'plugins/Installation/javascripts/installation.js', | |
| ); | |
| CoreVue::addJsFilesTo($files); | |
| $coreHomeUmd = Development::isEnabled() ? 'CoreHome.umd.js' : 'CoreHome.umd.min.js'; | |
| $files[] = "plugins/CoreHome/vue/dist/$coreHomeUmd"; | |
| return AssetManager::compileCustomJs($files); | |
| } | |
| public function newVersionAvailable() | |
| { | |
| Piwik::checkUserHasSuperUserAccess(); | |
| if (!SettingsPiwik::isAutoUpdateEnabled()) { | |
| throw new Exception('Auto updater is disabled'); | |
| } | |
| $this->checkNewVersionIsAvailableOrDie(); | |
| $newVersion = $this->updater->getLatestVersion(); | |
| $view = new View('@CoreUpdater/newVersionAvailable'); | |
| $this->addCustomLogoInfo($view); | |
| $this->setBasicVariablesView($view); | |
| $view->piwik_version = Version::VERSION; | |
| $view->piwik_new_version = $newVersion; | |
| $incompatiblePlugins = $this->getIncompatiblePlugins($newVersion); | |
| $marketplacePlugins = array(); | |
| try { | |
| if (!empty($incompatiblePlugins) && $this->marketplacePlugins) { | |
| $marketplacePlugins = $this->marketplacePlugins->getAllAvailablePluginNames(); | |
| } | |
| } catch (\Exception $e) { | |
| } | |
| $view->marketplacePlugins = $marketplacePlugins; | |
| $view->incompatiblePlugins = $incompatiblePlugins; | |
| $view->piwik_latest_version_url = $this->updater->getArchiveUrl($newVersion); | |
| $view->can_auto_update = Filechecks::canAutoUpdate(); | |
| $view->makeWritableCommands = Filechecks::getAutoUpdateMakeWritableMessage(); | |
| $view->nonce = Nonce::getNonce('oneClickUpdate'); | |
| return $view->render(); | |
| } | |
| public function oneClickUpdate() | |
| { | |
| Piwik::checkUserHasSuperUserAccess(); | |
| if (!SettingsPiwik::isAutoUpdateEnabled()) { | |
| throw new Exception('Auto updater is disabled'); | |
| } | |
| Nonce::checkNonce('oneClickUpdate'); | |
| $view = new OneClickDone(Piwik::getCurrentUserTokenAuth()); | |
| $useHttps = Common::getRequestVar('https', 1, 'int'); | |
| try { | |
| $messages = $this->updater->updatePiwik($useHttps); | |
| $this->refreshUpdateDetailsToken(); | |
| } catch (ArchiveDownloadException $e) { | |
| $view->httpsFail = $useHttps; | |
| $view->error = $e->getMessage(); | |
| $messages = $e->getUpdateLogMessages(); | |
| } catch (UpdaterException $e) { | |
| $view->error = $e->getMessage(); | |
| $messages = $e->getUpdateLogMessages(); | |
| } | |
| $view->feedbackMessages = $messages; | |
| $result = $view->render(); | |
| return $result; | |
| } | |
| public function oneClickUpdatePartTwo() | |
| { | |
| if (!SettingsPiwik::isAutoUpdateEnabled()) { | |
| throw new Exception('Auto updater is disabled'); | |
| } | |
| Json::sendHeaderJSON(); | |
| $task = "Couldn't update Marketplace plugins."; | |
| $nonce = Common::getRequestVar('nonce', '', 'string'); | |
| if (empty($nonce)) { | |
| return json_encode(['No token. ' . $task]); | |
| } | |
| $value = Option::get('NonceOneClickUpdatePartTwo'); | |
| if (empty($value)) { | |
| return json_encode(['Invalid token. ' . $task]); | |
| } | |
| $value = json_decode($value, true); | |
| if ( | |
| empty($value['nonce']) | |
| || empty($value['ttl']) | |
| || time() > (int) $value['ttl'] | |
| || $nonce !== $value['nonce'] | |
| ) { | |
| return json_encode(['Invalid nonce or nonce expired. ' . $task]); | |
| } | |
| try { | |
| $messages = $this->updater->oneClickUpdatePartTwo(); | |
| } catch (UpdaterException $e) { | |
| $messages = $e->getUpdateLogMessages(); | |
| $messages[] = $e->getMessage(); | |
| } catch (Exception $e) { | |
| $messages = [$e->getMessage()]; | |
| } | |
| return json_encode($messages); | |
| } | |
| public function oneClickResults() | |
| { | |
| if (!SettingsPiwik::isAutoUpdateEnabled()) { | |
| throw new Exception('Auto updater is disabled'); | |
| } | |
| $httpsFail = (bool) Common::getRequestVar('httpsFail', 0, 'int', $_POST); | |
| $error = Common::getRequestVar('error', '', 'string', $_POST); | |
| if ($httpsFail) { | |
| $view = new View('@CoreUpdater/updateHttpsError'); | |
| $view->nonce = Nonce::getNonce('oneClickUpdate'); | |
| $view->error = $error; | |
| } elseif ($error) { | |
| $view = new View('@CoreUpdater/updateHttpError'); | |
| $view->error = $error; | |
| } else { | |
| $updateDetailsToken = null; | |
| if (Piwik::hasUserSuperUserAccess()) { | |
| $updateDetailsToken = $this->getUpdateDetailsToken(); | |
| if ($updateDetailsToken === null) { | |
| $updateDetailsToken = $this->refreshUpdateDetailsToken(); | |
| } | |
| } | |
| $runUpdaterUrl = Url::getCurrentUrlWithoutQueryString(); | |
| if ($updateDetailsToken !== null) { | |
| $runUpdaterUrl .= '?module=CoreUpdater&updateDetailsToken=' . urlencode($updateDetailsToken); | |
| } | |
| $view = new View('@CoreUpdater/updateSuccess'); | |
| $view->runUpdaterUrl = $runUpdaterUrl; | |
| } | |
| $messages = safe_unserialize(Request::fromPost()->getStringParameter('messages', '')); | |
| if (!is_array($messages)) { | |
| $messages = array(); | |
| } | |
| $view->feedbackMessages = $messages; | |
| $this->addCustomLogoInfo($view); | |
| $this->setBasicVariablesView($view); | |
| return $view->render(); | |
| } | |
| protected function redirectToDashboardWhenNoError(DbUpdater $updater) | |
| { | |
| if ( | |
| count($updater->getSqlQueriesToExecute()) == 1 | |
| && !$this->coreError | |
| && empty($this->warningMessages) | |
| && empty($this->errorMessages) | |
| && empty($this->deactivatedPlugins) | |
| ) { | |
| Piwik::redirectToModule('CoreHome'); | |
| } | |
| } | |
| private function checkNewVersionIsAvailableOrDie() | |
| { | |
| if (!$this->updater->isNewVersionAvailable()) { | |
| throw new Exception(Piwik::translate('CoreUpdater_ExceptionAlreadyLatestVersion', Version::VERSION)); | |
| } | |
| } | |
| public function index() | |
| { | |
| try { | |
| return $this->runUpdaterAndExit(); | |
| } catch (NoUpdatesFoundException $e) { | |
| Piwik::redirectToModule('CoreHome'); | |
| } | |
| } | |
| public function runUpdaterAndExit($doDryRun = null) | |
| { | |
| if (!SettingsPiwik::isAutoUpdateEnabled()) { | |
| throw new Exception('Auto updater is disabled'); | |
| } | |
| $updater = new DbUpdater(); | |
| $componentsWithUpdateFile = $updater->getComponentUpdates(); | |
| if (empty($componentsWithUpdateFile)) { | |
| // remove token if updater screen is not displayed | |
| $this->removeUpdateDetailsToken(); | |
| throw new NoUpdatesFoundException("Everything is already up to date."); | |
| } | |
| SettingsServer::setMaxExecutionTime(0); | |
| $welcomeTemplate = '@CoreUpdater/runUpdaterAndExit_welcome'; | |
| $doneTemplate = '@CoreUpdater/runUpdaterAndExit_done'; | |
| $viewWelcome = new View($welcomeTemplate); | |
| $this->addCustomLogoInfo($viewWelcome); | |
| $this->setBasicVariablesView($viewWelcome); | |
| $viewDone = new View($doneTemplate); | |
| $this->addCustomLogoInfo($viewDone); | |
| $this->setBasicVariablesView($viewDone); | |
| $doExecuteUpdates = Request::fromRequest()->getBoolParameter('updateCorePlugins', false); | |
| if (is_null($doDryRun)) { | |
| $doDryRun = !$doExecuteUpdates; | |
| } | |
| if ($doDryRun) { | |
| $migrations = $updater->getSqlQueriesToExecute(); | |
| $queryCount = count($migrations); | |
| $migrations = $this->groupMigrations($migrations); | |
| $viewWelcome->migrations = $migrations; | |
| $viewWelcome->queryCount = $queryCount; | |
| $viewWelcome->isMajor = $updater->hasMajorDbUpdate(); | |
| $viewWelcome->showUpdateDetails = $this->checkUpdateDetailsToken(); | |
| $this->doWelcomeUpdates($viewWelcome, $componentsWithUpdateFile); | |
| return $viewWelcome->render(); | |
| } | |
| // Web | |
| if ($doExecuteUpdates) { | |
| $this->warningMessages = []; | |
| $this->doExecuteUpdates($viewDone, $updater, $componentsWithUpdateFile); | |
| $this->removeUpdateDetailsToken(); | |
| $this->redirectToDashboardWhenNoError($updater); | |
| return $viewDone->render(); | |
| } | |
| exit; | |
| } | |
| private function groupMigrations($migrations) | |
| { | |
| $result = []; | |
| $group = null; | |
| foreach ($migrations as $migration) { | |
| $type = $migration instanceof DbMigration ? 'sql' : 'command'; | |
| if ( | |
| $group === null | |
| || $type != $group['type'] | |
| ) { | |
| $group = [ | |
| 'type' => $type, | |
| 'migrations' => [], | |
| ]; | |
| $result[] = $group; | |
| } | |
| $result[count($result) - 1]['migrations'][] = $migration; | |
| } | |
| return $result; | |
| } | |
| private function doWelcomeUpdates($view, $componentsWithUpdateFile) | |
| { | |
| $view->new_piwik_version = Version::VERSION; | |
| $view->commandUpgradePiwik = "php " . Filesystem::getPathToPiwikRoot() . "/console core:update"; | |
| $instanceId = SettingsPiwik::getPiwikInstanceId(); | |
| if ($instanceId) { | |
| $view->commandUpgradePiwik .= ' --matomo-domain="' . $instanceId . '"'; | |
| } | |
| $pluginNamesToUpdate = array(); | |
| $dimensionsToUpdate = array(); | |
| $coreToUpdate = false; | |
| // handle case of existing database with no tables | |
| if (!DbHelper::isInstalled()) { | |
| $this->errorMessages[] = Piwik::translate('CoreUpdater_EmptyDatabaseError', Config::getInstance()->database['dbname']); | |
| $this->coreError = true; | |
| $currentVersion = 'N/A'; | |
| } else { | |
| $this->errorMessages = array(); | |
| try { | |
| $currentVersion = Option::get('version_core'); | |
| } catch (Exception $e) { | |
| $currentVersion = '<= 0.2.9'; | |
| } | |
| foreach ($componentsWithUpdateFile as $name => $filenames) { | |
| if ($name == 'core') { | |
| $coreToUpdate = true; | |
| } elseif (0 === strpos($name, 'log_')) { | |
| $dimensionsToUpdate[] = $name; | |
| } else { | |
| $pluginNamesToUpdate[] = $name; | |
| } | |
| } | |
| } | |
| // check file integrity | |
| [$success, $messages] = FileIntegrity::getFileIntegrityInformation(); | |
| if (!$success) { | |
| $this->warningMessages[] = Piwik::translate('General_FileIntegrityWarning'); | |
| } | |
| if (count($messages) > 0) { | |
| $this->warningMessages = array_merge($this->warningMessages, $messages); | |
| } | |
| Filesystem::deleteAllCacheOnUpdate(); | |
| sort($dimensionsToUpdate); | |
| $view->coreError = $this->coreError; | |
| $view->warningMessages = $this->warningMessages; | |
| $view->errorMessages = $this->errorMessages; | |
| $view->current_piwik_version = $currentVersion; | |
| $view->pluginNamesToUpdate = $pluginNamesToUpdate; | |
| $view->dimensionsToUpdate = $dimensionsToUpdate; | |
| $view->coreToUpdate = $coreToUpdate; | |
| } | |
| private function doExecuteUpdates($view, DbUpdater $updater, $componentsWithUpdateFile) | |
| { | |
| $result = $updater->updateComponents($componentsWithUpdateFile); | |
| $this->coreError = $result['coreError']; | |
| $this->warningMessages = $result['warnings']; | |
| $this->errorMessages = $result['errors']; | |
| $this->deactivatedPlugins = $result['deactivatedPlugins']; | |
| $view->coreError = $this->coreError; | |
| $view->warningMessages = $this->warningMessages; | |
| $view->errorMessages = $this->errorMessages; | |
| $view->deactivatedPlugins = $this->deactivatedPlugins; | |
| } | |
| private function getIncompatiblePlugins($piwikVersion) | |
| { | |
| return PluginManager::getInstance()->getIncompatiblePlugins($piwikVersion); | |
| } | |
| private function checkUpdateDetailsToken(): bool | |
| { | |
| $config = Config::getInstance(); | |
| if (empty($config->General['update_details_token'])) { | |
| return false; | |
| } | |
| return $config->General['update_details_token'] === Request::fromRequest()->getStringParameter('updateDetailsToken', ''); | |
| } | |
| private function refreshUpdateDetailsToken(): string | |
| { | |
| $config = Config::getInstance(); | |
| $token = Common::generateUniqId(); | |
| $config->General['update_details_token'] = $token; | |
| $config->forceSave(); | |
| return $token; | |
| } | |
| private function getUpdateDetailsToken(): ?string | |
| { | |
| $config = Config::getInstance(); | |
| if (empty($config->General['update_details_token'])) { | |
| return null; | |
| } | |
| return $config->General['update_details_token']; | |
| } | |
| private function removeUpdateDetailsToken(): void | |
| { | |
| $config = Config::getInstance(); | |
| if (empty($config->General['update_details_token'])) { | |
| return; | |
| } | |
| unset($config->General['update_details_token']); | |
| $config->forceSave(); | |
| } | |
| } | |