Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorThomas Steur <tsteur@users.noreply.github.com>2016-11-15 04:03:59 +0300
committerMatthieu Aubry <mattab@users.noreply.github.com>2016-11-15 04:03:59 +0300
commit587cc39e0362719332d410b7a4d5ddcc68788eeb (patch)
treec982c369cdda542c3a4de08be11c893e5364838c /core
parent64314b26dbc6619d535002bdb79b9e55d1fc87db (diff)
Update Marketplace to work with new API (#10799)
* starting to port marketplace to piwik 3 * updating tests * fix translation key * fix various issues * use material select * fix plugin upload * deprecate license_homepage plugin metadata and link to a LICENSE[.md|.txt] file if found (#10756) * deprecate license_homepage plugin metadata, and link to a LICENSE[.md|.txt] file if found * Make license view HTML only without menu * fix tests and update * fix some links did not work * we need to show warnings even when plugin is installed, not only when activated. otherwise it is not clear why something is not downloadable * fix install was not working * improved responsiveness of marketplace * fix more tests * fix search was shown when only a few plugins are there * fix ui tests * fix some translations * fix tests and remove duplicated test
Diffstat (limited to 'core')
-rw-r--r--core/API/DocumentationGenerator.php2
-rw-r--r--core/Http.php15
-rw-r--r--core/Notification.php7
-rw-r--r--core/Plugin.php2
-rw-r--r--core/Plugin/ControllerAdmin.php47
-rw-r--r--core/Plugin/Dependency.php81
-rw-r--r--core/Plugin/Manager.php9
-rw-r--r--core/Plugin/MetadataLoader.php37
-rw-r--r--core/Plugin/ReleaseChannels.php12
-rw-r--r--core/ProxyHttp.php12
-rw-r--r--core/SettingsPiwik.php37
-rwxr-xr-xcore/Twig.php26
-rw-r--r--core/UpdateCheck.php7
-rw-r--r--core/UpdateCheck/ReleaseChannel.php9
-rw-r--r--core/Updates/3.0.0-b2.php24
-rw-r--r--core/Updates/3.0.0-b3.php65
-rw-r--r--core/View.php2
17 files changed, 342 insertions, 52 deletions
diff --git a/core/API/DocumentationGenerator.php b/core/API/DocumentationGenerator.php
index 456e487f00..e738c6c4c8 100644
--- a/core/API/DocumentationGenerator.php
+++ b/core/API/DocumentationGenerator.php
@@ -285,6 +285,8 @@ class DocumentationGenerator
'addGoal',
'updateGoal',
'deleteGoal',
+ //Marketplace
+ 'deleteLicenseKey'
);
if (in_array($methodName, $doNotPrintExampleForTheseMethods)) {
diff --git a/core/Http.php b/core/Http.php
index 7e7602c20e..373c4815d9 100644
--- a/core/Http.php
+++ b/core/Http.php
@@ -94,17 +94,24 @@ class Http
$httpPassword = null)
{
// create output file
- $file = null;
+ $file = self::ensureDestinationDirectoryExists($destinationPath);
+
+ $acceptLanguage = $acceptLanguage ? 'Accept-Language: ' . $acceptLanguage : '';
+ return self::sendHttpRequestBy(self::getTransportMethod(), $aUrl, $timeout, $userAgent, $destinationPath, $file, $followDepth, $acceptLanguage, $acceptInvalidSslCertificate = false, $byteRange, $getExtendedInfo, $httpMethod, $httpUsername, $httpPassword);
+ }
+
+ public static function ensureDestinationDirectoryExists($destinationPath)
+ {
if ($destinationPath) {
- // Ensure destination directory exists
Filesystem::mkdir(dirname($destinationPath));
if (($file = @fopen($destinationPath, 'wb')) === false || !is_resource($file)) {
throw new Exception('Error while creating the file: ' . $destinationPath);
}
+
+ return $file;
}
- $acceptLanguage = $acceptLanguage ? 'Accept-Language: ' . $acceptLanguage : '';
- return self::sendHttpRequestBy(self::getTransportMethod(), $aUrl, $timeout, $userAgent, $destinationPath, $file, $followDepth, $acceptLanguage, $acceptInvalidSslCertificate = false, $byteRange, $getExtendedInfo, $httpMethod, $httpUsername, $httpPassword);
+ return null;
}
/**
diff --git a/core/Notification.php b/core/Notification.php
index b7c576eba0..7672263ab3 100644
--- a/core/Notification.php
+++ b/core/Notification.php
@@ -81,6 +81,13 @@ class Notification
const FLAG_NO_CLEAR = 1;
/**
+ * If this flag is applied, a close icon will be displayed.
+ *
+ * See {@link $flags}.
+ */
+ const FLAG_CLEAR = 0;
+
+ /**
* Notifications of this type will be displayed for a few seconds and then faded out.
*/
const TYPE_TOAST = 'toast';
diff --git a/core/Plugin.php b/core/Plugin.php
index 82ef4f2fec..949895b70e 100644
--- a/core/Plugin.php
+++ b/core/Plugin.php
@@ -42,7 +42,6 @@ require_once PIWIK_INCLUDE_PATH . '/core/Plugin/MetadataLoader.php';
* - **homepage**: The URL to the plugin's website.
* - **authors**: A list of author arrays with keys for 'name', 'email' and 'homepage'
* - **license**: The license the code uses (eg, GPL, MIT, etc.).
- * - **license_homepage**: URL to website describing the license used.
* - **version**: The plugin version (eg, 1.0.1).
* - **theme**: `true` or `false`. If `true`, the plugin will be treated as a theme.
*
@@ -184,7 +183,6 @@ class Plugin
* - 'author_homepage' => string // author homepage URL (or email "mailto:youremail@example.org")
* - 'homepage' => string // plugin homepage URL
* - 'license' => string // plugin license
- * - 'license_homepage' => string // license homepage URL
* - 'version' => string // plugin version number; examples and 3rd party plugins must not use Version::VERSION; 3rd party plugins must increment the version number with each plugin release
* - 'theme' => bool // Whether this plugin is a theme (a theme is a plugin, but a plugin is not necessarily a theme)
*
diff --git a/core/Plugin/ControllerAdmin.php b/core/Plugin/ControllerAdmin.php
index 092a963b8a..73bf47d32b 100644
--- a/core/Plugin/ControllerAdmin.php
+++ b/core/Plugin/ControllerAdmin.php
@@ -10,12 +10,14 @@ namespace Piwik\Plugin;
use Piwik\Config as PiwikConfig;
use Piwik\Config;
+use Piwik\Container\StaticContainer;
use Piwik\Development;
use Piwik\Menu\MenuAdmin;
use Piwik\Menu\MenuTop;
use Piwik\Notification;
use Piwik\Notification\Manager as NotificationManager;
use Piwik\Piwik;
+use Piwik\Plugins\Marketplace\Marketplace;
use Piwik\Tracker\TrackerConfig;
use Piwik\Url;
use Piwik\Version;
@@ -40,6 +42,50 @@ abstract class ControllerAdmin extends Controller
}
}
+ private static function notifyAnyInvalidLicense()
+ {
+ if (!Marketplace::isMarketplaceEnabled()) {
+ return;
+ }
+
+ if (Piwik::isUserIsAnonymous()) {
+ return;
+ }
+
+ if (!Piwik::isUserHasSomeAdminAccess()) {
+ return;
+ }
+
+ $expired = StaticContainer::get('Piwik\Plugins\Marketplace\Plugins\InvalidLicenses');
+
+ $messageLicenseMissing = $expired->getMessageNoLicense();
+ if (!empty($messageLicenseMissing)) {
+ $notification = new Notification($messageLicenseMissing);
+ $notification->raw = true;
+ $notification->context = Notification::CONTEXT_ERROR;
+ $notification->title = Piwik::translate('Marketplace_LicenseMissing');
+ Notification\Manager::notify('ControllerAdmin_LicenseMissingWarning', $notification);
+ }
+
+ $messageExceeded = $expired->getMessageExceededLicenses();
+ if (!empty($messageExceeded)) {
+ $notification = new Notification($messageExceeded);
+ $notification->raw = true;
+ $notification->context = Notification::CONTEXT_WARNING;
+ $notification->title = Piwik::translate('Marketplace_LicenseExceeded');
+ Notification\Manager::notify('ControllerAdmin_LicenseExceededWarning', $notification);
+ }
+
+ $messageExpired = $expired->getMessageExpiredLicenses();
+ if (!empty($messageExpired)) {
+ $notification = new Notification($messageExpired);
+ $notification->raw = true;
+ $notification->context = Notification::CONTEXT_WARNING;
+ $notification->title = Piwik::translate('Marketplace_LicenseExpired');
+ Notification\Manager::notify('ControllerAdmin_LicenseExpiredWarning', $notification);
+ }
+ }
+
private static function notifyAnyInvalidPlugin()
{
$missingPlugins = \Piwik\Plugin\Manager::getInstance()->getMissingPlugins();
@@ -272,6 +318,7 @@ abstract class ControllerAdmin extends Controller
$view->isSuperUser = Piwik::hasUserSuperUserAccess();
+ self::notifyAnyInvalidLicense();
self::notifyAnyInvalidPlugin();
self::notifyWhenPhpVersionIsEOL();
self::notifyWhenPhpVersionIsNotCompatibleWithNextMajorPiwik();
diff --git a/core/Plugin/Dependency.php b/core/Plugin/Dependency.php
index e1ccc1c92c..127d32eabf 100644
--- a/core/Plugin/Dependency.php
+++ b/core/Plugin/Dependency.php
@@ -8,7 +8,9 @@
*/
namespace Piwik\Plugin;
+use Composer\Semver\VersionParser;
use Piwik\Plugin\Manager as PluginManager;
+use Piwik\Plugins\Marketplace\Environment;
use Piwik\Version;
/**
@@ -17,10 +19,18 @@ use Piwik\Version;
class Dependency
{
private $piwikVersion;
+ private $phpVersion;
public function __construct()
{
$this->setPiwikVersion(Version::VERSION);
+ $this->setPhpVersion(PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION . '.' . PHP_RELEASE_VERSION);
+ }
+
+ public function setEnvironment(Environment $environment)
+ {
+ $this->setPiwikVersion($environment->getPiwikVersion());
+ $this->setPhpVersion($environment->getPhpVersion());
}
public function getMissingDependencies($requires)
@@ -50,40 +60,91 @@ class Dependency
public function getMissingVersions($currentVersion, $requiredVersion)
{
- $currentVersion = trim($currentVersion);
- $requiredVersions = explode(',', (string) $requiredVersion);
+ $currentVersion = trim($currentVersion);
$missingVersions = array();
+ if (empty($currentVersion)) {
+ if (!empty($requiredVersion)) {
+ $missingVersions[] = (string) $requiredVersion;
+ }
+
+ return $missingVersions;
+ }
+
+ $requiredVersion = $this->makeVersionBackwardsCompatibleIfNoComparisonDefined($requiredVersion);
+
+ $version = new VersionParser();
+ $constraintsExisting = $version->parseConstraints($currentVersion);
+
+ $requiredVersions = explode(',', (string) $requiredVersion);
+
foreach ($requiredVersions as $required) {
- $comparison = '>=';
- $required = trim($required);
+ $required = trim($required);
- if (preg_match('{^(<>|!=|>=?|<=?|==?)\s*(.*)}', $required, $matches)) {
- $required = $matches[2];
- $comparison = trim($matches[1]);
+ if (empty($required)) {
+ continue;
}
- if (false === version_compare($currentVersion, $required, $comparison)) {
- $missingVersions[] = $comparison . $required;
+ $required = $this->makeVersionBackwardsCompatibleIfNoComparisonDefined($required);
+ $constraintRequired = $version->parseConstraints($required);
+
+ if (!$constraintRequired->matches($constraintsExisting)) {
+ $missingVersions[] = $required;
}
}
return $missingVersions;
}
+ private function makeVersionBackwardsCompatibleIfNoComparisonDefined($version)
+ {
+ if (!empty($version) && preg_match('/^(\d+)\.(\d+)/', $version)) {
+ // TODO: we should remove this from piwik 3. To stay BC we add >= if no >= is defined yet
+ $version = '>=' . $version;
+ }
+
+ return $version;
+ }
+
public function setPiwikVersion($piwikVersion)
{
$this->piwikVersion = $piwikVersion;
}
+ public function setPhpVersion($phpVersion)
+ {
+ $this->phpVersion = $phpVersion;
+ }
+
+ public function hasDependencyToDisabledPlugin($requires)
+ {
+ if (empty($requires)) {
+ return false;
+ }
+
+ foreach ($requires as $name => $requiredVersion) {
+ $nameLower = strtolower($name);
+ $isPluginRequire = !in_array($nameLower, array('piwik', 'php'));
+ if ($isPluginRequire) {
+ // we do not check version, only whether it's activated. Everything that is not piwik or php is assumed
+ // a plugin so far.
+ if (!PluginManager::getInstance()->isPluginActivated($name)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
private function getCurrentVersion($name)
{
switch (strtolower($name)) {
case 'piwik':
return $this->piwikVersion;
case 'php':
- return PHP_VERSION;
+ return $this->phpVersion;
default:
try {
$pluginNames = PluginManager::getAllPluginsNames();
diff --git a/core/Plugin/Manager.php b/core/Plugin/Manager.php
index 9455f06c0b..846de60086 100644
--- a/core/Plugin/Manager.php
+++ b/core/Plugin/Manager.php
@@ -658,7 +658,12 @@ class Manager
|| $name == self::DEFAULT_THEME;
}
- protected function isPluginThirdPartyAndBogus($pluginName)
+ /**
+ * @param $pluginName
+ * @return bool
+ * @ignore
+ */
+ public function isPluginThirdPartyAndBogus($pluginName)
{
if ($this->isPluginBundledWithCore($pluginName)) {
return false;
@@ -915,7 +920,7 @@ class Manager
public function isValidPluginName($pluginName)
{
- return (bool) preg_match('/^[a-zA-Z]([a-zA-Z0-9]*)$/D', $pluginName);
+ return (bool) preg_match('/^[a-zA-Z]([a-zA-Z0-9_]*)$/D', $pluginName);
}
/**
diff --git a/core/Plugin/MetadataLoader.php b/core/Plugin/MetadataLoader.php
index 5a6b2617e6..bde849ff7e 100644
--- a/core/Plugin/MetadataLoader.php
+++ b/core/Plugin/MetadataLoader.php
@@ -57,6 +57,12 @@ class MetadataLoader
unset($plugin['description']);
}
+ // look for a license file
+ $licenseFile = $this->getPathToLicenseFile();
+ if(!empty($licenseFile)) {
+ $plugin['license_file'] = $licenseFile;
+ }
+
return array_merge(
$defaults,
$plugin
@@ -78,7 +84,6 @@ class MetadataLoader
'homepage' => 'http://piwik.org/',
'authors' => array(array('name' => 'Piwik', 'homepage' => 'http://piwik.org/')),
'license' => 'GPL v3+',
- 'license_homepage' => 'http://www.gnu.org/licenses/gpl.html',
'version' => Version::VERSION,
'theme' => false,
'require' => array()
@@ -87,7 +92,7 @@ class MetadataLoader
private function loadPluginInfoJson()
{
- $path = \Piwik\Plugin\Manager::getPluginsDirectory() . $this->pluginName . '/' . self::PLUGIN_JSON_FILENAME;
+ $path = $this->getPathToPluginFolder() . '/' . self::PLUGIN_JSON_FILENAME;
return $this->loadJsonMetadata($path);
}
@@ -111,4 +116,32 @@ class MetadataLoader
return $info;
}
+
+ /**
+ * @return string
+ */
+ private function getPathToPluginFolder()
+ {
+ return \Piwik\Plugin\Manager::getPluginsDirectory() . $this->pluginName;
+ }
+
+ /**
+ * @return null|string
+ */
+ public function getPathToLicenseFile()
+ {
+ $prefixPath = $this->getPathToPluginFolder() . '/';
+ $licenseFiles = array(
+ 'LICENSE',
+ 'LICENSE.md',
+ 'LICENSE.txt'
+ );
+ foreach ($licenseFiles as $licenseFile) {
+ $pathToLicense = $prefixPath . $licenseFile;
+ if (is_file($pathToLicense) && is_readable($pathToLicense)) {
+ return $pathToLicense;
+ }
+ }
+ return null;
+ }
}
diff --git a/core/Plugin/ReleaseChannels.php b/core/Plugin/ReleaseChannels.php
index f108a32cdf..08d95d9bb2 100644
--- a/core/Plugin/ReleaseChannels.php
+++ b/core/Plugin/ReleaseChannels.php
@@ -68,6 +68,18 @@ class ReleaseChannels
return reset($channels);
}
+ /**
+ * Sets the given release channel in config but does not save id. $config->forceSave() still needs to be called
+ * @internal tests only
+ * @param string $channel
+ */
+ public function setActiveReleaseChannelId($channel)
+ {
+ $general = Config::getInstance()->General;
+ $general['release_channel'] = $channel;
+ Config::getInstance()->General = $general;
+ }
+
public function isValidReleaseChannelId($releaseChannelId)
{
$channel = $this->factory($releaseChannelId);
diff --git a/core/ProxyHttp.php b/core/ProxyHttp.php
index 790d62229d..bf3bbf43e3 100644
--- a/core/ProxyHttp.php
+++ b/core/ProxyHttp.php
@@ -60,9 +60,12 @@ class ProxyHttp
* of the file will be served.
* @param int|false $byteEnd The ending byte in the file to serve. If false, the data from $byteStart to the
* end of the file will be served.
+ * @param string|false $filename By default the filename of $file is reused as Content-Disposition. If the
+ * file should be sent as a different filename to the client you can specify
+ * a custom filename here.
*/
public static function serverStaticFile($file, $contentType, $expireFarFutureDays = 100, $byteStart = false,
- $byteEnd = false)
+ $byteEnd = false, $filename = false)
{
// if the file cannot be found return HTTP status code '404'
if (!file_exists($file)) {
@@ -78,7 +81,12 @@ class ProxyHttp
// set some HTTP response headers
self::overrideCacheControlHeaders('public');
Common::sendHeader('Vary: Accept-Encoding');
- Common::sendHeader('Content-Disposition: inline; filename=' . basename($file));
+
+ if (false === $filename) {
+ $filename = basename($file);
+ }
+
+ Common::sendHeader('Content-Disposition: inline; filename=' . $filename);
if ($expireFarFutureDays) {
// Required by proxy caches potentially in between the browser and server to cache the request indeed
diff --git a/core/SettingsPiwik.php b/core/SettingsPiwik.php
index c0b2d8e177..52c4f3e16f 100644
--- a/core/SettingsPiwik.php
+++ b/core/SettingsPiwik.php
@@ -233,6 +233,43 @@ class SettingsPiwik
}
/**
+ * Detect whether user has enabled auto updates. Please note this config is a bit misleading. It is currently
+ * actually used for 2 things: To disable making any connections back to Piwik, and to actually disable the auto
+ * update of core and plugins.
+ * @return bool
+ */
+ public static function isAutoUpdateEnabled()
+ {
+ return (bool) Config::getInstance()->General['enable_auto_update'];
+ }
+
+ /**
+ * Detects whether an auto update can be made. An update is possible if the user is not on multiple servers and if
+ * automatic updates are actually enabled. If a user is running Piwik on multiple servers an update is not possible
+ * as it would be installed only on one server instead of all of them. Also if a user has disabled automatic updates
+ * we cannot perform any automatic updates.
+ *
+ * @return bool
+ */
+ public static function isAutoUpdatePossible()
+ {
+ return !self::isMultiServerEnvironment() && self::isAutoUpdateEnabled();
+ }
+
+ /**
+ * Returns `true` if Piwik is running on more than one server. For example in a load balanced environment. In this
+ * case we should not make changes to the config and not install a plugin via the UI as it would be only executed
+ * on one server.
+ * @return bool
+ */
+ public static function isMultiServerEnvironment()
+ {
+ $is = Config::getInstance()->General['multi_server_environment'];
+
+ return !empty($is);
+ }
+
+ /**
* Returns `true` if segmentation is allowed for this user, `false` if otherwise.
*
* @return bool
diff --git a/core/Twig.php b/core/Twig.php
index 5ac84993f1..ce8085f23c 100755
--- a/core/Twig.php
+++ b/core/Twig.php
@@ -176,6 +176,9 @@ class Twig
$this->addFilter_prettyDate();
$this->addFilter_safeDecodeRaw();
$this->addFilter_number();
+ $this->addFilter_nonce();
+ $this->addFilter_md5();
+ $this->addFilter_onlyDomain();
$this->twig->addFilter(new Twig_SimpleFilter('implode', 'implode'));
$this->twig->addFilter(new Twig_SimpleFilter('ucwords', 'ucwords'));
$this->twig->addFilter(new Twig_SimpleFilter('lcfirst', 'lcfirst'));
@@ -428,6 +431,29 @@ class Twig
$this->twig->addFilter($formatter);
}
+ protected function addFilter_nonce()
+ {
+ $nonce = new Twig_SimpleFilter('nonce', array('Piwik\\Nonce', 'getNonce'));
+ $this->twig->addFilter($nonce);
+ }
+
+ private function addFilter_md5()
+ {
+ $md5 = new \Twig_SimpleFilter('md5', function ($value) {
+ return md5($value);
+ });
+ $this->twig->addFilter($md5);
+ }
+
+ private function addFilter_onlyDomain()
+ {
+ $domainOnly = new \Twig_SimpleFilter('domainOnly', function ($url) {
+ $parsed = parse_url($url);
+ return $parsed['scheme'] . '://' . $parsed['host'];
+ });
+ $this->twig->addFilter($domainOnly);
+ }
+
protected function addFilter_truncate()
{
$truncateFilter = new Twig_SimpleFilter('truncate', function ($string, $size) {
diff --git a/core/UpdateCheck.php b/core/UpdateCheck.php
index e2ce130c4a..403fa90b36 100644
--- a/core/UpdateCheck.php
+++ b/core/UpdateCheck.php
@@ -21,11 +21,6 @@ class UpdateCheck
const LATEST_VERSION = 'UpdateCheck_LatestVersion';
const SOCKET_TIMEOUT = 2;
- private static function isAutoUpdateEnabled()
- {
- return (bool) Config::getInstance()->General['enable_auto_update'];
- }
-
/**
* Check for a newer version
*
@@ -34,7 +29,7 @@ class UpdateCheck
*/
public static function check($force = false, $interval = null)
{
- if (!self::isAutoUpdateEnabled()) {
+ if (!SettingsPiwik::isAutoUpdateEnabled()) {
return;
}
diff --git a/core/UpdateCheck/ReleaseChannel.php b/core/UpdateCheck/ReleaseChannel.php
index b398ea22c3..0744378623 100644
--- a/core/UpdateCheck/ReleaseChannel.php
+++ b/core/UpdateCheck/ReleaseChannel.php
@@ -34,6 +34,15 @@ abstract class ReleaseChannel
abstract public function getName();
/**
+ * Whether only stable versions are wanted or also beta versions.
+ * @return bool
+ */
+ public function doesPreferStable()
+ {
+ return true;
+ }
+
+ /**
* Get the latest available version number for this release channel. Eg '2.15.0-b4' or '2.15.0'. Should be
* a semantic version number in format MAJOR.MINOR.PATCH (http://semver.org/). Returning an empty string in case
* one cannot connect to the remote server can be acceptable.
diff --git a/core/Updates/3.0.0-b2.php b/core/Updates/3.0.0-b2.php
deleted file mode 100644
index 17c0fce85b..0000000000
--- a/core/Updates/3.0.0-b2.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-/**
- * Piwik - free/libre analytics platform
- *
- * @link http://piwik.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- *
- */
-
-namespace Piwik\Updates;
-
-use Piwik\Db;
-use Piwik\Plugins\Dashboard;
-use Piwik\Updater;
-use Piwik\Updater\Migration;
-use Piwik\Updates;
-
-class Updates_3_0_0_b2 extends Updates
-{
- public static function isMajorUpdate()
- {
- return true;
- }
-}
diff --git a/core/Updates/3.0.0-b3.php b/core/Updates/3.0.0-b3.php
new file mode 100644
index 0000000000..898f669eeb
--- /dev/null
+++ b/core/Updates/3.0.0-b3.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+
+namespace Piwik\Updates;
+
+use Piwik\Config;
+use Piwik\Plugin;
+use Piwik\Updater;
+use Piwik\Updates as PiwikUpdates;
+use Piwik\Updates;
+
+class Updates_3_0_0_b3 extends Updates
+{
+ private $marketplaceEnabledConfigSetting = 'enable_marketplace';
+
+ public static function isMajorUpdate()
+ {
+ return true;
+ }
+
+ public function doUpdate(Updater $updater)
+ {
+ $general = $this->getConfig()->General;
+
+ // need to check against int(0) value, as if the config setting is not set at all its value is null
+ if (isset($general[$this->marketplaceEnabledConfigSetting])) {
+ $isMarketplaceEnabled = 0 !== $general[$this->marketplaceEnabledConfigSetting];
+
+ $this->removeOldMarketplaceEnabledConfig();
+
+ if ($isMarketplaceEnabled) {
+ $pluginManager = Plugin\Manager::getInstance();
+ $pluginName = 'Marketplace';
+
+ if (!$pluginManager->isPluginActivated($pluginName)) {
+ $pluginManager->activatePlugin($pluginName);
+ }
+ }
+ }
+ }
+
+ private function getConfig()
+ {
+ return Config::getInstance();
+ }
+
+ private function removeOldMarketplaceEnabledConfig()
+ {
+ $config = $this->getConfig();
+ $general = $config->General;
+
+ if (array_key_exists($this->marketplaceEnabledConfigSetting, $general)) {
+ unset($general[$this->marketplaceEnabledConfigSetting]);
+
+ $config->General = $general;
+ $config->forceSave();
+ }
+ }
+}
diff --git a/core/View.php b/core/View.php
index 0c9b379a67..06b6db5f4a 100644
--- a/core/View.php
+++ b/core/View.php
@@ -87,6 +87,7 @@ if (!defined('PIWIK_USER_PATH')) {
* - **isPluginLoaded**: Returns true if the supplied plugin is loaded, false if otherwise.
* `{% if isPluginLoaded('Goals') %}...{% endif %}`
* - **areAdsForProfessionalServicesEnabled**: Returns true if it is ok to show some advertising in the UI for providers of Professional Support for Piwik (from Piwik 2.16.0)
+ * - **isMultiServerEnvironment**: Returns true if Piwik is used on more than one server (since Piwik 2.16.1)
*
* ### Examples
*
@@ -237,6 +238,7 @@ class View implements ViewInterface
$this->latest_version_available = UpdateCheck::isNewestVersionAvailable();
$this->disableLink = Common::getRequestVar('disableLink', 0, 'int');
$this->isWidget = Common::getRequestVar('widget', 0, 'int');
+ $this->isMultiServerEnvironment = SettingsPiwik::isMultiServerEnvironment();
$piwikAds = StaticContainer::get('Piwik\ProfessionalServices\Advertising');
$this->areAdsForProfessionalServicesEnabled = $piwikAds->areAdsForProfessionalServicesEnabled();