Skip to content

Commit

Permalink
refs #4053 cleanup code of marketplace integration
Browse files Browse the repository at this point in the history
  • Loading branch information
tsteur committed Sep 23, 2013
1 parent 4620a36 commit b67827b
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 108 deletions.
35 changes: 10 additions & 25 deletions plugins/CorePluginsAdmin/Controller.php
Expand Up @@ -37,13 +37,8 @@ private function createUpdateOrInstallView($template, $nonceName)

$view = $this->configureView('@CorePluginsAdmin/' . $template);

$pluginName = Common::getRequestVar('pluginName', '', 'string');
$pluginName = strip_tags($pluginName);
$nonce = Common::getRequestVar('nonce', '', 'string');

if (empty($pluginName)) {
throw new \Exception('Plugin parameter is missing');
}
$pluginName = Common::getRequestVar('pluginName', null, 'string');
$nonce = Common::getRequestVar('nonce', null, 'string');

$view->plugin = array('name' => $pluginName);

Expand All @@ -58,7 +53,7 @@ private function createUpdateOrInstallView($template, $nonceName)
$pluginInstaller = new PluginInstaller($pluginName);
$pluginInstaller->installOrUpdatePluginFromMarketplace();

} catch (PluginInstallerException $e) {
} catch (\Exception $e) {
$view->errorMessage = $e->getMessage();
return $view;
}
Expand All @@ -85,12 +80,7 @@ public function installPlugin()

public function pluginDetails()
{
$pluginName = Common::getRequestVar('pluginName', '', 'string');
$pluginName = strip_tags($pluginName);

if (empty($pluginName)) {
return;
}
$pluginName = Common::getRequestVar('pluginName', null, 'string');

$view = $this->configureView('@CorePluginsAdmin/pluginDetails');

Expand All @@ -107,7 +97,6 @@ public function pluginDetails()
private function createBrowsePluginsOrThemesView($template, $themesOnly)
{
$query = Common::getRequestVar('query', '', 'string', $_POST);
$query = strip_tags($query);
$sort = Common::getRequestVar('sort', $this->defaultSortMethod, 'string');

if (!in_array($sort, $this->validSortMethods)) {
Expand Down Expand Up @@ -263,13 +252,8 @@ public function activate($redirectAfter = true)
{
Piwik::checkUserIsSuperUser();

$pluginName = Common::getRequestVar('pluginName', '', 'string');
$pluginName = strip_tags($pluginName);
$nonce = Common::getRequestVar('nonce', '', 'string');

if (empty($pluginName)) {
throw new \Exception('Plugin parameter is missing');
}
$pluginName = Common::getRequestVar('pluginName', null, 'string');
$nonce = Common::getRequestVar('nonce', null, 'string');

if (!Nonce::verifyNonce('CorePluginsAdmin.activatePlugin', $nonce)) {
throw new \Exception(Piwik_Translate('General_ExceptionNonceMismatch'));
Expand All @@ -283,11 +267,12 @@ public function activate($redirectAfter = true)
$params = array('activated' => 1, 'pluginName' => $pluginName);
$plugin = PluginsManager::getInstance()->loadPlugin($pluginName);

$actionToRedirect = 'plugins';
if ($plugin->isTheme()) {
$this->redirectToIndex('CorePluginsAdmin', 'themes', null, null, null, $params);
} else {
$this->redirectToIndex('CorePluginsAdmin', 'plugins', null, null, null, $params);
$actionToRedirect = 'themes';
}

$this->redirectToIndex('CorePluginsAdmin', $actionToRedirect, null, null, null, $params);
}
}

Expand Down
24 changes: 13 additions & 11 deletions plugins/CorePluginsAdmin/Marketplace.php
Expand Up @@ -47,25 +47,25 @@ public function searchPlugins($query, $sort, $themesOnly)

$dateFormat = Piwik_Translate('CoreHome_ShortDateFormatWithYear');

foreach ($plugins as $plugin) {
$plugin->canBeUpdated = $this->hasPluginUpdate($plugin);
$plugin->isInstalled = PluginsManager::getInstance()->isPluginLoaded($plugin->name);
$plugin->lastUpdated = Date::factory($plugin->lastUpdated)->getLocalized($dateFormat);
foreach ($plugins as &$plugin) {
$plugin['canBeUpdated'] = $this->hasPluginUpdate($plugin);
$plugin['isInstalled'] = PluginsManager::getInstance()->isPluginLoaded($plugin['name']);
$plugin['lastUpdated'] = Date::factory($plugin['lastUpdated'])->getLocalized($dateFormat);
}

return $plugins;
}

private function hasPluginUpdate($plugin)
{
if (empty($plugin->name)) {
if (empty($plugin['name'])) {
return false;
}

$pluginsHavingUpdate = $this->getPluginsHavingUpdate($plugin->isTheme);
$pluginsHavingUpdate = $this->getPluginsHavingUpdate($plugin['isTheme']);

foreach ($pluginsHavingUpdate as $pluginHavingUpdate) {
if ($plugin->name == $pluginHavingUpdate->name) {
if ($plugin['name'] == $pluginHavingUpdate['name']) {
return true;
}
}
Expand All @@ -89,12 +89,14 @@ public function getPluginsHavingUpdate($themesOnly)
$pluginsHavingUpdate = array();
}

foreach ($pluginsHavingUpdate as $updatePlugin) {
foreach ($pluginsHavingUpdate as &$updatePlugin) {
foreach ($loadedPlugins as $loadedPlugin) {

if (!empty($updatePlugin->name) && $loadedPlugin->getPluginName() == $updatePlugin->name) {
$updatePlugin->currentVersion = $loadedPlugin->getVersion();
$updatePlugin->isActivated = $pluginManager->isPluginActivated($updatePlugin->name);
if (!empty($updatePlugin['name'])
&& $loadedPlugin->getPluginName() == $updatePlugin['name']) {

$updatePlugin['currentVersion'] = $loadedPlugin->getVersion();
$updatePlugin['isActivated'] = $pluginManager->isPluginActivated($updatePlugin['name']);
break;
}
}
Expand Down
72 changes: 49 additions & 23 deletions plugins/CorePluginsAdmin/MarketplaceApiClient.php
Expand Up @@ -11,13 +11,17 @@
namespace Piwik\Plugins\CorePluginsAdmin;
use Piwik\CacheFile;
use Piwik\Http;
use Piwik\PluginsManager;

/**
*
* @package CorePluginsAdmin
*/
class MarketplaceApiClient
{
const CACHE_TIMEOUT_IN_SECONDS = 1200;
const HTTP_REQUEST_TIMEOUT = 30;

private $domain = 'http://plugins.piwik.org';

/**
Expand All @@ -27,7 +31,7 @@ class MarketplaceApiClient

public function __construct()
{
$this->cache = new CacheFile('marketplace', 1200);
$this->cache = new CacheFile('marketplace', self::CACHE_TIMEOUT_IN_SECONDS);
}

public static function clearAllCacheEntries()
Expand All @@ -45,16 +49,13 @@ public function getPluginInfo($name)

public function download($pluginOrThemeName, $target)
{
$plugin = $this->getPluginInfo($pluginOrThemeName);
$downloadUrl = $this->getDownloadUrl($pluginOrThemeName);

if (empty($plugin->versions)) {
if (empty($downloadUrl)) {
return false;
}

$latestVersion = array_pop($plugin->versions);
$downloadUrl = $latestVersion->download;

$success = Http::fetchRemoteFile($this->domain . $downloadUrl, $target);
$success = Http::fetchRemoteFile($downloadUrl, $target, 0, static::HTTP_REQUEST_TIMEOUT);

return $success;
}
Expand All @@ -68,7 +69,10 @@ public function checkUpdates($plugins)
$params = array();

foreach ($plugins as $plugin) {
$params[] = array('name' => $plugin->getPluginName(), 'version' => $plugin->getVersion());
$pluginName = $plugin->getPluginName();
if (!PluginsManager::getInstance()->isPluginBundledWithCore($pluginName)) {
$params[] = array('name' => $plugin->getPluginName(), 'version' => $plugin->getVersion());
}
}

$params = array('plugins' => $params);
Expand All @@ -94,9 +98,9 @@ public function getInfoOfPluginsHavingUpdate($plugins, $themesOnly)
$pluginDetails = array();

foreach ($hasUpdates as $pluginHavingUpdate) {
$plugin = $this->getPluginInfo($pluginHavingUpdate->name);
$plugin = $this->getPluginInfo($pluginHavingUpdate['name']);

if (!empty($plugin->isTheme) == $themesOnly) {
if (!empty($plugin['isTheme']) == $themesOnly) {
$pluginDetails[] = $plugin;
}
}
Expand All @@ -108,8 +112,8 @@ public function searchForPlugins($keywords, $query, $sort)
{
$response = $this->fetch('plugins', array('keywords' => $keywords, 'query' => $query, 'sort' => $sort));

if (!empty($response->plugins)) {
return $response->plugins;
if (!empty($response['plugins'])) {
return $response['plugins'];
}

return array();
Expand All @@ -119,33 +123,36 @@ public function searchForThemes($keywords, $query, $sort)
{
$response = $this->fetch('themes', array('keywords' => $keywords, 'query' => $query, 'sort' => $sort));

if (!empty($response->plugins)) {
return $response->plugins;
if (!empty($response['plugins'])) {
return $response['plugins'];
}

return array();
}

private function fetch($action, $params)
{
ksort($params);
$query = http_build_query($params);
$result = $this->getCachedResult($action, $query);

if (false === $result) {
$endpoint = $this->domain . '/api/1.0/';
$url = sprintf('%s%s?%s', $endpoint, $action, $query);
$result = Http::sendHttpRequest($url, 5);
$this->cacheResult($action, $query, $result);
}
$response = Http::sendHttpRequest($url, static::HTTP_REQUEST_TIMEOUT);
$result = json_decode($response, true);

$result = json_decode($result);
if (is_null($result)) {
$message = sprintf('There was an error reading the response from the Marketplace: %s. Please try again later.',
substr($response, 0, 50));
throw new MarketplaceApiException($message);
}

if (is_null($result)) {
throw new MarketplaceApiException('Failure during communication with marketplace, unable to read response');
}
if (!empty($result['error'])) {
throw new MarketplaceApiException($result['error']);
}

if (!empty($result->error)) {
throw new MarketplaceApiException($result->error);
$this->cacheResult($action, $query, $result);
}

return $result;
Expand All @@ -170,4 +177,23 @@ private function getCacheKey($action, $query)
return sprintf('api.1.0.%s.%s', str_replace('/', '.', $action), md5($query));
}

/**
* @param $pluginOrThemeName
* @throws MarketplaceApiException
* @return string
*/
public function getDownloadUrl($pluginOrThemeName)
{
$plugin = $this->getPluginInfo($pluginOrThemeName);

if (empty($plugin['versions'])) {
throw new MarketplaceApiException('Plugin has no versions.');
}

$latestVersion = array_pop($plugin['versions']);
$downloadUrl = $latestVersion['download'];

return $this->domain . $downloadUrl;
}

}
46 changes: 31 additions & 15 deletions plugins/CorePluginsAdmin/PluginInstaller.php
Expand Up @@ -35,6 +35,7 @@ public function installOrUpdatePluginFromMarketplace()
$tmpPluginFolder = PIWIK_USER_PATH . self::PATH_TO_DOWNLOAD . $this->pluginName;

$this->makeSureFoldersAreWritable();
$this->makeSurePluginNameIsValid();
$this->downloadPluginFromMarketplace($tmpPluginZip);
$this->extractPluginFiles($tmpPluginZip, $tmpPluginFolder);
$this->makeSurePluginJsonExists($tmpPluginFolder);
Expand All @@ -53,21 +54,21 @@ private function downloadPluginFromMarketplace($pluginZipTargetFile)
{
$this->removeFileIfExists($pluginZipTargetFile);

try {
$marketplace = new MarketplaceApiClient();
$pluginDetails = $marketplace->getPluginInfo($this->pluginName);
} catch (\Exception $e) {
throw new PluginInstallerException($e->getMessage());
}

if (empty($pluginDetails)) {
throw new PluginInstallerException('A plugin with this name does not exist');
}
$marketplace = new MarketplaceApiClient();

try {
$marketplace->download($this->pluginName, $pluginZipTargetFile);
} catch (\Exception $e) {
throw new PluginInstallerException('Failed to download plugin: ' . $e->getMessage());

try {
$downloadUrl = $marketplace->getDownloadUrl($this->pluginName);
$errorMessage = sprintf('Failed to download plugin from %s: %s', $downloadUrl, $e->getMessage());

} catch (\Exception $ex) {
$errorMessage = sprintf('Failed to download plugin: %s', $e->getMessage());
}

throw new PluginInstallerException($errorMessage);
}
}

Expand All @@ -94,7 +95,7 @@ private function extractPluginFiles($pluginZipFile, $pathExtracted)
private function makeSurePluginJsonExists($tmpPluginFolder)
{
if (!file_exists($tmpPluginFolder . DIRECTORY_SEPARATOR . $this->pluginName . DIRECTORY_SEPARATOR . 'plugin.json')) {
throw new PluginInstallerException('Plugin is not valid, missing plugin.json');
throw new PluginInstallerException('Plugin is not valid, it is missing the plugin.json file.');
}
}

Expand All @@ -112,9 +113,7 @@ private function copyPluginToDestination($tmpPluginFolder)
*/
private function removeFolderIfExists($pathExtracted)
{
if (file_exists($pathExtracted)) {
Filesystem::unlinkRecursive($pathExtracted, true);
}
Filesystem::unlinkRecursive($pathExtracted, true);
}

/**
Expand All @@ -127,4 +126,21 @@ private function removeFileIfExists($targetTmpFile)
}
}

/**
* @throws PluginInstallerException
*/
private function makeSurePluginNameIsValid()
{
try {
$marketplace = new MarketplaceApiClient();
$pluginDetails = $marketplace->getPluginInfo($this->pluginName);
} catch (\Exception $e) {
throw new PluginInstallerException($e->getMessage());
}

if (empty($pluginDetails)) {
throw new PluginInstallerException('This plugin was not found in the Marketplace.');
}
}

}

0 comments on commit b67827b

Please sign in to comment.