This commit is contained in:
2025-04-01 00:38:54 +02:00
parent d4d4c0c09d
commit 87da06293a
22351 changed files with 5168854 additions and 7538 deletions

View File

@@ -0,0 +1,198 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Accounts\Provider;
use Db;
use Exception;
use PrestaShop\Module\PsAccounts\Repository\UserTokenRepository;
use PrestaShop\PrestaShop\Adapter\CoreException;
use PrestaShop\PrestaShop\Adapter\ServiceLocator;
use PrestaShop\PrestaShop\Core\Module\Exception\ModuleErrorException;
use PrestaShop\PsAccountsInstaller\Installer\Exception\ModuleNotInstalledException;
use PrestaShop\PsAccountsInstaller\Installer\Exception\ModuleVersionException;
use PrestaShop\PsAccountsInstaller\Installer\Facade\PsAccounts;
use PrestaShop\PsAccountsInstaller\Installer\Installer;
class AccountsDataProvider
{
/**
* @var string
*/
private $psAccountsVersion;
public function __construct(
string $psAccountsVersion
) {
$this->psAccountsVersion = $psAccountsVersion;
}
/**
* @return string
*
* @throws CoreException
*/
public function getAccountsToken()
{
if (!$this->isAccountLinked() || null === $psAccountsModule = ServiceLocator::get('ps_accounts')) {
return '';
}
/**
* @var UserTokenRepository $accountsUserTokenRepository
*/
$accountsUserTokenRepository = $psAccountsModule->getService(UserTokenRepository::class);
try {
$token = $accountsUserTokenRepository->getOrRefreshToken();
} catch (Exception $e) {
return '';
}
return null === $token ? '' : (string) $token;
}
/**
* @return string|null
*/
public function getAccountsShopId()
{
if (!$this->isAccountLinked()) {
return null;
}
try {
$shopUuid = $this->getAccountsService()->getShopUuid();
} catch (Exception $e) {
$shopUuid = null;
}
return $shopUuid ?: null;
}
/**
* @return string|null
*/
public function getAccountsUserId()
{
try {
$userUuid = $this->getAccountsService()->getUserUuid();
} catch (Exception $e) {
$userUuid = null;
}
return $userUuid ?: null;
}
/**
* @return string|null
*/
public function getAccountsUserEmail()
{
try {
$email = $this->getAccountsService()->getEmail();
} catch (Exception $e) {
$email = null;
}
return $email;
}
/**
* @return bool
*/
private function isAccountLinked()
{
try {
return $this->getAccountsService()->isAccountLinked();
} catch (Exception $e) {
return false;
}
}
/**
* @return mixed
*
* @throws ModuleNotInstalledException
* @throws ModuleVersionException
*/
public function getAccountsService()
{
if ($this->isPsAccountsInstalled()) {
if ($this->checkPsAccountsVersion()) {
$psAccounts = \Module::getInstanceByName(Installer::PS_ACCOUNTS_MODULE_NAME);
if (!$psAccounts instanceof \Module) {
throw new ModuleErrorException('Module ' . Installer::PS_ACCOUNTS_MODULE_NAME . ' not found');
}
return $psAccounts->getService(PsAccounts::PS_ACCOUNTS_SERVICE);
}
throw new ModuleVersionException('Module version expected : ' . $this->psAccountsVersion);
}
throw new ModuleNotInstalledException('Module not installed : ' . Installer::PS_ACCOUNTS_MODULE_NAME);
}
/**
* @return bool
*/
private function isPsAccountsInstalled()
{
$moduleName = Installer::PS_ACCOUNTS_MODULE_NAME;
if (false === $this->isShopVersion17()) {
return \Module::isInstalled($moduleName);
}
$sqlQuery = sprintf(
'SELECT `id_module` FROM `%smodule` WHERE `name` = "%s" AND `active` = 1',
_DB_PREFIX_,
pSQL($moduleName)
);
return (int) Db::getInstance()->getValue($sqlQuery) > 0;
}
/**
* @return bool
*/
private function checkPsAccountsVersion()
{
$moduleName = Installer::PS_ACCOUNTS_MODULE_NAME;
$module = \Module::getInstanceByName($moduleName);
if ($module instanceof \Ps_accounts) {
return (bool) version_compare(
(string) $module->version,
$this->psAccountsVersion,
'>='
);
}
return false;
}
/**
* @return bool
*/
private function isShopVersion17()
{
return version_compare(_PS_VERSION_, '1.7.0.0', '>=');
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,319 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Addons;
use Exception;
use GuzzleHttp\Exception\ClientException;
use PhpEncryption;
use PrestaShop\Module\Mbo\Addons\Exception\DownloadModuleException;
use PrestaShop\Module\Mbo\Addons\User\AddonsUser;
use PrestaShop\Module\Mbo\Exception\AddonsDownloadModuleException;
use PrestaShop\Module\Mbo\Helpers\ErrorHelper;
use PrestaShop\PrestaShop\Adapter\Module\ModuleZipManager;
use PrestaShopBundle\Service\DataProvider\Admin\AddonsInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Translation\TranslatorInterface;
/**
* Data provider for new Architecture, about Addons.
*
* This class will provide data from Addons API
*/
class AddonsDataProvider implements AddonsInterface
{
/** @var string */
const ADDONS_API_MODULE_CHANNEL_STABLE = 'stable';
/** @var array<string, string> */
const ADDONS_API_MODULE_ACTIONS = [
'native' => 'getNativesModules',
'service' => 'getServices',
'native_all' => 'getNativesModules',
'must-have' => 'getMustHaveModules',
'customer' => 'getCustomerModules',
'customer_themes' => 'getCustomerThemes',
'check_customer' => 'getCheckCustomer',
'check_module' => 'getCheckModule',
'module_download' => 'getModuleZip',
'module' => 'getModule',
'install-modules' => 'getPreInstalledModules',
'categories' => 'getCategories',
];
/**
* @var bool
*/
protected static $isAddonsUp = true;
/**
* @var ApiClient
*/
private $marketplaceClient;
/**
* @var ModuleZipManager
*/
private $zipManager;
/**
* @var PhpEncryption
*/
private $encryption;
/**
* @var string the cache directory location
*/
public $cacheDir;
/**
* @var string
*/
private $moduleChannel;
/**
* @var AddonsUser
*/
private $user;
/**
* @var TranslatorInterface
*/
private $translator;
/**
* @param ApiClient $apiClient
* @param ModuleZipManager $zipManager
* @param AddonsUser $user
* @param string|null $moduleChannel
*/
public function __construct(
ApiClient $apiClient,
ModuleZipManager $zipManager,
AddonsUser $user,
TranslatorInterface $translator,
string $moduleChannel = null
) {
$this->marketplaceClient = $apiClient;
$this->zipManager = $zipManager;
$this->encryption = new PhpEncryption(_NEW_COOKIE_KEY_);
if (null === $moduleChannel) {
$moduleChannel = self::ADDONS_API_MODULE_CHANNEL_STABLE;
}
$this->user = $user;
$this->translator = $translator;
$this->moduleChannel = $moduleChannel;
}
/**
* @param int $module_id
*
* @return bool
*
* @throws Exception
*/
public function downloadModule(int $module_id): bool
{
$params = [
'id_module' => $module_id,
'format' => 'json',
];
// Module downloading
try {
$module_data = $this->request('module_download', $params);
} catch (Exception $e) {
ErrorHelper::reportError($e);
$message = $this->isUserAuthenticated() ?
'Error sent by Addons. You may be not allowed to download this module.'
: 'Error sent by Addons. You may need to be logged.';
if ($e instanceof ClientException) {
$e = new AddonsDownloadModuleException($e);
$message = $this->translator->trans($e->getMessage(), [], 'Modules.Mbo.Errors');
}
throw new DownloadModuleException($message, 0, $e);
}
$temp_filename = tempnam($this->cacheDir, 'mod');
if (file_put_contents($temp_filename, $module_data) !== false) {
$this->zipManager->storeInModulesFolder($temp_filename);
return true;
} else {
throw new DownloadModuleException('Cannot store module content in temporary folder !');
}
}
/**
* @return bool
*
* @todo Does this function should be in a User related class ?
*/
public function isAddonsAuthenticated(): bool
{
return $this->isUserAuthenticated();
}
/**
* Tells if the user is authenticated to Addons or Account
*
* @return bool
*/
public function isUserAuthenticated()
{
return $this->user->isAuthenticated();
}
/**
* Tells if the user is authenticated to Addons
*
* @return bool
*/
public function isUserAuthenticatedOnAccounts()
{
return $this->user->hasAccountsTokenInSession() || $this->user->isConnectedOnPsAccounts();
}
/**
* Returns the user's login if he is authenticated to Addons
*
* @return string|null
*
* @throws Exception
*/
public function getAuthenticatedUserEmail()
{
return $this->isUserAuthenticated() ? (string) $this->user->getEmail()['username'] : null;
}
/**
* @param string $action
* @param array $params
*
* @return mixed
*
* @throws Exception
*/
public function request($action, $params = [])
{
if (!$this->isAddonsUp()) {
throw new Exception('Previous call failed and disabled client.');
}
if (
!array_key_exists($action, self::ADDONS_API_MODULE_ACTIONS) ||
!method_exists($this->marketplaceClient, self::ADDONS_API_MODULE_ACTIONS[$action])
) {
throw new Exception("Action '{$action}' not found in actions list.");
}
$this->marketplaceClient->reset();
$authParams = $this->getAuthenticationParams();
if (isset($authParams['bearer']) && is_string($authParams['bearer'])) {
$this->marketplaceClient->setHeaders([
'Authorization' => 'Bearer ' . $authParams['bearer'],
]);
}
if (is_array($authParams['credentials']) && !empty($authParams['credentials'])) {
$params = array_merge($authParams['credentials'], $params);
}
if ($action === 'module_download') {
$params['channel'] = $this->moduleChannel;
} elseif ($action === 'native_all') {
$params['iso_code'] = 'all';
}
try {
return $this->marketplaceClient->{self::ADDONS_API_MODULE_ACTIONS[$action]}($params);
} catch (Exception $e) {
self::$isAddonsUp = false;
throw $e;
}
}
/**
* @return array
*
* @throws Exception
*/
protected function getAddonsCredentials()
{
$request = Request::createFromGlobals();
$username = $this->encryption->decrypt($request->cookies->get('username_addons'));
$password = $this->encryption->decrypt($request->cookies->get('password_addons'));
return [
'username_addons' => $username,
'password_addons' => $password,
];
}
/** Does this function should be in a User related class ? **/
public function getAddonsEmail()
{
$request = Request::createFromGlobals();
$username = $this->encryption->decrypt($request->cookies->get('username_addons'));
return [
'username_addons' => $username,
];
}
/**
* @return array
*/
public function getAuthenticationParams()
{
$authParams = [
'bearer' => null,
'credentials' => null,
];
// We merge the addons credentials
if ($this->isUserAuthenticated()) {
$credentials = $this->user->getCredentials();
if (array_key_exists('accounts_token', $credentials)) {
$authParams['bearer'] = $credentials['accounts_token'];
// This is a bug for now, we need to give a couple of username/password even if a token is given
// It has to be cleaned once the bug fixed
$authParams['credentials'] = [
'username' => 'name@domain.com',
'password' => 'fakepwd',
];
} else {
$authParams['credentials'] = $credentials;
}
}
return $authParams;
}
/**
* Check if a request has already failed.
*
* @return bool
*/
public function isAddonsUp(): bool
{
return self::$isAddonsUp;
}
}

View File

@@ -0,0 +1,365 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Addons;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use PrestaShop\Module\Mbo\Helpers\AddonsApiHelper;
use stdClass;
class ApiClient
{
const HTTP_METHOD_GET = 'GET';
const HTTP_METHOD_POST = 'POST';
/**
* @var Client
*/
protected $httpClient;
/**
* @var array<string, string>
*/
protected $queryParameters = ['format' => 'json'];
protected $headers = [];
/**
* @var array<string, string>
*/
protected $defaultQueryParameters;
/**
* @var array<int, string>
*/
protected $possibleQueryParameters = [
'format',
'method',
'action',
'iso_lang',
'iso_code',
'version',
'channel',
'id_module',
'module_key',
'module_name',
'shop_url',
'username',
'password',
];
/**
* @param Client $httpClient
*/
public function __construct(Client $httpClient)
{
$this->httpClient = $httpClient;
}
public function setDefaultParams(string $locale, $isoCode, ?string $domain, string $shopVersion)
{
list($isoLang) = explode('-', $locale);
$this->setQueryParams([
'iso_lang' => $isoLang,
'iso_code' => $isoCode,
'version' => $shopVersion,
'shop_url' => $domain,
]);
$this->defaultQueryParameters = $this->queryParameters;
}
/**
* In case you reuse the Client, you may want to clean the previous parameters.
*/
public function reset()
{
$this->queryParameters = $this->defaultQueryParameters;
$this->headers = [];
}
/**
* @return array<string, string>
*/
public function getQueryParameters()
{
return $this->queryParameters;
}
public function getHeaders()
{
return array_merge($this->headers, AddonsApiHelper::addCustomHeaderIfNeeded());
}
/**
* Check Addons client account credentials.
*
* @param array{username_addons: string, password_addons: string} $params
*
* @return stdClass
*/
public function getCheckCustomer(array $params)
{
return $this->setQueryParams([
'method' => 'check_customer',
] + $params)->processRequestAndReturn(null, self::HTTP_METHOD_POST);
}
/**
* Check if a module is distributed by Addons.
*
* @param array{username_addons: string, password_addons: string, module_name: string, module_key: string} $params
*
* @return stdClass
*/
public function getCheckModule(array $params)
{
return $this->setQueryParams([
'method' => 'check',
] + $params)->processRequestAndReturn();
}
/**
* @param array{iso_code: string} $params
*
* @return array
*/
public function getNativesModules(array $params)
{
return $this->setQueryParams([
'method' => 'listing',
'action' => 'native',
] + $params)->processRequestAndReturn('modules');
}
/**
* @param array $params
*
* @return array
*/
public function getPreInstalledModules(array $params = [])
{
return $this->setQueryParams([
'method' => 'listing',
'action' => 'install-modules',
] + $params)->processRequestAndReturn('modules');
}
/**
* @param array $params
*
* @return array
*/
public function getMustHaveModules(array $params = [])
{
return $this->setQueryParams([
'method' => 'listing',
'action' => 'must-have',
] + $params)->processRequestAndReturn('modules');
}
/**
* @param array $params
*
* @return array
*/
public function getServices(array $params = [])
{
return $this->setQueryParams([
'method' => 'listing',
'action' => 'service',
] + $params)->processRequestAndReturn('services');
}
/**
* @param array $params
*
* @return array
*/
public function getCategories(array $params = [])
{
return $this->setQueryParams([
'method' => 'listing',
'action' => 'categories',
] + $params)->processRequestAndReturn('module');
}
/**
* @param array{id_module: int} $params
*
* @return object|null
*/
public function getModule(array $params)
{
$modules = $this->setQueryParams([
'method' => 'listing',
'action' => 'module',
] + $params)->processRequestAndReturn('modules');
if (!isset($modules[0])) {
return null;
}
return $modules[0];
}
/**
* Call API for module ZIP content (= download).
*
* @param array{username_addons: string, password_addons: string, channel: string, id_module: int} $params
*
* @return string binary content (zip format)
*/
public function getModuleZip(array $params)
{
return $this->setQueryParams([
'method' => 'module',
] + $params)->processRequest(self::HTTP_METHOD_POST);
}
/**
* @param array{username_addons: string, password_addons: string} $params
*
* @return array
*/
public function getCustomerModules(array $params)
{
return $this->setQueryParams([
'method' => 'listing',
'action' => 'customer',
] + $params)->processRequestAndReturn('modules', self::HTTP_METHOD_POST);
}
/**
* Get list of themes bought by customer.
*
* @param array{username_addons: string, password_addons: string} $params
*
* @return array
*/
public function getCustomerThemes(array $params)
{
return $this->setQueryParams([
'method' => 'listing',
'action' => 'customer-themes',
] + $params)->processRequestAndReturn('themes', self::HTTP_METHOD_POST, new stdClass());
}
/**
* Process the request with the current parameters, given the $method, and return the $attribute from
* the response body, or the default fallback value $default.
*
* @param string|null $attributeToReturn
* @param string $method
* @param mixed $default
*
* @return mixed
*/
public function processRequestAndReturn(
string $attributeToReturn = null,
string $method = self::HTTP_METHOD_GET,
$default = []
) {
$response = json_decode($this->processRequest($method));
if (JSON_ERROR_NONE !== json_last_error()) {
return $default;
}
if ($attributeToReturn) {
if (!isset($response->{$attributeToReturn})) {
return $default;
}
return $response->{$attributeToReturn};
}
return $response;
}
/**
* Process the request with the current parameters, given the $method, return the body as string
*
* @return string
*
* @throws RequestException
* @throws Exception
*/
public function processRequest(string $method = self::HTTP_METHOD_GET)
{
$options = ['query' => $this->queryParameters];
$headers = $this->getHeaders();
if (!empty($headers)) {
$options['headers'] = $headers;
}
switch ($method) {
case self::HTTP_METHOD_GET:
return (string) $this->httpClient
->get(null, $options)
->getBody();
case self::HTTP_METHOD_POST:
return (string) $this->httpClient
->post(null, $options)
->getBody();
default:
throw new Exception("Unknown or Not allowed method '{$method}'.");
}
}
/**
* @param Client $client
*
* @return $this
*/
public function setClient(Client $client)
{
$this->httpClient = $client;
return $this;
}
/**
* @param array $params
*
* @return $this
*/
public function setQueryParams(array $params)
{
$filteredParams = array_intersect_key($params, array_flip($this->possibleQueryParameters));
$this->queryParameters = array_merge($this->queryParameters, $filteredParams);
return $this;
}
/**
* @param array $headers
*
* @return $this
*/
public function setHeaders(array $headers)
{
$this->headers = array_merge($this->headers, $headers);
return $this;
}
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Addons\Exception;
class DownloadModuleException extends \Exception
{
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,229 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Addons\User;
use Exception;
use PrestaShop\Module\Mbo\Accounts\Provider\AccountsDataProvider;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
/**
* This class will read user information stored in cookies
*/
class AddonsUser implements UserInterface
{
/**
* @var CredentialsEncryptor
*/
protected $encryption;
/**
* @var Request
*/
private $request;
/**
* @var SessionInterface
*/
private $session;
/**
* @var AccountsDataProvider
*/
private $accountsDataProvider;
public function __construct(
SessionInterface $session,
CredentialsEncryptor $encryption,
AccountsDataProvider $accountsDataProvider
) {
$this->encryption = $encryption;
$this->request = Request::createFromGlobals();
$this->session = $session;
$this->accountsDataProvider = $accountsDataProvider;
}
/**
* @return bool
*/
public function isAuthenticated()
{
return $this->hasAccountsTokenInSession()
|| $this->isConnectedOnPsAccounts()
|| $this->hasCookieAuthenticated()
|| $this->hasSessionAuthenticated();
}
/**
* @return bool
*/
public function hasAccountsTokenInSession()
{
return null !== $this->getFromSession('accounts_token');
}
/**
* @return bool
*/
public function isConnectedOnPsAccounts()
{
$accountsToken = $this->accountsDataProvider->getAccountsToken();
return !empty($accountsToken);
}
/**
* @return bool
*/
private function hasSessionAuthenticated()
{
return $this->getFromSession('username_addons')
&& $this->getFromSession('password_addons');
}
/**
* {@inheritdoc}
*/
public function getCredentials($encrypted = false)
{
$accountsToken = $this->getFromSession('accounts_token');
if (null !== $accountsToken) {
return ['accounts_token' => (string) $accountsToken];
}
// accounts
$accountsToken = $this->accountsDataProvider->getAccountsToken();
if (!empty($accountsToken)) {
return ['accounts_token' => (string) $accountsToken];
}
return $encrypted ?
[
'username' => $this->get('username_addons'),
'password' => $this->get('password_addons'),
]
: [
'username' => $this->getAndDecrypt('username_addons'),
'password' => $this->getAndDecrypt('password_addons'),
];
}
/**
* @return array|null[]|string[]
*
* @throws Exception
*/
public function getEmail()
{
$email = null;
if ($this->isAuthenticated()) {
// Connected on ps_accounts
if ($this->isConnectedOnPsAccounts()) {
$email = $this->accountsDataProvider->getAccountsUserEmail();
} elseif ($this->hasAccountsTokenInSession()) { // Connected on ps_accounts with session
$email = $this->jwtDecode($this->getFromSession('accounts_token'))['email'];
} else { // Connected on addons
$email = $this->getAndDecrypt('username_addons');
}
}
return [
'username' => $email,
];
}
/**
* @param string $key
*
* @return mixed
*/
private function getFromCookie(string $key)
{
return $this->request->cookies->get($key);
}
/**
* @param string $key
*
* @return mixed
*/
private function getFromSession(string $key)
{
return $this->session->get($key);
}
/**
* @param string $key
*
* @return string|null
*
* @throws Exception
*/
private function getAndDecrypt(string $key)
{
$value = $this->get($key);
if (null !== $value) {
return $this->encryption->decrypt($value);
}
return null;
}
/**
* @param string $key
*
* @return string|null
*
* @throws Exception
*/
private function get(string $key)
{
$sessionValue = $this->getFromSession($key);
if (null !== $sessionValue) {
return $sessionValue;
}
return $this->getFromCookie($key);
}
/**
* @return bool
*/
private function hasCookieAuthenticated()
{
return $this->getFromCookie('username_addons')
&& $this->getFromCookie('password_addons');
}
/**
* @param string $token
*
* @return array
*/
private function jwtDecode(string $token)
{
$payload = explode('.', $token)[1];
$jsonToken = base64_decode($payload);
return json_decode($jsonToken, true);
}
}

View File

@@ -0,0 +1,46 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Addons\User;
use PhpEncryptionCore as PhpEncryption;
class CredentialsEncryptor
{
/**
* @var PhpEncryption
*/
private $encryptor;
public function __construct()
{
$this->encryptor = new PhpEncryption(_NEW_COOKIE_KEY_);
}
public function encrypt(string $value)
{
return $this->encryptor->encrypt($value);
}
public function decrypt(string $value)
{
return $this->encryptor->decrypt($value);
}
}

View File

@@ -0,0 +1,41 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Addons\User;
interface UserInterface
{
/**
* @return bool
*/
public function isAuthenticated();
/**
* @pararm bool $encrypted
*
* @return array{username?: string, password?: string, accounts_token?: string}
*/
public function getCredentials($encrypted = false);
/**
* @return array{username: string}
*/
public function getEmail();
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,93 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo;
use PrestaShop\PrestaShop\Adapter\Configuration;
use PrestaShop\PrestaShop\Adapter\LegacyContext;
use PrestaShop\PrestaShop\Core\Foundation\Version;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Responsible of provide Addons url with Context params for Module Selection and Theme Catalog pages
*/
class AddonsSelectionLinkProvider
{
/**
* @var Version
*/
private $version;
/**
* @var LegacyContext
*/
private $context;
/**
* @var Configuration
*/
private $configuration;
/**
* @var RequestStack
*/
private $requestStack;
/**
* @param Version $version
* @param LegacyContext $context
* @param Configuration $configuration
* @param RequestStack $requestStack
*/
public function __construct(
Version $version,
LegacyContext $context,
Configuration $configuration,
RequestStack $requestStack
) {
$this->version = $version;
$this->context = $context;
$this->configuration = $configuration;
$this->requestStack = $requestStack;
}
/**
* We cannot use http_build_query() here due to a bug on Addons
*
* @see https://github.com/PrestaShop/PrestaShop/pull/9255/files#r200498010
*
* @return string
*/
public function getLinkUrl()
{
$link = 'https://addons.prestashop.com/iframe/search-1.7.php?psVersion=' . $this->version->getVersion()
. '&isoLang=' . $this->context->getContext()->language->iso_code
. '&isoCurrency=' . $this->context->getContext()->currency->iso_code
. '&isoCountry=' . $this->context->getContext()->country->iso_code
. '&activity=' . $this->configuration->getInt('PS_SHOP_ACTIVITY')
. '&parentUrl=' . $this->requestStack->getCurrentRequest()->getSchemeAndHttpHost();
if ('AdminPsMboTheme' === $this->requestStack->getCurrentRequest()->attributes->get('_legacy_controller')) {
$link .= '&onlyThemes=1';
}
return $link;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,383 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Controller\Admin;
use Exception;
use PrestaShop\PrestaShop\Adapter\Module\AdminModuleDataProvider;
use PrestaShop\PrestaShop\Core\Addon\AddonListFilter;
use PrestaShop\PrestaShop\Core\Addon\AddonListFilterStatus;
use PrestaShop\PrestaShop\Core\Addon\AddonListFilterType;
use PrestaShop\PrestaShop\Core\Addon\AddonsCollection;
use PrestaShopBundle\Controller\Admin\Improve\ModuleController as ModuleControllerCore;
use PrestaShopBundle\Security\Annotation\AdminSecurity;
use PrestaShopBundle\Security\Voter\PageVoter;
use PrestaShopBundle\Service\DataProvider\Admin\CategoriesProvider;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class ModuleController extends ModuleControllerCore
{
/**
* @AdminSecurity("is_granted(['read'], 'ADMINMODULESSF_')")
*
* @return Response
*/
public function catalogAction()
{
$moduleUri = __PS_BASE_URI__ . 'modules/ps_mbo/';
$extraParams = [
'me_url' => $this->generateUrl('admin_mbo_security'),
'cdc_error_templating_url' => $moduleUri . 'views/js/cdc-error-templating.js',
'cdc_error_templating_css' => $moduleUri . 'views/css/cdc-error-templating.css',
];
$cdcJsFile = getenv('MBO_CDC_URL');
if (false === $cdcJsFile || !is_string($cdcJsFile) || empty($cdcJsFile)) {
$extraParams['cdc_script_not_found'] = true;
$extraParams['cdc_error_url'] = $moduleUri . 'views/js/cdc-error.js';
} else {
$extraParams['cdc_url'] = $cdcJsFile;
}
/*********************
* PrestaShop Account *
* *******************/
$urlAccountsCdn = '';
try {
$accountsFacade = $this->get('mbo.ps_accounts.facade');
$accountsService = $accountsFacade->getPsAccountsService();
if ($this->ensurePsAccountIsEnabled()) {
$this->ensurePsEventbusEnabled();
}
} catch (Exception $e) {
try {
$accountsInstaller = $this->get('mbo.ps_accounts.installer');
$accountsInstaller->install();
$accountsFacade = $this->get('mbo.ps_accounts.facade');
$accountsService = $accountsFacade->getPsAccountsService();
} catch (Exception $e) {
$accountsFacade = $accountsService = null;
}
}
if (null !== $accountsFacade && null !== $accountsService) {
try {
\Media::addJsDef([
'contextPsAccounts' => $accountsFacade->getPsAccountsPresenter()
->present('ps_mbo'),
]);
// Retrieve the PrestaShop Account CDN
$urlAccountsCdn = $accountsService->getAccountsCdn();
} catch (Exception $e) {
//osef ?
}
}
return $this->render(
'@Modules/ps_mbo/views/templates/admin/controllers/module_catalog/catalog.html.twig',
[
'layoutHeaderToolbarBtn' => $this->getToolbarButtons(),
'layoutTitle' => $this->trans('Marketplace', 'Admin.Navigation.Menu'),
'requireAddonsSearch' => true,
'requireBulkActions' => false,
'showContentHeader' => true,
'enableSidebar' => true,
'help_link' => $this->generateSidebarLink('AdminModules'),
'requireFilterStatus' => false,
'level' => $this->authorizationLevel(self::CONTROLLER_NAME),
'shop_context' => $this->get('mbo.cdc.context_builder')->getViewContext(),
'urlAccountsCdn' => $urlAccountsCdn,
'errorMessage' => $this->trans(
'You do not have permission to add this.',
'Admin.Notifications.Error'
),
] + $extraParams
);
}
/**
* Controller responsible for displaying "Catalog Module Grid" section of Module management pages with ajax.
*
* @param Request $request
*
* @return JsonResponse
*/
public function refreshCatalogAction(Request $request)
{
$deniedAccess = $this->checkPermissions(
[
PageVoter::LEVEL_READ,
PageVoter::LEVEL_CREATE,
PageVoter::LEVEL_DELETE,
PageVoter::LEVEL_UPDATE,
]
);
if (null !== $deniedAccess) {
return $deniedAccess;
}
/**
* @var AdminModuleDataProvider $modulesProvider
*/
$modulesProvider = $this->get('prestashop.core.admin.data_provider.module_interface');
$moduleRepository = $this->get('prestashop.core.admin.module.repository');
$responseArray = [];
$filters = new AddonListFilter();
$filters->setType(AddonListFilterType::MODULE | AddonListFilterType::SERVICE)
->setStatus(~AddonListFilterStatus::INSTALLED);
try {
$modulesFromRepository = AddonsCollection::createFrom($moduleRepository->getFilteredList($filters));
$modulesProvider->generateAddonsUrls($modulesFromRepository);
$modules = $modulesFromRepository->toArray();
shuffle($modules);
$categories = $this->getCategories($modulesProvider, $modules);
$responseArray['domElements'][] = $this->constructJsonCatalogCategoriesMenuResponse($categories);
$responseArray['domElements'][] = $this->constructJsonCatalogBodyResponse(
$categories,
$modules
);
$responseArray['status'] = true;
} catch (Exception $e) {
$responseArray['msg'] = $this->trans(
'Cannot get catalog data, please try again later. Reason: %error_details%',
'Admin.Modules.Notification',
['%error_details%' => print_r($e->getMessage(), true)]
);
$responseArray['status'] = false;
}
return new JsonResponse($responseArray);
}
/**
* Responsible for displaying error block when CDC cannot be loaded.
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function cdcErrorAction()
{
return $this->render(
'@Modules/ps_mbo/views/templates/admin/controllers/module_catalog/cdc-error.html.twig'
);
}
/**
* @AdminSecurity("is_granted(['read'], 'ADMINMODULESSF_')")
*
* @param Request $request
*/
public function uninstalledAction(Request $request)
{
$modulesProvider = $this->get('prestashop.core.admin.data_provider.module_interface');
$moduleRepository = $this->get('prestashop.core.admin.module.repository');
$filters = new AddonListFilter();
$filters->setType(AddonListFilterType::MODULE | AddonListFilterType::SERVICE)
->setStatus(AddonListFilterStatus::UNINSTALLED);
$installedProducts = $moduleRepository->getFilteredList($filters);
$collection = AddonsCollection::createFrom($installedProducts);
$modulesProvider->generateAddonsUrls($collection);
$modules = $this->get('prestashop.adapter.presenter.module')
->presentCollection($installedProducts);
return $this->render(
'@Modules/ps_mbo/views/templates/admin/controllers/module_catalog/uninstalled-modules.html.twig',
[
'maxModulesDisplayed' => self::MAX_MODULES_DISPLAYED,
'layoutHeaderToolbarBtn' => $this->getToolbarButtons(),
'layoutTitle' => $this->trans('Module manager', 'Admin.Modules.Feature'),
'modules' => $modules,
'requireAddonsSearch' => false,
'requireBulkActions' => false,
'enableSidebar' => true,
'help_link' => $this->generateSidebarLink('AdminModules'),
'requireFilterStatus' => true,
'level' => $this->authorizationLevel(self::CONTROLLER_NAME),
'errorMessage' => $this->trans('You do not have permission to add this.', 'Admin.Notifications.Error'),
]
);
}
/**
* Construct Json struct for catalog body response.
*
* @param array $categories
* @param array $modules
*
* @return array
*/
private function constructJsonCatalogBodyResponse(
array $categories,
array $modules
) {
$formattedContent = [];
$formattedContent['selector'] = '.module-catalog-page-result';
$formattedContent['content'] = $this->render(
'@Modules/ps_mbo/views/templates/admin/controllers/module_catalog/Includes/sorting.html.twig',
[
'totalModules' => count($modules),
]
)->getContent();
$errorMessage = $this->trans('You do not have permission to add this.', 'Admin.Notifications.Error');
$psVersion = explode('.', _PS_VERSION_);
$version = sprintf('%d.%d.%d', (int) $psVersion[0], (int) $psVersion[1], (int) $psVersion[2]);
$locale = $this->getContext()->language->iso_code;
$formattedContent['content'] .= $this->render(
'@Modules/ps_mbo/views/templates/admin/controllers/module_catalog/catalog_grid.html.twig',
[
'categories' => $categories['categories'],
'requireAddonsSearch' => true,
'level' => $this->authorizationLevel(self::CONTROLLER_NAME),
'errorMessage' => $errorMessage,
'psVersion' => $version,
'locale' => $locale,
]
)->getContent();
return $formattedContent;
}
/**
* Construct json struct from top menu.
*
* @param array $categories
*
* @return array
*/
private function constructJsonCatalogCategoriesMenuResponse(array $categories)
{
$formattedContent = [];
$formattedContent['selector'] = '.module-menu-item';
$formattedContent['content'] = $this->render(
'@PrestaShop/Admin/Module/Includes/dropdown_categories_catalog.html.twig',
[
'topMenuData' => $this->getTopMenuData($categories),
]
)->getContent();
return $formattedContent;
}
/**
* Check user permission.
*
* @param array $pageVoter
*
* @return JsonResponse|null
*/
private function checkPermissions(array $pageVoter)
{
if (!in_array(
$this->authorizationLevel(self::CONTROLLER_NAME),
$pageVoter
)) {
return new JsonResponse(
[
'status' => false,
'msg' => $this->trans('You do not have permission to add this.', 'Admin.Notifications.Error'),
]
);
}
return null;
}
/**
* Get categories and its modules.
*
* @param array $modules List of installed modules
*
* @return array
*/
private function getCategories(AdminModuleDataProvider $modulesProvider, array $modules)
{
/** @var CategoriesProvider $categoriesProvider */
$categoriesProvider = $this->get('prestashop.categories_provider');
$categories = $categoriesProvider->getCategoriesMenu($modules);
foreach ($categories['categories']->subMenu as $category) {
$collection = AddonsCollection::createFrom($category->modules);
$modulesProvider->generateAddonsUrls($collection);
$category->modules = $this->get('prestashop.adapter.presenter.module')
->presentCollection($category->modules);
}
return $categories;
}
private function getTopMenuData(array $topMenuData, $activeMenu = null)
{
if (isset($activeMenu)) {
if (!isset($topMenuData[$activeMenu])) {
throw new Exception(sprintf('Menu \'%s\' not found in Top Menu data', $activeMenu), 1);
}
$topMenuData[$activeMenu]->class = 'active';
}
return $topMenuData;
}
/**
* @return bool
*/
private function ensurePsAccountIsEnabled()
{
$accountsInstaller = $this->get('mbo.ps_accounts.installer');
// @phpstan-ignore booleanNot.alwaysFalse
if (!$accountsInstaller) {
return false;
}
$accountsEnabled = $accountsInstaller->isModuleEnabled();
if ($accountsEnabled) {
return true;
}
$moduleManager = $this->get('prestashop.module.manager');
return $moduleManager->enable($accountsInstaller->getModuleName());
}
/**
* @return void
*/
private function ensurePsEventbusEnabled()
{
$installer = $this->get('mbo.ps_eventbus.installer');
if ($installer->install()) {
$installer->enable();
}
}
}

View File

@@ -0,0 +1,209 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Controller\Admin;
use PrestaShop\Module\Mbo\RecommendedModule\RecommendedModulePresenterInterface;
use PrestaShop\Module\Mbo\Tab\TabCollectionProviderInterface;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
use Tools;
/**
* Responsible of render json data for ajax display of Recommended Modules.
*/
class ModuleRecommendedController extends FrameworkBundleAdminController
{
const MBO_AVAILABLE_LANGUAGES = ['en', 'de', 'fr', 'es', 'it', 'nl', 'pl', 'pt', 'ru'];
/**
* @var RequestStack
*/
private $requestStack;
/**
* @var TabCollectionProviderInterface
*/
private $tabCollectionProvider;
/**
* @var RecommendedModulePresenterInterface
*/
private $recommendedModulePresenter;
/**
* @param RequestStack $requestStack
* @param TabCollectionProviderInterface $tabCollectionProvider
* @param RecommendedModulePresenterInterface $recommendedModulePresenter
*/
public function __construct(
RequestStack $requestStack,
TabCollectionProviderInterface $tabCollectionProvider,
RecommendedModulePresenterInterface $recommendedModulePresenter
) {
parent::__construct();
$this->requestStack = $requestStack;
$this->tabCollectionProvider = $tabCollectionProvider;
$this->recommendedModulePresenter = $recommendedModulePresenter;
}
/**
* @return JsonResponse
*/
public function indexAction()
{
$response = new JsonResponse();
try {
$tabCollection = $this->tabCollectionProvider->getTabCollection();
$tabClassName = $this->requestStack->getCurrentRequest()->get('tabClassName');
$tab = $tabCollection->getTab($tabClassName);
$response->setData([
'content' => $this->renderView(
'@Modules/ps_mbo/views/templates/admin/controllers/module_catalog/recommended-modules.html.twig',
[
'recommendedModulesInstalled' => $this->recommendedModulePresenter->presentCollection($tab->getRecommendedModulesInstalled()),
'recommendedModulesNotInstalled' => $this->recommendedModulePresenter->presentCollection($tab->getRecommendedModulesNotInstalled()),
'recommendedModulesLinkToAddons' => $this->getRecommendedModulesLinkToAddons(),
]
),
]);
} catch (ServiceUnavailableHttpException $exception) {
$response->setData([
'content' => $this->renderView('@Modules/ps_mbo/views/templates/admin/error.html.twig'),
]);
$response->setStatusCode($exception->getStatusCode());
$response->headers->add($exception->getHeaders());
}
return $response;
}
/**
* Customize link to addons of recommended modules modal
*
* @return string
*/
private function getRecommendedModulesLinkToAddons()
{
// Get the 3 digits version number. For example, 1.7.6.7 will become 1.7.6
$psVersion = explode('.', _PS_VERSION_);
$version = sprintf('%d.%d.%d', (int) $psVersion[0], (int) $psVersion[1], (int) $psVersion[2]);
// Get the request context language. Fallback to english if not supported
$locale = $this->getContext()->language->iso_code;
if (!in_array($locale, self::MBO_AVAILABLE_LANGUAGES)) {
$locale = 'en';
}
$params = [
'utm_source' => 'back-office',
'utm_medium' => 'dispatch',
'utm_campaign' => 'back-office-' . $locale,
'utm_content' => 'download',
'compatibility' => $version,
];
$request = $this->requestStack->getCurrentRequest();
if ($request->request->has('admin_list_from_source')) {
$params['utm_term'] = $request->request->get('admin_list_from_source');
}
$baseUrl = 'https://addons.prestashop.com/' . $locale;
switch (Tools::getValue('tabClassName')) {
case 'AdminCustomers':
$linkToAddons = $baseUrl . '/475-clients';
break;
case 'AdminEmails':
$linkToAddons = $baseUrl . '/437-emails-notifications';
break;
case 'AdminAdminPreferences':
$linkToAddons = $baseUrl . '/440-administration';
break;
case 'AdminSearchConf':
$linkToAddons = $baseUrl . '/510-recherches-filtres';
break;
case 'AdminMeta':
$linkToAddons = $baseUrl . '/488-trafic-marketplaces';
break;
case 'AdminContacts':
$linkToAddons = $baseUrl . '/475-clients';
break;
case 'AdminGroups':
$linkToAddons = $baseUrl . '/537-gestion-clients?';
break;
case 'AdminStatuses':
$linkToAddons = $baseUrl . '/441-gestion-commandes?';
break;
case 'AdminPayment':
$linkToAddons = $baseUrl . '/481-paiement';
break;
case 'AdminShipping':
$linkToAddons = $baseUrl . '/518-livraison-logistique';
break;
case 'AdminCarriers':
$linkToAddons = $baseUrl . '/520-transporteurs';
break;
case 'AdminImages':
$linkToAddons = $baseUrl . '/462-visuels-produits';
break;
case 'AdminCmsContent':
$linkToAddons = $baseUrl . '/516-personnalisation-de-page';
break;
case 'AdminStats':
$linkToAddons = $baseUrl . '/209-tableaux-de-bord';
break;
case 'AdminCustomerThreads':
$linkToAddons = $baseUrl . '/442-service-client';
break;
case 'AdminSpecificPriceRule':
case 'AdminCartRules':
$linkToAddons = $baseUrl . '/496-promotions-marketing';
break;
case 'AdminManufacturers':
$linkToAddons = $baseUrl . '/512-marques-fabricants';
break;
case 'AdminFeatures':
$linkToAddons = $baseUrl . '/467-declinaisons-personnalisation';
break;
case 'AdminProducts':
$linkToAddons = $baseUrl . '/460-fiche-produit';
break;
case 'AdminDeliverySlip':
$linkToAddons = $baseUrl . '/519-preparation-expedition';
break;
case 'AdminSlip':
case 'AdminInvoices':
$linkToAddons = $baseUrl . '/446-comptabilite-facturation';
break;
case 'AdminOrders':
$params['benefit_categories[]'] = 3;
$linkToAddons = $baseUrl . '/2-modules-prestashop';
break;
default:
$linkToAddons = $baseUrl;
break;
}
return $linkToAddons . '?' . http_build_query($params, '', '&');
}
}

View File

@@ -0,0 +1,106 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Controller\Admin;
use PrestaShop\Module\Mbo\AddonsSelectionLinkProvider;
use PrestaShop\Module\Mbo\ExternalContentProvider\ExternalContentProviderInterface;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
use PrestaShopBundle\Security\Annotation\AdminSecurity;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
/**
* Responsible of "Improve > Modules > Modules Catalog > Modules Selection" page display.
*/
class ModuleSelectionController extends FrameworkBundleAdminController
{
/**
* @var RequestStack
*/
private $requestStack;
/**
* @var ExternalContentProviderInterface
*/
private $externalContentProvider;
/**
* @var AddonsSelectionLinkProvider
*/
private $addonsSelectionLinkProvider;
/**
* @param RequestStack $requestStack
* @param ExternalContentProviderInterface $externalContentCollectionProvider
* @param AddonsSelectionLinkProvider $addonsSelectionLinkProvider
*/
public function __construct(
RequestStack $requestStack,
ExternalContentProviderInterface $externalContentCollectionProvider,
AddonsSelectionLinkProvider $addonsSelectionLinkProvider
) {
parent::__construct();
$this->requestStack = $requestStack;
$this->externalContentProvider = $externalContentCollectionProvider;
$this->addonsSelectionLinkProvider = $addonsSelectionLinkProvider;
}
/**
* @AdminSecurity("is_granted('read', request.get('_legacy_controller'))")
*
* @return Response
*/
public function indexAction()
{
$response = new Response();
try {
if (true === (bool) version_compare(_PS_VERSION_, '1.7.8', '>=')) {
$pageTitle = $this->trans('Modules in the spotlight', 'Modules.Mbo.Modulesselection');
} else {
$pageTitle = $this->trans('Module selection', 'Admin.Navigation.Menu');
}
$response->setContent($this->renderView(
'@Modules/ps_mbo/views/templates/admin/controllers/module_catalog/addons_store.html.twig',
[
'pageContent' => $this->externalContentProvider->getContent($this->addonsSelectionLinkProvider->getLinkUrl()),
'layoutHeaderToolbarBtn' => [],
'layoutTitle' => $pageTitle,
'requireAddonsSearch' => true,
'requireBulkActions' => false,
'showContentHeader' => true,
'enableSidebar' => true,
'help_link' => $this->generateSidebarLink($this->requestStack->getCurrentRequest()->get('_legacy_controller')),
'requireFilterStatus' => false,
'level' => $this->authorizationLevel($this->requestStack->getCurrentRequest()->get('_legacy_controller')),
]
));
} catch (ServiceUnavailableHttpException $exception) {
$response->setContent($this->renderView('@Modules/ps_mbo/views/templates/admin/error.html.twig'));
$response->setStatusCode($exception->getStatusCode());
$response->headers->add($exception->getHeaders());
}
return $response;
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Controller\Admin;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
use Symfony\Component\HttpFoundation\JsonResponse;
class SecurityController extends FrameworkBundleAdminController
{
/**
* @return JsonResponse
*/
public function meAction()
{
return new JsonResponse();
}
}

View File

@@ -0,0 +1,100 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Controller\Admin;
use PrestaShop\Module\Mbo\AddonsSelectionLinkProvider;
use PrestaShop\Module\Mbo\ExternalContentProvider\ExternalContentProviderInterface;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
use PrestaShopBundle\Security\Annotation\AdminSecurity;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
/**
* Responsible of "Improve > Design > Themes Catalog" page display.
*/
class ThemeCatalogController extends FrameworkBundleAdminController
{
/**
* @var RequestStack
*/
private $requestStack;
/**
* @var ExternalContentProviderInterface
*/
private $externalContentProvider;
/**
* @var AddonsSelectionLinkProvider
*/
private $addonsSelectionLinkProvider;
/**
* @param RequestStack $requestStack
* @param ExternalContentProviderInterface $externalContentCollectionProvider
* @param AddonsSelectionLinkProvider $addonsSelectionLinkProvider
*/
public function __construct(
RequestStack $requestStack,
ExternalContentProviderInterface $externalContentCollectionProvider,
AddonsSelectionLinkProvider $addonsSelectionLinkProvider
) {
parent::__construct();
$this->requestStack = $requestStack;
$this->externalContentProvider = $externalContentCollectionProvider;
$this->addonsSelectionLinkProvider = $addonsSelectionLinkProvider;
}
/**
* @AdminSecurity("is_granted('read', request.get('_legacy_controller'))")
*
* @return Response
*/
public function indexAction()
{
$response = new Response();
try {
$response->setContent($this->renderView(
'@Modules/ps_mbo/views/templates/admin/controllers/theme_catalog/addons_store.html.twig',
[
'pageContent' => $this->externalContentProvider->getContent($this->addonsSelectionLinkProvider->getLinkUrl()),
'layoutHeaderToolbarBtn' => [],
'layoutTitle' => $this->trans('Themes Catalog', 'Admin.Navigation.Menu'),
'requireAddonsSearch' => true,
'requireBulkActions' => false,
'showContentHeader' => true,
'enableSidebar' => true,
'help_link' => $this->generateSidebarLink($this->requestStack->getCurrentRequest()->get('_legacy_controller')),
'requireFilterStatus' => false,
'level' => $this->authorizationLevel($this->requestStack->getCurrentRequest()->get('_legacy_controller')),
]
));
} catch (ServiceUnavailableHttpException $exception) {
$response->setContent($this->renderView('@Modules/ps_mbo/views/templates/admin/error.html.twig'));
$response->setStatusCode($exception->getStatusCode());
$response->headers->add($exception->getHeaders());
}
return $response;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,67 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Distribution;
use Doctrine\Common\Cache\CacheProvider;
use Firebase\JWT\JWT;
use PrestaShop\Module\Mbo\Helpers\Config;
class AuthenticationProvider
{
/**
* @var CacheProvider
*/
private $cacheProvider;
public function __construct(
CacheProvider $cacheProvider
) {
$this->cacheProvider = $cacheProvider;
}
public function getMboJWT()
{
$cacheKey = $this->getJwtTokenCacheKey();
if ($this->cacheProvider->contains($cacheKey)) {
return $this->cacheProvider->fetch($cacheKey);
}
$shopUrl = Config::getShopUrl();
$shopUuid = Config::getShopMboUuid();
$jwtToken = JWT::encode(['shop_url' => $shopUrl, 'shop_uuid' => $shopUuid], md5($shopUuid), 'HS256');
$this->cacheProvider->save($cacheKey, $jwtToken, 0); // Lifetime infinite, will be purged when MBO is uninstalled
return $this->cacheProvider->fetch($cacheKey);
}
public function clearCache()
{
$this->cacheProvider->delete($this->getJwtTokenCacheKey());
}
private function getJwtTokenCacheKey()
{
return sprintf('mbo_jwt_token_%s', Config::getShopMboUuid());
}
}

View File

@@ -0,0 +1,213 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Distribution;
use Doctrine\Common\Cache\CacheProvider;
use GuzzleHttp\Client as HttpClient;
use PrestaShop\Module\Mbo\Helpers\Config;
class BaseClient
{
const HTTP_METHOD_GET = 'GET';
const HTTP_METHOD_POST = 'POST';
const HTTP_METHOD_PUT = 'PUT';
const HTTP_METHOD_DELETE = 'DELETE';
/**
* @var HttpClient
*/
protected $httpClient;
/**
* @var CacheProvider
*/
protected $cacheProvider;
/**
* @var array<string, string>
*/
protected $queryParameters = [];
/**
* @var array<int, string>
*/
protected $possibleQueryParameters = [
'format',
'method',
'action',
'shop_uuid',
'shop_url',
'isoLang',
'shopVersion',
'ps_version',
'iso_lang',
'iso_code',
'addons_username',
'addons_pwd',
];
/**
* @var array<string, string>
*/
protected $headers = [];
/**
* @param HttpClient $httpClient
* @param \Doctrine\Common\Cache\CacheProvider $cacheProvider
*/
public function __construct(HttpClient $httpClient, CacheProvider $cacheProvider)
{
$this->httpClient = $httpClient;
$this->cacheProvider = $cacheProvider;
}
/**
* In case you reuse the Client, you may want to clean the previous parameters.
*/
public function reset()
{
$this->queryParameters = [];
$this->headers = [];
}
/**
* @param array $params
*
* @return $this
*/
public function setQueryParams(array $params)
{
$filteredParams = array_intersect_key($params, array_flip($this->possibleQueryParameters));
$this->queryParameters = array_merge($this->queryParameters, $filteredParams);
return $this;
}
/**
* @param array $headers
*
* @return $this
*/
public function setHeaders(array $headers)
{
$this->headers = array_merge($this->headers, $headers);
return $this;
}
/**
* @param string $jwt
*
* @return $this
*/
public function setBearer(string $jwt)
{
return $this->setHeaders(['Authorization' => 'Bearer ' . $jwt]);
}
/**
* @param array $params
*
* @return array
*/
protected function mergeShopDataWithParams(array $params)
{
$psMbo = \Module::getInstanceByName('ps_mbo');
$psMboVersion = false;
if (\Validate::isLoadedObject($psMbo)) {
$psMboVersion = $psMbo->version;
}
$shopUuid = Config::getShopMboUuid();
return array_merge([
'uuid' => $shopUuid,
'shop_url' => Config::getShopUrl(),
'admin_path' => sprintf('/%s/', trim(str_replace(_PS_ROOT_DIR_, '', _PS_ADMIN_DIR_), '/')),
'mbo_version' => $psMboVersion,
'ps_version' => _PS_VERSION_,
'mbo_api_user_token' => md5($shopUuid),
], $params);
}
/**
* Process the request with the current parameters, given the $method, and return the $attribute from
* the response body, or the default fallback value $default.
*
* @param string $uri
* @param array $options
* @param string $method
* @param mixed $default
*
* @return mixed
*/
protected function processRequestAndDecode(
string $uri,
string $method = self::HTTP_METHOD_GET,
array $options = [],
$default = []
) {
$response = json_decode($this->processRequest($uri, $method, $options));
if (JSON_ERROR_NONE !== json_last_error()) {
return $default;
}
return $response;
}
/**
* Process the request with the current parameters, given the $method, return the body as string
*
* @param string $uri
* @param string $method
* @param array $options
*
* @return string
*/
protected function processRequest(
string $uri,
string $method,
array $options
) {
$options = array_merge($options, [
'query' => $this->queryParameters,
'headers' => $this->headers,
]);
switch ($method) {
case self::HTTP_METHOD_GET:
return (string) $this->httpClient
->get('/api/' . ltrim($uri, '/'), $options)
->getBody();
case self::HTTP_METHOD_POST:
return (string) $this->httpClient
->post('/api/' . ltrim($uri, '/'), $options)
->getBody();
case self::HTTP_METHOD_PUT:
return (string) $this->httpClient
->put('/api/' . ltrim($uri, '/'), $options)
->getBody();
case self::HTTP_METHOD_DELETE:
return (string) $this->httpClient
->delete('/api/' . ltrim($uri, '/'), $options)
->getBody();
default:
throw new \Exception('Unhandled method in BaseClient::processRequest');
}
}
}

View File

@@ -0,0 +1,76 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Distribution;
use PrestaShop\Module\Mbo\Helpers\Config;
use stdClass;
class Client extends BaseClient
{
/**
* Register new Shop on Distribution API.
*
* @param array $params
*
* @return stdClass
*
* @usage \ps_mbo::registerShop
*/
public function registerShop(array $params = [])
{
return $this->processRequestAndDecode(
'shops',
self::HTTP_METHOD_POST,
['body' => $this->mergeShopDataWithParams($params)]
);
}
/**
* Unregister a Shop on Distribution API.
*
* @return stdClass
*/
public function unregisterShop()
{
return $this->processRequestAndDecode(
'shops/' . Config::getShopMboUuid(),
self::HTTP_METHOD_DELETE
);
}
/**
* Update shop on Distribution API.
*
* @param array $params
*
* @return stdClass
*
* @usage \ps_mbo::updateShop
*/
public function updateShop(array $params)
{
return $this->processRequestAndDecode(
'shops/' . Config::getShopMboUuid(),
self::HTTP_METHOD_PUT,
['body' => $this->mergeShopDataWithParams($params)]
);
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,70 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\EventSubscriber;
use PrestaShop\Module\Mbo\UpgradeTracker;
use PrestaShopBundle\Event\ModuleManagementEvent;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Listen upgrade events from module manager, and push event to distribution event for tracking purpose.
*/
class ModuleEventSubscriber implements EventSubscriberInterface
{
/**
* @var LoggerInterface
*/
private $logger;
/**
* @param LoggerInterface $logger
*/
public function __construct(
LoggerInterface $logger
) {
$this->logger = $logger;
}
/**
* @return array
*/
public static function getSubscribedEvents()
{
return [
ModuleManagementEvent::UPGRADE => 'pushDistributionTracking',
];
}
/**
* @param ModuleManagementEvent $event
*/
public function pushDistributionTracking(ModuleManagementEvent $event)
{
$module = $event->getModule();
$moduleName = $module->get('name');
if ('ps_mbo' !== $moduleName) {
return;
}
(new UpgradeTracker())->postTracking($module->getInstance());
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,146 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
declare(strict_types=1);
namespace PrestaShop\Module\Mbo\Exception;
use Exception;
use GuzzleHttp\Exception\ClientException;
class AddonsDownloadModuleException extends Exception
{
private const UNKNOWN_ADDONS_CODE = '0030';
const WRONG_PARAMETERS = '0000';
const WRONG_MODULE_KEY = '0001';
const UNKNOWN_MODULE = '0002';
const INVALID_CREDENTIALS = '0003';
const INVALID_EMAIL_OR_PASSWORD = '0004';
const ACCESS_DENIED = '0005';
const INVALID_PRODUCT_FILE = '0006';
const TM_CURL_INVALID_LINK = '0007';
const TM_INACTIVE_LINK = '0008';
const TM_INVALID_ORDER = '0009';
const INVALID_METHOD = '0010';
const HTTPS_REQUIRED = '0011';
const INVALID_AUTH = '0012';
const INVALID_EMAIL = '0013';
const INVALID_PARAMETERS = '0014';
const METHOD_UNDEFINED = '0015';
const KO_LABEL = '0016';
const SERVICE_UNAVAILABLE = '0017';
const NO_ZIP_SERVICE = '0018';
const WEBSITE_REFUSED = '0019';
const NO_SELECTABLE_BUSINESS_CARE = '0020';
public static $errors = [
self::WRONG_PARAMETERS => 'Wrong Parameters',
self::WRONG_MODULE_KEY => 'Wrong module key',
self::UNKNOWN_MODULE => 'Unknown module',
self::INVALID_CREDENTIALS => 'Invalid credentials',
self::INVALID_EMAIL_OR_PASSWORD => 'Invalid Email or Password too short',
self::ACCESS_DENIED => 'Access Denied',
self::INVALID_PRODUCT_FILE => 'Invalid product file',
self::TM_CURL_INVALID_LINK => 'Fatal error : CURL on TM link not valid.',
self::TM_INACTIVE_LINK => 'Fatal error : TM link is inactive.',
self::TM_INVALID_ORDER => 'Fatal error : Invalid TM order.',
self::INVALID_METHOD => 'Method doesn\'t exist !',
self::HTTPS_REQUIRED => 'HTTPS Required !',
self::INVALID_AUTH => 'Invalid Authentification.',
self::INVALID_EMAIL => 'Fatal error : Invalid Email.',
self::INVALID_PARAMETERS => 'Invalid Parameters',
self::METHOD_UNDEFINED => 'Fatal error : method is undefined.',
self::KO_LABEL => 'ko',
self::SERVICE_UNAVAILABLE => 'Service unavailable',
self::NO_ZIP_SERVICE => 'No download, Service',
self::WEBSITE_REFUSED => 'Store URL not matching',
self::NO_SELECTABLE_BUSINESS_CARE => 'No selectable support subscription',
];
/**
* @var array
*/
private $context;
/**
* @var string
*/
private $technicalErrorMessage;
public function __construct(ClientException $previous, array $context = [])
{
$addonsError = $this->getErrorSentByAddons($previous);
parent::__construct(
$this->getCustomizedMessage($addonsError),
$addonsError['http_code'] ?? 0,
$previous
);
$context['previous_exception_class'] = get_class($previous);
$context['previous_exception_message'] = $previous->getMessage();
$this->context = $context;
$this->technicalErrorMessage = $addonsError['technical_error_message'];
}
public function getContext(): array
{
return $this->context;
}
public function getTechnicalErrorMessage(): string
{
return $this->technicalErrorMessage;
}
private function getErrorSentByAddons(ClientException $exception): array
{
$rawContent = $exception->getResponse()->getBody()->getContents();
$jsonContent = json_decode($rawContent, true);
$code = self::UNKNOWN_ADDONS_CODE;
if (is_array($jsonContent) && isset($jsonContent['errors']['code'])) {
$code = $jsonContent['errors']['code'];
}
$message = self::$errors[$code] ?? 'No explanation given by Addons';
return [
'message' => $message,
'http_code' => 460 + (int) $code,
'technical_error_message' => self::$errors[$code] ?? 'Addons error',
];
}
private function getCustomizedMessage(array $addonsError): string
{
switch ($addonsError['http_code']) {
case 460 + (int) self::WEBSITE_REFUSED:
return "Your store's URL doesn't match the one provided when the module was purchased.";
case 460 + (int) self::NO_SELECTABLE_BUSINESS_CARE:
return 'You need an active Business Care subscription to download this module.';
default:
return sprintf(
'Cannot download the module from Addons : %s',
$addonsError['message'] ?? 'No further information'
);
}
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,106 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\ExternalContentProvider;
use Closure;
use PrestaShop\CircuitBreaker\FactorySettings;
use PrestaShop\CircuitBreaker\SimpleCircuitBreakerFactory;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ExternalContentProvider implements ExternalContentProviderInterface
{
const ALLOWED_FAILURES = 2;
const TIMEOUT_SECONDS = 0.6;
const THRESHOLD_SECONDS = 3600; // Retry in 1 hour
/**
* @var SimpleCircuitBreakerFactory
*/
private $circuitBreakerFactory;
/**
* @var OptionsResolver
*/
private $optionsResolver;
/**
* Constructor.
*/
public function __construct()
{
$this->circuitBreakerFactory = new SimpleCircuitBreakerFactory();
$this->optionsResolver = new OptionsResolver();
$this->configureOptions();
}
/**
* {@inheritdoc}
*
* @throws ServiceUnavailableHttpException
*/
public function getContent($url, array $options = [])
{
$settings = $this->optionsResolver->resolve($options);
$apiSettings = new FactorySettings(
$settings['failures'],
$settings['timeout'],
$settings['threshold']
);
$circuitBreaker = $this->circuitBreakerFactory->create($apiSettings);
return $circuitBreaker->call(
$url,
$settings['client_options'],
$this->circuitBreakerFallback()
);
}
private function configureOptions()
{
$this->optionsResolver->setDefaults([
'failures' => self::ALLOWED_FAILURES,
'timeout' => self::TIMEOUT_SECONDS,
'threshold' => self::THRESHOLD_SECONDS,
'client_options' => [],
]);
$this->optionsResolver->setAllowedTypes('failures', 'numeric');
$this->optionsResolver->setAllowedTypes('timeout', 'numeric');
$this->optionsResolver->setAllowedTypes('threshold', 'numeric');
$this->optionsResolver->setAllowedTypes('client_options', 'array');
}
/**
* Called by CircuitBreaker if the service is unavailable
*
* @return Closure
*/
private function circuitBreakerFallback()
{
return function () {
throw new ServiceUnavailableHttpException(self::THRESHOLD_SECONDS);
};
}
}

View File

@@ -0,0 +1,32 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\ExternalContentProvider;
interface ExternalContentProviderInterface
{
/**
* @param string $url
* @param array $options
*
* @return string
*/
public function getContent($url, array $options = []);
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,35 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
declare(strict_types=1);
namespace PrestaShop\Module\Mbo\Handler\ErrorHandler;
use Exception;
class ErrorHandler implements ErrorHandlerInterface
{
/**
* {@inheritDoc}
*/
public function handle(Exception $error, ?array $data = []): void
{
// Do nothing here, Just prepare the field for Sentry or other error reporter
}
}

View File

@@ -0,0 +1,32 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Handler\ErrorHandler;
use Exception;
interface ErrorHandlerInterface
{
/**
* @param Exception $error
* @param array|null $data
*/
public function handle(Exception $error, ?array $data = null): void;
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,41 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
declare(strict_types=1);
namespace PrestaShop\Module\Mbo\Helpers;
class AddonsApiHelper
{
/**
* @return array
*/
public static function addCustomHeaderIfNeeded()
{
$customHeaderKey = getenv('ADDONS_API_HEADER_KEY');
$customHeaderValue = getenv('ADDONS_API_HEADER_VALUE');
if (empty($customHeaderKey) || empty($customHeaderValue)) {
return [];
}
return [$customHeaderKey => $customHeaderValue];
}
}

View File

@@ -0,0 +1,194 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Helpers;
use Configuration;
use Shop;
class Config
{
const AVAILABLE_SHOP_ACTIVITIES = [
1 => 'Lingerie and Adult',
2 => 'Animals and Pets',
3 => 'Art and Culture',
4 => 'Babies',
5 => 'Beauty and Personal Care',
6 => 'Cars',
7 => 'Computer Hardware and Software',
8 => 'Download',
9 => 'Fashion and accessories',
10 => 'Flowers, Gifts and Crafts',
11 => 'Food and beverage',
12 => 'HiFi, Photo and Video',
13 => 'Home and Garden',
14 => 'Home Appliances',
15 => 'Jewelry',
16 => 'Mobile and Telecom',
17 => 'Services',
18 => 'Shoes and accessories',
19 => 'Sport and Entertainment',
20 => 'Travel',
];
/**
* @var string|null
*/
private static $SHOP_MBO_UUID;
/**
* @var string|null
*/
private static $SHOP_URL;
public static function resetConfigValues()
{
self::$SHOP_MBO_UUID = null;
self::$SHOP_URL = null;
}
/**
* @return false|string|null
*/
public static function getShopMboUuid()
{
if (null === self::$SHOP_MBO_UUID) {
// PS_MBO_SHOP_ADMIN_UUID have the same value for all shops
// to prevent errors in a multishop context,
// we request the shops list and get the config value for the 1st one
$singleShop = self::getDefaultShop();
self::$SHOP_MBO_UUID = Configuration::get(
'PS_MBO_SHOP_ADMIN_UUID',
null,
$singleShop->id_shop_group,
$singleShop->id,
null
);
}
return self::$SHOP_MBO_UUID;
}
/**
* The Tools::usingSecureMode used by Shop::getBaseUrl seems to not work in all situations
* To be sure to have the correct data, use shop configuration
*
* @return string|null
*/
public static function getShopUrl()
{
if (null === self::$SHOP_URL) {
$singleShop = self::getDefaultShop();
$domains = \Tools::getDomains();
$shopDomain = array_filter(
$domains,
function ($domain) use ($singleShop) {
// Here we assume that every shop have a single domain (?)
$domain = reset($domain);
return isset($domain['id_shop']) && (int) $singleShop->id === (int) $domain['id_shop'];
}
);
$useSecureProtocol = self::isUsingSecureProtocol();
if (empty($shopDomain)) {
$domainConfigKey = $useSecureProtocol ? 'PS_SHOP_DOMAIN_SSL' : 'PS_SHOP_DOMAIN';
$domain = Configuration::get(
$domainConfigKey,
null,
$singleShop->id_shop_group,
$singleShop->id
);
if ($domain) {
$domain = preg_replace('#(https?://)#', '', $domain);
self::$SHOP_URL = ($useSecureProtocol ? 'https://' : 'http://') . $domain;
}
} else {
$domain = array_keys($shopDomain)[0];
$domain = preg_replace('#(https?://)#', '', $domain);
// concatenate the physical_uri
$domainDef = reset($shopDomain[$domain]);
if (isset($domainDef['physical']) && '/' !== $domainDef['physical']) {
$domain .= $domainDef['physical'];
}
self::$SHOP_URL = ($useSecureProtocol ? 'https://' : 'http://') . $domain;
}
}
return self::$SHOP_URL;
}
/**
* @return bool
*/
public static function isUsingSecureProtocol()
{
$singleShop = self::getDefaultShop();
return (bool) Configuration::get(
'PS_SSL_ENABLED',
null,
$singleShop->id_shop_group,
$singleShop->id
);
}
/**
* @return array
*/
public static function getShopActivity(): array
{
$singleShop = self::getDefaultShop();
$activity = [
'id' => null,
'name' => null,
];
$activityId = (int) Configuration::get(
'PS_SHOP_ACTIVITY',
null,
$singleShop->id_shop_group,
$singleShop->id,
null
);
if (empty($activityId)) {
return $activity;
}
$activity['id'] = $activityId;
$activity['name'] = self::AVAILABLE_SHOP_ACTIVITIES[$activityId] ?? 'Unknown';
return $activity;
}
/**
* @return Shop
*/
private static function getDefaultShop()
{
return new Shop((int) Configuration::get('PS_SHOP_DEFAULT'));
}
}

View File

@@ -0,0 +1,48 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
declare(strict_types=1);
namespace PrestaShop\Module\Mbo\Helpers;
use PrestaShop\Module\Mbo\Handler\ErrorHandler\ErrorHandler;
use PrestaShop\Module\Mbo\Handler\ErrorHandler\ErrorHandlerInterface;
class ErrorHelper
{
/**
* @var ErrorHandlerInterface
*/
private static $errorHandler;
/**
* @param \Exception $error
* @param array|null $data
*
* @return void
*/
public static function reportError(\Exception $error, ?array $data = null): void
{
if (!self::$errorHandler instanceof ErrorHandlerInterface) {
self::$errorHandler = new ErrorHandler();
}
self::$errorHandler->handle($error, $data);
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,136 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo;
use Module;
use PrestaShop\PrestaShop\Adapter\LegacyContext;
use PrestaShop\PrestaShop\Adapter\Module\AdminModuleDataProvider;
use PrestaShop\PrestaShop\Adapter\Presenter\PresenterInterface;
use PrestaShop\PrestaShop\Core\Addon\AddonsCollection;
use PrestaShop\PrestaShop\Core\Addon\Module\ModuleRepository;
use PrestaShop\PrestaShop\Core\Addon\Module\ModuleRepositoryInterface;
use PrestaShopBundle\Entity\Repository\TabRepository;
use Profile;
class ModuleCollectionDataProvider
{
/**
* @var AdminModuleDataProvider
*/
private $addonsProvider;
/**
* @var ModuleRepositoryInterface
*/
private $moduleRepository;
/**
* @var PresenterInterface
*/
private $modulePresenter;
/**
* @var TabRepository
*/
private $tabRepository;
/**
* @var LegacyContext
*/
private $context;
/**
* Constructor.
*
* @param AdminModuleDataProvider $addonsProvider
* @param ModuleRepositoryInterface $moduleRepository
* @param PresenterInterface $modulePresenter
* @param TabRepository $tabRepository
* @param LegacyContext $context
*/
public function __construct(
AdminModuleDataProvider $addonsProvider,
ModuleRepositoryInterface $moduleRepository,
PresenterInterface $modulePresenter,
TabRepository $tabRepository,
LegacyContext $context
) {
$this->addonsProvider = $addonsProvider;
$this->moduleRepository = $moduleRepository;
$this->modulePresenter = $modulePresenter;
$this->tabRepository = $tabRepository;
$this->context = $context;
}
/**
* @param array $moduleNames
*
* @return array
*/
public function getData(array $moduleNames)
{
$data = [];
$modulesOnDisk = AddonsCollection::createFrom($this->moduleRepository->getList());
$modulesOnDisk = $this->addonsProvider->generateAddonsUrls($modulesOnDisk);
foreach ($modulesOnDisk as $module) {
/** @var \PrestaShop\PrestaShop\Adapter\Module\Module $module */
if (!in_array($module->get('name'), $moduleNames)) {
continue;
}
if ($module->get('id')) {
$isEmployeeAllowed = (bool) Module::getPermissionStatic(
$module->get('id'),
'configure',
$this->context->getContext()->employee
);
} else {
$ModuleTabId = $this->tabRepository->findOneIdByClassName('AdminModules');
/** @var array $access */
$access = Profile::getProfileAccess(
$this->context->getContext()->employee->id_profile,
$ModuleTabId
);
$isEmployeeAllowed = !$access['edit'];
}
if (false === $isEmployeeAllowed) {
continue;
}
if ($module->get('author') === ModuleRepository::PARTNER_AUTHOR) {
$module->set('type', 'addonsPartner');
}
if (!empty($module->get('description'))) {
$module->set('description', html_entity_decode($module->get('description'), ENT_QUOTES));
}
$module->fillLogo();
$data[$module->get('name')] = $this->modulePresenter->present($module);
}
return $data;
}
}

View File

@@ -0,0 +1,77 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\RecommendedLink;
class RecommendedLink implements RecommendedLinkInterface
{
/**
* @var string
*/
private $id;
/**
* @var string
*/
private $url;
/**
* @var string
*/
private $name;
/**
* RecommendedLink constructor.
*
* @param string $id
* @param string $url
* @param string $name
*/
public function __construct($id, $url, $name)
{
$this->id = $id;
$this->url = $url;
$this->name = $name;
}
/**
* {@inheritdoc}
*/
public function getId()
{
return $this->id;
}
/**
* {@inheritdoc}
*/
public function getUrl()
{
return $this->url;
}
/**
* {@inheritdoc}
*/
public function getName()
{
return $this->name;
}
}

View File

@@ -0,0 +1,45 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\RecommendedLink;
interface RecommendedLinkInterface
{
/**
* Get the identifier of the recommended link.
*
* @return string
*/
public function getId();
/**
* Get the url of the recommended module.
*
* @return string
*/
public function getUrl();
/**
* Get the display name of the recommended module.
*
* @return string
*/
public function getName();
}

View File

@@ -0,0 +1,98 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\RecommendedLink;
use PrestaShop\PrestaShop\Adapter\LegacyContext;
use Symfony\Component\Serializer\SerializerInterface;
class RecommendedLinkProvider
{
/**
* @var LegacyContext
*/
private $context;
/**
* @var SerializerInterface
*/
private $serializer;
/**
* Constructor.
*
* @param SerializerInterface $serializer
* @param LegacyContext $context
*/
public function __construct(
LegacyContext $context,
SerializerInterface $serializer
) {
$this->context = $context;
$this->serializer = $serializer;
}
/**
* @return RecommendedLink[]
*/
public function getRecommendedLinks()
{
$recommendedLinks = [];
$cacheFile = $this->getCacheFile();
if ($cacheFile) {
$recommendedLinks = $this->serializer->deserialize(
file_get_contents($cacheFile),
sprintf('%s[]', RecommendedLink::class),
'json'
);
}
return $recommendedLinks;
}
/**
* Search a cache associated to context language or try to fallback to default locale
*
* @return string
*/
private function getCacheFile()
{
$cacheFile = _PS_MODULE_DIR_
. 'ps_mbo/cache/recommended-links-'
. strtolower($this->context->getContext()->language->iso_code)
. '.json'
;
if (file_exists($cacheFile)) {
return $cacheFile;
}
$cacheFile = _PS_MODULE_DIR_
. 'ps_mbo/cache/recommended-links-en.json'
;
if (file_exists($cacheFile)) {
return $cacheFile;
}
return '';
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,116 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\RecommendedModule;
class RecommendedModule implements RecommendedModuleInterface
{
/**
* @var string technical name of the recommended module
*/
private $moduleName;
/**
* @var int position of the recommended module
*/
private $position;
/**
* @var bool
*/
private $isInstalled;
/**
* @var array
*/
private $moduleData;
/**
* {@inheritdoc}
*/
public function getModuleName()
{
return $this->moduleName;
}
/**
* {@inheritdoc}
*/
public function setModuleName($moduleName)
{
$this->moduleName = $moduleName;
return $this;
}
/**
* {@inheritdoc}
*/
public function getPosition()
{
return $this->position;
}
/**
* {@inheritdoc}
*/
public function setPosition($position)
{
$this->position = $position;
return $this;
}
/**
* {@inheritdoc}
*/
public function isInstalled()
{
return $this->isInstalled;
}
/**
* {@inheritdoc}
*/
public function setInstalled($isInstalled)
{
$this->isInstalled = $isInstalled;
return $this;
}
/**
* {@inheritdoc}
*/
public function getModuleData()
{
return $this->moduleData;
}
/**
* {@inheritdoc}
*/
public function setModuleData($moduleData)
{
$this->moduleData = $moduleData;
return $this;
}
}

View File

@@ -0,0 +1,192 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\RecommendedModule;
use ArrayIterator;
use Closure;
class RecommendedModuleCollection implements RecommendedModuleCollectionInterface
{
/**
* @var RecommendedModuleInterface[]
*/
private $recommendedModules = [];
/**
* {@inheritdoc}
*/
public function addRecommendedModule(RecommendedModuleInterface $recommendedModule)
{
$this->recommendedModules[] = $recommendedModule;
return $this;
}
/**
* {@inheritdoc}
*/
public function getRecommendedModule($moduleName)
{
foreach ($this->recommendedModules as $recommendedModule) {
if ($moduleName === $recommendedModule->getModuleName()) {
return $recommendedModule;
}
}
return false;
}
/**
* {@inheritdoc}
*/
public function getRecommendedModuleNames()
{
$recommendedModuleNames = [];
foreach ($this->recommendedModules as $recommendedModule) {
$recommendedModuleNames[] = $recommendedModule->getModuleName();
}
return $recommendedModuleNames;
}
/**
* {@inheritdoc}
*/
public function offsetExists($offset)
{
return array_key_exists($offset, $this->recommendedModules);
}
/**
* {@inheritdoc}
*/
public function offsetGet($offset)
{
return $this->recommendedModules[$offset];
}
/**
* {@inheritdoc}
*/
public function offsetSet($offset, $value)
{
$this->recommendedModules[$offset] = $value;
}
/**
* {@inheritdoc}
*/
public function offsetUnset($offset)
{
unset($this->recommendedModules[$offset]);
}
/**
* {@inheritdoc}
*/
public function getIterator()
{
return new ArrayIterator($this->recommendedModules);
}
/**
* {@inheritdoc}
*/
public function count()
{
return count($this->recommendedModules);
}
/**
* {@inheritdoc}
*/
public function isEmpty()
{
return empty($this->recommendedModules);
}
/**
* {@inheritdoc}
*/
public function sortByPosition()
{
$this->sort(function (
RecommendedModuleInterface $recommendedModuleA,
RecommendedModuleInterface $recommendedModuleB
) {
if ($recommendedModuleA->getPosition() === $recommendedModuleB->getPosition()) {
return 0;
}
return ($recommendedModuleA->getPosition() < $recommendedModuleB->getPosition()) ? -1 : 1;
});
}
/**
* {@inheritdoc}
*/
public function getInstalled()
{
return $this->filter(function (RecommendedModuleInterface $recommendedModule) {
return $recommendedModule->isInstalled();
});
}
/**
* {@inheritdoc}
*/
public function getNotInstalled()
{
return $this->filter(function (RecommendedModuleInterface $recommendedModule) {
return !$recommendedModule->isInstalled();
});
}
/**
* @param Closure $closure
*
* @return RecommendedModuleCollection
*/
private function filter(Closure $closure)
{
$recommendedModules = new static();
$recommendedModules->recommendedModules = array_filter(
$this->recommendedModules,
$closure,
ARRAY_FILTER_USE_BOTH
);
$recommendedModules->sortByPosition();
return $recommendedModules;
}
/**
* @param Closure $closure
*/
private function sort(Closure $closure)
{
uasort(
$this->recommendedModules,
$closure
);
}
}

View File

@@ -0,0 +1,84 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\RecommendedModule;
use ArrayAccess;
use Countable;
use IteratorAggregate;
interface RecommendedModuleCollectionInterface extends ArrayAccess, IteratorAggregate, Countable
{
/**
* Add a recommended module to this collection.
*
* @param RecommendedModuleInterface $recommendedModule
*
* @return self
*/
public function addRecommendedModule(RecommendedModuleInterface $recommendedModule);
/**
* Get a recommended module by name
*
* @param string $moduleName
*
* @return RecommendedModuleInterface|false
*/
public function getRecommendedModule($moduleName);
/**
* Get names of recommended modules
*
* @return string[]
*/
public function getRecommendedModuleNames();
/**
* @param mixed $offset
*
* @return RecommendedModuleInterface
*/
public function offsetGet($offset);
/**
* @return bool
*/
public function isEmpty();
/**
* Sort recommended modules by position
*/
public function sortByPosition();
/**
* Get recommended modules installed.
*
* @return RecommendedModuleCollectionInterface
*/
public function getInstalled();
/**
* Get recommended modules not installed.
*
* @return RecommendedModuleCollectionInterface
*/
public function getNotInstalled();
}

View File

@@ -0,0 +1,80 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\RecommendedModule;
interface RecommendedModuleInterface
{
/**
* Get the technical name of the recommended module.
*
* @return string
*/
public function getModuleName();
/**
* @param string $moduleName
*
* @return RecommendedModuleInterface
*/
public function setModuleName($moduleName);
/**
* Get the position of the recommended module.
*
* @return int
*/
public function getPosition();
/**
* @param int $position
*
* @return RecommendedModuleInterface
*/
public function setPosition($position);
/**
* Check if the recommended modules is installed.
*
* @return bool
*/
public function isInstalled();
/**
* @param bool $isInstalled
*
* @return RecommendedModuleInterface
*/
public function setInstalled($isInstalled);
/**
* Get the recommended module data.
*
* @return array
*/
public function getModuleData();
/**
* @param array $moduleData
*
* @return RecommendedModuleInterface
*/
public function setModuleData($moduleData);
}

View File

@@ -0,0 +1,46 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\RecommendedModule;
class RecommendedModulePresenter implements RecommendedModulePresenterInterface
{
/**
* {@inheritdoc}
*/
public function present(RecommendedModuleInterface $recommendedModule)
{
return $recommendedModule->getModuleData();
}
/**
* {@inheritdoc}
*/
public function presentCollection(RecommendedModuleCollectionInterface $recommendedModules)
{
$recommendedModulesPresented = [];
foreach ($recommendedModules as $recommendedModule) {
$recommendedModulesPresented[] = $this->present($recommendedModule);
}
return $recommendedModulesPresented;
}
}

View File

@@ -0,0 +1,42 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\RecommendedModule;
interface RecommendedModulePresenterInterface
{
/**
* Transform a RecommendedModuleInterface as a simple array of data.
*
* @param RecommendedModuleInterface $recommendedModule
*
* @return array
*/
public function present(RecommendedModuleInterface $recommendedModule);
/**
* Transform a collection of RecommendedModulesInterface as a simple array of data.
*
* @param RecommendedModuleCollectionInterface $recommendedModules
*
* @return array
*/
public function presentCollection(RecommendedModuleCollectionInterface $recommendedModules);
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,113 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
declare(strict_types=1);
namespace PrestaShop\Module\Mbo\Service;
use PrestaShop\PrestaShop\Core\Addon\Module\ModuleManagerBuilder;
class ModuleInstaller
{
private $moduleName;
private $moduleVersion;
private $absoluteCompare;
private $moduleManager;
/**
* @param string $moduleName
* @param string|null $moduleVersion
* @param bool $absoluteCompare
*/
public function __construct(string $moduleName, string $moduleVersion = null, bool $absoluteCompare = false)
{
$this->moduleName = $moduleName;
$this->moduleVersion = $moduleVersion;
$this->absoluteCompare = $absoluteCompare;
$moduleManagerBuilder = ModuleManagerBuilder::getInstance();
$this->moduleManager = $moduleManagerBuilder->build();
}
/**
* Install ps_accounts module if not installed
* Method to call in every psx modules during the installation process
*
* @return bool
*
* @throws \Exception
*/
public function install()
{
if ($this->isModuleInstalled() && $this->isModuleVersionSatisfied()) {
return true;
}
return $this->moduleManager->install($this->moduleName);
}
/**
* @return bool
*/
public function enable()
{
if (!$this->moduleManager->isEnabled($this->moduleName)) {
return $this->moduleManager->enable($this->moduleName);
}
return true;
}
/**
* @return bool
*/
public function isShopVersion17()
{
/* @SuppressWarnings("php:S1313") */
return version_compare(_PS_VERSION_, '1.7.0.0', '>=');
}
/**
* @return bool
*/
public function isModuleInstalled()
{
if (false === $this->isShopVersion17()) {
return \Module::isInstalled($this->moduleName);
}
return $this->moduleManager->isInstalled($this->moduleName);
}
/**
* @return bool
*/
public function isModuleVersionSatisfied()
{
if (!$this->moduleVersion) {
return true;
}
$module = \Module::getInstanceByName($this->moduleName);
return version_compare(
$module->version,
$this->moduleVersion,
$this->absoluteCompare ? '>' : '>='
);
}
}

View File

@@ -0,0 +1,311 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Service\View;
use Configuration;
use Context;
use Country;
use Doctrine\Common\Cache\CacheProvider;
use Language;
use PrestaShop\Module\Mbo\Accounts\Provider\AccountsDataProvider;
use PrestaShop\Module\Mbo\Distribution\AuthenticationProvider;
use PrestaShop\Module\Mbo\Helpers\Config;
use PrestaShop\PrestaShop\Adapter\LegacyContext as ContextAdapter;
use PrestaShop\PrestaShop\Adapter\Module\Module as CoreModule;
use PrestaShop\PrestaShop\Core\Addon\Module\ModuleRepository;
use Symfony\Component\Routing\Router;
use Tools;
class ContextBuilder
{
const DEFAULT_CURRENCY_CODE = 'EUR';
const STATUS_UNINSTALLED = 'uninstalled';
const STATUS_ENABLED__MOBILE_ENABLED = 'enabled__mobile_enabled';
const STATUS_ENABLED__MOBILE_DISABLED = 'enabled__mobile_disabled';
const STATUS_DISABLED__MOBILE_ENABLED = 'disabled__mobile_enabled';
const STATUS_DISABLED__MOBILE_DISABLED = 'disabled__mobile_disabled';
const STATUS_RESET = 'reset'; //virtual status
const STATUS_UPGRADED = 'upgraded'; //virtual status
const STATUS_CONFIGURED = 'configured'; //virtual status
/**
* @var ContextAdapter
*/
private $contextAdapter;
/**
* @var ModuleRepository
*/
private $moduleRepository;
/**
* @var Router
*/
private $router;
/**
* @var CacheProvider
*/
private $cacheProvider;
/**
* @var AuthenticationProvider
*/
private $distributionAuthenticationProvider;
/**
* @var AccountsDataProvider
*/
private $accountsDataProvider;
public function __construct(
ContextAdapter $contextAdapter,
ModuleRepository $moduleRepository,
Router $router,
AuthenticationProvider $distributionAuthenticationProvider,
CacheProvider $cacheProvider,
AccountsDataProvider $accountsDataProvider
) {
$this->contextAdapter = $contextAdapter;
$this->moduleRepository = $moduleRepository;
$this->router = $router;
$this->distributionAuthenticationProvider = $distributionAuthenticationProvider;
$this->cacheProvider = $cacheProvider;
$this->accountsDataProvider = $accountsDataProvider;
}
/**
* @return array
*/
public function getViewContext()
{
$context = $this->getCommonContextContent();
$context['prestaShop_controller_class_name'] = Tools::getValue('controller');
return $context;
}
/**
* @return bool
*/
public function clearCache()
{
$cacheKey = $this->getCacheKey();
if ($this->cacheProvider->contains($cacheKey)) {
if (!$this->cacheProvider->delete($cacheKey)) {
return false;
}
}
return true;
}
/**
* @return array
*/
private function getCommonContextContent()
{
$context = $this->getContext();
$language = $this->getLanguage();
$country = $this->getCountry();
$psMbo = \Module::getInstanceByName('ps_mbo');
$psMboVersion = false;
if (\Validate::isLoadedObject($psMbo)) {
$psMboVersion = $psMbo->version;
}
$token = Tools::getValue('_token');
if (false === $token) {
$token = Tools::getValue('token');
}
$refreshUrl = $this->router->generate('admin_mbo_security');
$shopUuid = Config::getShopMboUuid();
$shopActivity = Config::getShopActivity();
return [
'currency' => $this->getCurrencyCode(),
'iso_lang' => $language->iso_code,
'iso_code' => mb_strtolower($country->iso_code),
'shop_version' => _PS_VERSION_,
'shop_url' => Config::getShopUrl(),
'shop_uuid' => $shopUuid,
'mbo_token' => $this->distributionAuthenticationProvider->getMboJWT(),
'mbo_version' => $psMboVersion,
'mbo_reset_url' => $this->router->generate('admin_module_manage_action', [
'action' => 'reset',
'module_name' => 'ps_mbo',
]),
'user_id' => $context->cookie->id_employee,
'admin_token' => $token,
'refresh_url' => $refreshUrl,
'installed_modules' => $this->getInstalledModules(),
'accounts_user_id' => $this->accountsDataProvider->getAccountsUserId(),
'accounts_shop_id' => $this->accountsDataProvider->getAccountsShopId(),
'accounts_token' => $this->accountsDataProvider->getAccountsToken(),
'accounts_component_loaded' => false,
'module_catalog_url' => $this->router->generate('admin_mbo_catalog_module'),
'theme_catalog_url' => $this->router->generate('admin_mbo_catalog_theme'),
'php_version' => phpversion(),
'shop_creation_date' => defined('_PS_CREATION_DATE_') ? _PS_CREATION_DATE_ : null,
'shop_business_sector_id' => $shopActivity['id'],
'shop_business_sector' => $shopActivity['name'],
];
}
/**
* @return Context|null
*/
private function getContext()
{
return $this->contextAdapter->getContext();
}
/**
* @return Language
*
* @throws \PrestaShopDatabaseException
* @throws \PrestaShopException
*/
private function getLanguage()
{
return null !== $this->getContext() ? $this->getContext()->language : new Language((int) Configuration::get('PS_LANG_DEFAULT'));
}
/**
* @return Country
*
* @throws \PrestaShopDatabaseException
* @throws \PrestaShopException
*/
private function getCountry()
{
return null !== $this->getContext() ? $this->getContext()->country : new Country((int) Configuration::get('PS_COUNTRY_DEFAULT'));
}
/**
* @return string
*/
private function getCurrencyCode()
{
if (null === $this->getContext()) {
return self::DEFAULT_CURRENCY_CODE;
}
$currency = $this->getContext()->currency;
if (\Validate::isLoadedObject($currency) || !in_array($currency->iso_code, ['EUR', 'USD', 'GBP'])) {
return self::DEFAULT_CURRENCY_CODE;
}
return $currency->iso_code;
}
/**
* @return array<array>
*/
private function getInstalledModules()
{
$cacheKey = $this->getCacheKey();
if ($this->cacheProvider->contains($cacheKey)) {
return $this->cacheProvider->fetch($cacheKey);
}
$installedModulesCollection = $this->moduleRepository->getInstalledModulesCollection();
$installedModules = [];
/** @var CoreModule $installedModule */
foreach ($installedModulesCollection as $installedModule) {
$moduleAttributes = $installedModule->attributes;
$moduleDiskAttributes = $installedModule->disk;
$moduleDatabaseAttributes = $installedModule->database;
$module = $installedModule;
$moduleId = (int) $module->get('id');
$moduleName = $module->get('name');
$moduleStatus = $this->getModuleStatus($module);
$moduleVersion = $module->get('version');
$moduleConfigUrl = null;
if (!$moduleName || !$moduleVersion) {
continue;
}
if (true === (bool) $module->get('is_configurable')) {
$moduleConfigUrl = $this->router->generate('admin_module_configure_action', [
'module_name' => $moduleName,
]);
}
$installedModules[] = (new InstalledModule($moduleId, $moduleName, $moduleStatus, (string) $moduleVersion, $moduleConfigUrl))->toArray();
}
$this->cacheProvider->save($cacheKey, $installedModules, 86400); // Lifetime for 24h, will be purged at every action on modules
return $this->cacheProvider->fetch($cacheKey);
}
/**
* @return string
*/
private function getCacheKey()
{
return sprintf('mbo_installed_modules_list_%s', Config::getShopMboUuid());
}
/**
* @param CoreModule $module
*
* @return string
*/
private function getModuleStatus(CoreModule $module)
{
$installed = (bool) $module->database->get('installed');
$active = (bool) $module->database->get('active');
$activeOnMobile = (bool) $module->database->get('active_on_mobile');
if (!$installed) {
return self::STATUS_UNINSTALLED;
}
if ($active && $activeOnMobile) {
return self::STATUS_ENABLED__MOBILE_ENABLED;
}
if ($active && !$activeOnMobile) {
return self::STATUS_ENABLED__MOBILE_DISABLED;
}
if (!$active && $activeOnMobile) {
return self::STATUS_DISABLED__MOBILE_ENABLED;
}
return self::STATUS_DISABLED__MOBILE_DISABLED;
}
}

View File

@@ -0,0 +1,74 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Service\View;
class InstalledModule
{
/**
* @var int
*/
private $id;
/**
* @var string
*/
private $name;
/**
* @var string
*/
private $status;
/**
* @var string
*/
private $version;
/**
* @var string|null
*/
private $configUrl;
public function __construct(
int $id,
string $name,
string $status,
string $version,
string $configUrl = null
) {
$this->id = $id;
$this->name = $name;
$this->status = $status;
$this->version = $version;
$this->configUrl = $configUrl;
}
public function toArray()
{
return [
'id' => $this->id,
'name' => $this->name,
'status' => $this->status,
'version' => $this->version,
'config_url' => $this->configUrl,
];
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,158 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Tab;
use PrestaShop\Module\Mbo\RecommendedModule\RecommendedModuleCollection;
use PrestaShop\Module\Mbo\RecommendedModule\RecommendedModuleCollectionInterface;
class Tab implements TabInterface
{
/**
* @var string class name of the tab
*/
private $legacyClassName;
/**
* @var string class name of the tab
*/
private $displayMode;
/**
* @var RecommendedModuleCollectionInterface recommended modules of the tab
*/
private $recommendedModules;
/**
* Tab constructor.
*/
public function __construct()
{
$this->recommendedModules = new RecommendedModuleCollection();
}
/**
* {@inheritdoc}
*/
public function getLegacyClassName()
{
return $this->legacyClassName;
}
/**
* {@inheritdoc}
*/
public function setLegacyClassName($legacyClassName)
{
$this->legacyClassName = $legacyClassName;
return $this;
}
/**
* {@inheritdoc}
*/
public function getDisplayMode()
{
return $this->displayMode;
}
/**
* {@inheritdoc}
*/
public function setDisplayMode($displayMode)
{
$this->displayMode = $displayMode;
return $this;
}
/**
* {@inheritdoc}
*/
public function getRecommendedModules()
{
return $this->recommendedModules;
}
/**
* {@inheritdoc}
*/
public function setRecommendedModules(RecommendedModuleCollectionInterface $recommendedModules)
{
$this->recommendedModules = $recommendedModules;
return $this;
}
/**
* {@inheritdoc}
*/
public function hasRecommendedModules()
{
return !$this->recommendedModules->isEmpty();
}
/**
* {@inheritdoc}
*/
public function getRecommendedModulesInstalled()
{
$recommendedModulesInstalled = $this->getRecommendedModules();
if ($this->hasRecommendedModules()) {
return $recommendedModulesInstalled->getInstalled();
}
return $recommendedModulesInstalled;
}
/**
* {@inheritdoc}
*/
public function getRecommendedModulesNotInstalled()
{
$recommendedModulesNotInstalled = $this->getRecommendedModules();
if ($this->hasRecommendedModules()) {
return $recommendedModulesNotInstalled->getNotInstalled();
}
return $recommendedModulesNotInstalled;
}
/**
* {@inheritdoc}
*/
public function shouldDisplayButton()
{
return $this->hasRecommendedModules()
&& TabInterface::DISPLAY_MODE_MODAL === $this->getDisplayMode();
}
/**
* {@inheritdoc}
*/
public function shouldDisplayAfterContent()
{
return $this->hasRecommendedModules()
&& TabInterface::DISPLAY_MODE_AFTER_CONTENT === $this->getDisplayMode();
}
}

View File

@@ -0,0 +1,111 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Tab;
use ArrayIterator;
class TabCollection implements TabCollectionInterface
{
/**
* @var TabInterface[]
*/
private $tabs = [];
/**
* {@inheritdoc}
*/
public function addTab(TabInterface $tab)
{
$this->tabs[] = $tab;
return $this;
}
/**
* {@inheritdoc}
*/
public function getTab($tabClassName)
{
foreach ($this->tabs as $tab) {
if ($tabClassName === $tab->getLegacyClassName()) {
return $tab;
}
}
return new Tab();
}
/**
* {@inheritdoc}
*/
public function offsetExists($offset)
{
return array_key_exists($offset, $this->tabs);
}
/**
* {@inheritdoc}
*/
public function offsetSet($offset, $value)
{
$this->tabs[$offset] = $value;
}
/**
* {@inheritdoc}
*/
public function offsetGet($offset)
{
return $this->tabs[$offset];
}
/**
* {@inheritdoc}
*/
public function offsetUnset($offset)
{
unset($this->tabs[$offset]);
}
/**
* {@inheritdoc}
*/
public function getIterator()
{
return new ArrayIterator($this->tabs);
}
/**
* {@inheritdoc}
*/
public function count()
{
return count($this->tabs);
}
/**
* {@inheritdoc}
*/
public function isEmpty()
{
return empty($this->tabs);
}
}

View File

@@ -0,0 +1,83 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Tab;
class TabCollectionDecoderXml
{
private $content;
/**
* Constructor.
*
* @param string $content
*/
public function __construct($content)
{
$this->content = $content;
}
/**
* @return array
*/
public function toArray()
{
$data = [];
if (empty($this->content)) {
return $data;
}
$simpleXMLElement = @simplexml_load_string($this->content);
if (false === $simpleXMLElement
|| !isset($simpleXMLElement->tab)
) {
return $data;
}
foreach ($simpleXMLElement->tab as $tab) {
$tabClassName = null;
$tabDisplayMode = 'slider_list';
$tabRecommendedModules = [];
foreach ($tab->attributes() as $key => $value) {
if ('class_name' === $key) {
$tabClassName = (string) $value;
}
if ('display_type' === $key) {
$tabDisplayMode = (string) $value;
}
}
foreach ($tab->children() as $module) {
if (isset($module['position'], $module['name'])) {
$tabRecommendedModules[(int) $module['position']] = (string) $module['name'];
}
}
if (!empty($tabClassName)) {
$data[$tabClassName] = [
'displayMode' => $tabDisplayMode,
'recommendedModules' => $tabRecommendedModules,
];
}
}
return $data;
}
}

View File

@@ -0,0 +1,104 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Tab;
use PrestaShop\Module\Mbo\ModuleCollectionDataProvider;
use PrestaShop\Module\Mbo\RecommendedModule\RecommendedModule;
use PrestaShop\Module\Mbo\RecommendedModule\RecommendedModuleCollection;
class TabCollectionFactory implements TabCollectionFactoryInterface
{
private $moduleCollectionDataProvider;
/**
* Constructor.
*
* @param ModuleCollectionDataProvider $moduleCollectionDataProvider
*/
public function __construct(ModuleCollectionDataProvider $moduleCollectionDataProvider)
{
$this->moduleCollectionDataProvider = $moduleCollectionDataProvider;
}
/**
* {@inheritdoc}
*/
public function buildFromArray(array $data)
{
$tabCollection = new TabCollection();
if (empty($data)) {
return $tabCollection;
}
$modulesData = $this->moduleCollectionDataProvider->getData($this->getModuleNames($data));
if (empty($modulesData)) {
return $tabCollection;
}
foreach ($data as $tabClassName => $tabData) {
$recommendedModuleCollection = new RecommendedModuleCollection();
foreach ($tabData['recommendedModules'] as $position => $moduleName) {
if (isset($modulesData[$moduleName])) {
$recommendedModule = new RecommendedModule();
$recommendedModule->setModuleName($moduleName);
$recommendedModule->setPosition((int) $position);
$recommendedModule->setInstalled((bool) $modulesData[$moduleName]['database']['installed']);
$recommendedModule->setModuleData($modulesData[$moduleName]);
$recommendedModuleCollection->addRecommendedModule($recommendedModule);
}
}
if (!$recommendedModuleCollection->isEmpty()) {
$recommendedModuleCollection->sortByPosition();
$tab = new Tab();
$tab->setLegacyClassName($tabClassName);
$tab->setDisplayMode($tabData['displayMode']);
$tab->setRecommendedModules($recommendedModuleCollection);
$tabCollection->addTab($tab);
}
}
return $tabCollection;
}
/**
* @param array $data
*
* @return string[]
*/
private function getModuleNames(array $data)
{
$moduleNames = [];
foreach ($data as $tabData) {
foreach ($tabData['recommendedModules'] as $moduleName) {
$moduleNames[] = $moduleName;
}
}
return array_unique($moduleNames);
}
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Tab;
interface TabCollectionFactoryInterface
{
/**
* Builds a tabs recommended modules collection from an array.
*
* @param array $data
*
* @return TabCollectionInterface
*/
public function buildFromArray(array $data);
}

View File

@@ -0,0 +1,56 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Tab;
use ArrayAccess;
use Countable;
use IteratorAggregate;
interface TabCollectionInterface extends ArrayAccess, IteratorAggregate, Countable
{
/**
* Add a tab to this collection.
*
* @param TabInterface $tab
*
* @return self
*/
public function addTab(TabInterface $tab);
/**
* @param string $tabClassName
*
* @return TabInterface
*/
public function getTab($tabClassName);
/**
* @param mixed $offset
*
* @return TabInterface
*/
public function offsetGet($offset);
/**
* @return bool
*/
public function isEmpty();
}

View File

@@ -0,0 +1,128 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Tab;
use Doctrine\Common\Cache\CacheProvider;
use PrestaShop\Module\Mbo\ExternalContentProvider\ExternalContentProviderInterface;
use PrestaShop\PrestaShop\Adapter\LegacyContext;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
class TabCollectionProvider implements TabCollectionProviderInterface
{
const CACHE_KEY = 'recommendedModules';
const CACHE_LIFETIME_SECONDS = 604800;
const API_URL = 'https://api.prestashop.com/xml/tab_modules_list_17.xml';
/**
* @var LegacyContext
*/
private $context;
/**
* @var ExternalContentProviderInterface
*/
private $externalContentProvider;
/**
* @var TabCollectionFactoryInterface
*/
private $tabCollectionFactory;
/**
* @var CacheProvider|null
*/
private $cacheProvider;
/**
* @param LegacyContext $context
* @param ExternalContentProviderInterface $externalContentProvider
* @param TabCollectionFactoryInterface $tabCollectionFactory
* @param CacheProvider|null $cacheProvider
*/
public function __construct(
LegacyContext $context,
ExternalContentProviderInterface $externalContentProvider,
TabCollectionFactoryInterface $tabCollectionFactory,
CacheProvider $cacheProvider = null
) {
$this->context = $context;
$this->externalContentProvider = $externalContentProvider;
$this->tabCollectionFactory = $tabCollectionFactory;
$this->cacheProvider = $cacheProvider;
}
/**
* {@inheritdoc}
*/
public function getTabCollection()
{
if ($this->isTabCollectionCached()) {
return $this->cacheProvider->fetch($this->getCacheKey());
}
$tabCollection = $this->getTabCollectionFromApi();
if ($this->cacheProvider
&& false === $tabCollection->isEmpty()
) {
$this->cacheProvider->save(
$this->getCacheKey(),
$tabCollection,
static::CACHE_LIFETIME_SECONDS
);
}
return $tabCollection;
}
private function getCacheKey()
{
return static::CACHE_KEY . '-' . $this->context->getEmployeeLanguageIso();
}
/**
* Check if recommended modules cache is set
*
* @return bool
*/
public function isTabCollectionCached()
{
return $this->cacheProvider
&& $this->cacheProvider->contains($this->getCacheKey());
}
/**
* Retrieve tabs with recommended modules from PrestaShop
*
* @return TabCollectionInterface
*
* @throws ServiceUnavailableHttpException
*/
private function getTabCollectionFromApi()
{
$apiResponse = $this->externalContentProvider->getContent(self::API_URL);
$tabCollectionDecoderXml = new TabCollectionDecoderXml($apiResponse);
return $this->tabCollectionFactory->buildFromArray($tabCollectionDecoderXml->toArray());
}
}

View File

@@ -0,0 +1,29 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Tab;
interface TabCollectionProviderInterface
{
/**
* @return TabCollectionInterface
*/
public function getTabCollection();
}

View File

@@ -0,0 +1,103 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo\Tab;
use PrestaShop\Module\Mbo\RecommendedModule\RecommendedModuleCollectionInterface;
interface TabInterface
{
const DISPLAY_MODE_MODAL = 'slider_list';
const DISPLAY_MODE_AFTER_CONTENT = 'default_list';
/**
* Get the class name of the tab.
*
* @return string
*/
public function getLegacyClassName();
/**
* @param string $legacyClassName
*
* @return TabInterface
*/
public function setLegacyClassName($legacyClassName);
/**
* Get the display mode of the tab.
*
* @return string
*/
public function getDisplayMode();
/**
* @param string $displayMode
*
* @return TabInterface
*/
public function setDisplayMode($displayMode);
/**
* Get the recommended modules of the tab.
*
* @return RecommendedModuleCollectionInterface
*/
public function getRecommendedModules();
/**
* @param RecommendedModuleCollectionInterface $recommendedModules
*
* @return TabInterface
*/
public function setRecommendedModules(RecommendedModuleCollectionInterface $recommendedModules);
/**
* Check if the tab has recommended modules.
*
* @return bool
*/
public function hasRecommendedModules();
/**
* Get the installed recommended modules of the tab.
*
* @return RecommendedModuleCollectionInterface
*/
public function getRecommendedModulesInstalled();
/**
* Get the not installed recommended modules of the tab.
*
* @return RecommendedModuleCollectionInterface
*/
public function getRecommendedModulesNotInstalled();
/**
* @return bool
*/
public function shouldDisplayButton();
/**
* @return bool
*/
public function shouldDisplayAfterContent();
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,200 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\Mbo;
use Configuration;
use Db;
use Module;
use PrestaShopLogger;
use Psr\Log\LoggerInterface;
use Shop;
use Symfony\Component\Dotenv\Dotenv;
class UpgradeTracker
{
/**
* @param Module $module
*
* @return bool
*/
public function postTracking(Module $module, string $nextVersion = null)
{
try {
// Load env variables
$dotenv = new Dotenv();
$dotenv->load(__DIR__ . '/../.env');
$apiBaseUrl = getenv('DISTRIBUTION_API_URL');
if (is_string($apiBaseUrl) && !empty($apiBaseUrl)) {
// Execute the API call
$this->sendRequest(
$apiBaseUrl . '/api/shops/track-upgrade-mbo',
[
'shop_url' => $this->getShopUrl(),
'ps_version' => _PS_VERSION_,
// At this point, the module is not changed in DB yet but module->database_version is null. So we make DB query
'from_mbo_version' => $this->getCurrentModuleVersion(),
'to_mbo_version' => $nextVersion ?: $this->getNextModuleVersion(),
]
);
}
} catch (\Exception $e) {
$message = 'Upgrade tracking on Distribution failed : ' . $e->getMessage();
$logger = $module->get('logger');
if ($logger instanceof LoggerInterface) {
$logger->warning($message);
}
PrestaShopLogger::addLog($message, 2);
}
return true;
}
/**
* @param string $url
* @param array $data
*/
private function sendRequest($url, $data)
{
if (function_exists('curl_init') && defined('CURLOPT_POST')) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
]);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
$content = curl_exec($curl);
$httpcode = curl_getinfo($curl);
$error = curl_error($curl);
if ($error) {
$errno = curl_errno($curl);
curl_close($curl);
throw new \Exception(sprintf('Response code : %s. Error : %s', (string) $httpcode['http_code'], $error), $errno);
}
curl_close($curl);
}
}
/**
* The Tools::usingSecureMode used by Shop::getBaseUrl seems to not work in all situations
* To be sure to have the correct data, use shop configuration
*
* @return string|null
*/
private function getShopUrl()
{
$shopUrl = null;
$singleShop = $this->getSingleShop();
$useSecureProtocol = $this->isUsingSecureProtocol();
$domainConfigKey = $useSecureProtocol ? 'PS_SHOP_DOMAIN_SSL' : 'PS_SHOP_DOMAIN';
$domain = Configuration::get(
$domainConfigKey,
null,
$singleShop->id_shop_group,
$singleShop->id
);
if ($domain) {
$domain = preg_replace('#(https?://)#', '', $domain);
$shopUrl = ($useSecureProtocol ? 'https://' : 'http://') . $domain;
}
return $shopUrl;
}
/**
* @return bool
*/
private function isUsingSecureProtocol()
{
$singleShop = $this->getSingleShop();
return (bool) Configuration::get(
'PS_SSL_ENABLED',
null,
$singleShop->id_shop_group,
$singleShop->id
);
}
/**
* @return Shop
*/
private function getSingleShop()
{
$shops = Shop::getShops(false, null, true);
return new Shop((int) reset($shops));
}
/**
* @return string
*/
private function getCurrentModuleVersion()
{
return (string) Db::getInstance()->getValue(sprintf("SELECT `version` FROM `%smodule` WHERE `name`='ps_mbo'", _DB_PREFIX_));
}
/**
* Because there is an issue after upgrade : the version in module->version is the old one.
*
* @return string
*
* @throws \Exception
*/
private function getNextModuleVersion()
{
$moduleMainFile = sprintf('%s/ps_mbo/ps_mbo.php', rtrim(_PS_MODULE_DIR_, '/'));
if (!file_exists($moduleMainFile)) {
throw new \Exception(sprintf('Could not find module main file at %s', $moduleMainFile));
}
$moduleClassContent = file_get_contents($moduleMainFile);
preg_match('/const[ ]+VERSION[ ]*=[ ]*\'(.+)\'/', $moduleClassContent, $matches);
if (!empty($matches)) {
$version = $matches[1];
} else {
preg_match('/this->version[ ]*=[ ]*\'(.+)\'/', $moduleClassContent, $matches);
if (!empty($matches)) {
$version = $matches[1];
}
}
if (empty($version)) {
throw new \Exception(sprintf('Could not find module version in the main file at %s', $moduleMainFile));
}
return (string) $version;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;