⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.1
Server IP:
185.238.29.86
Server:
Linux server2 6.8.12-6-pve #1 SMP PREEMPT_DYNAMIC PMX 6.8.12-6 (2024-12-19T19:05Z) x86_64
Server Software:
nginx/1.18.0
PHP Version:
8.1.31
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
var
/
www
/
olasjoys
/
src
/
Adapter
/
Module
/
View File Name :
AdminModuleDataProvider.php
<?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 Open Software License (OSL 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/OSL-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. * * DISCLAIMER * * Do not edit or add to this file if you wish to upgrade PrestaShop to newer * versions in the future. If you wish to customize PrestaShop for your * needs please refer to https://devdocs.prestashop.com/ for more information. * * @author PrestaShop SA and Contributors <contact@prestashop.com> * @copyright Since 2007 PrestaShop SA and Contributors * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) */ namespace PrestaShop\PrestaShop\Adapter\Module; use Context; use Doctrine\Common\Cache\CacheProvider; use Employee; use Module as LegacyModule; use PrestaShop\PrestaShop\Core\Addon\AddonListFilterOrigin; use PrestaShop\PrestaShop\Core\Addon\AddonsCollection; use PrestaShopBundle\Service\DataProvider\Admin\AddonsInterface; use PrestaShopBundle\Service\DataProvider\Admin\CategoriesProvider; use PrestaShopBundle\Service\DataProvider\Admin\ModuleInterface; use Psr\Log\LoggerInterface; use Symfony\Component\Routing\Router; use Symfony\Component\Translation\TranslatorInterface; use Tools; /** * Data provider for new Architecture, about Module object model. * * This class will provide data from DB / ORM about Modules for the Admin interface. * This is an Adapter that works with the Legacy code and persistence behaviors. */ class AdminModuleDataProvider implements ModuleInterface { public const _CACHEKEY_MODULES_ = '_addons_modules'; public const _DAY_IN_SECONDS_ = 86400; /* Cache for One Day */ /** * @const array giving a translation domain key for each module action */ public const _ACTIONS_TRANSLATION_DOMAINS_ = [ 'install' => 'Admin.Actions', 'uninstall' => 'Admin.Actions', 'enable' => 'Admin.Actions', 'disable' => 'Admin.Actions', 'enable_mobile' => 'Admin.Modules.Feature', 'disable_mobile' => 'Admin.Modules.Feature', 'reset' => 'Admin.Actions', 'upgrade' => 'Admin.Actions', 'configure' => 'Admin.Actions', ]; /** * @var array of defined and callable module actions */ protected $moduleActions = ['install', 'uninstall', 'enable', 'disable', 'enable_mobile', 'disable_mobile', 'reset', 'upgrade']; /** * @var int */ private $languageISO; /** * @var LoggerInterface */ private $logger; /** * @var Router|null */ private $router = null; /** * @var AddonsInterface */ private $addonsDataProvider; /** * @var CategoriesProvider */ private $categoriesProvider; /** * @var ModuleDataProvider */ private $moduleProvider; /** * @var CacheProvider|null */ private $cacheProvider; /** * @var Employee|null */ private $employee; /** * @var array */ protected $catalog_modules = []; /** * @var array */ protected $catalog_modules_names; /** * @var bool */ public $failed = false; public function __construct( TranslatorInterface $translator, LoggerInterface $logger, AddonsInterface $addonsDataProvider, CategoriesProvider $categoriesProvider, ModuleDataProvider $modulesProvider, CacheProvider $cacheProvider = null, Employee $employee = null ) { list($this->languageISO) = explode('-', $translator->getLocale()); $this->logger = $logger; $this->addonsDataProvider = $addonsDataProvider; $this->categoriesProvider = $categoriesProvider; $this->moduleProvider = $modulesProvider; $this->cacheProvider = $cacheProvider; $this->employee = $employee; } /** * @param Router $router */ public function setRouter(Router $router) { $this->router = $router; } /** * Clear the modules information from Addons cache. */ public function clearCatalogCache() { if ($this->cacheProvider) { $this->cacheProvider->delete($this->languageISO . self::_CACHEKEY_MODULES_); } $this->catalog_modules = []; } /** * Clears module list cache. */ public function clearModuleListCache() { if (file_exists(LegacyModule::CACHE_FILE_DEFAULT_COUNTRY_MODULES_LIST)) { @unlink(LegacyModule::CACHE_FILE_DEFAULT_COUNTRY_MODULES_LIST); } } /** * @deprecated since version 1.7.3.0 * * @return array */ public function getAllModules() { return LegacyModule::getModulesOnDisk( true, $this->addonsDataProvider->isAddonsAuthenticated(), (int) Context::getContext()->employee->id ); } /** * @param array $filters * * @return array */ public function getCatalogModules(array $filters = []) { if (count($this->catalog_modules) === 0 && !$this->failed) { $this->loadCatalogData(); } return $this->applyModuleFilters( $this->catalog_modules, $filters ); } /** * @param array $filter * * @return array */ public function getCatalogModulesNames(array $filter = []) { return array_keys($this->getCatalogModules($filter)); } /** * Check the permissions of the current context (CLI or employee) for a module. * * @param array $actions Actions to check * @param string $name The module name * * @return array of allowed actions */ protected function filterAllowedActions(array $actions, $name = '') { $allowedActions = []; foreach (array_keys($actions) as $actionName) { if ($this->isAllowedAccess($actionName, $name)) { $allowedActions[$actionName] = $actions[$actionName]; } } return $allowedActions; } /** * Check the permissions of the current context (CLI or employee) for a specified action. * * @param string $action The action called in the module * @param string $name (Optionnal for 'install') The module name to check * * @return bool */ public function isAllowedAccess($action, $name = '') { if (Tools::isPHPCLI()) { return true; } if (in_array($action, ['install', 'upgrade'])) { return $this->employee->can('add', 'AdminModulessf'); } if ('uninstall' === $action) { return $this->employee->can('delete', 'AdminModulessf') && $this->moduleProvider->can('uninstall', $name); } return $this->employee->can('edit', 'AdminModulessf') && $this->moduleProvider->can('configure', $name); } /** * @param AddonsCollection $addons * @param string|null $specific_action * * @return AddonsCollection */ public function generateAddonsUrls(AddonsCollection $addons, $specific_action = null) { foreach ($addons as $addon) { $urls = []; foreach ($this->moduleActions as $action) { $urls[$action] = $this->router->generate('admin_module_manage_action', [ 'action' => $action, 'module_name' => $addon->attributes->get('name'), ]); } $urls['configure'] = $this->router->generate('admin_module_configure_action', [ 'module_name' => $addon->attributes->get('name'), ]); if ($addon->database->has('installed') && $addon->database->getBoolean('installed')) { if (!$addon->database->getBoolean('active')) { $url_active = 'enable'; unset( $urls['install'], $urls['disable'] ); } elseif ($addon->attributes->getBoolean('is_configurable')) { $url_active = 'configure'; unset( $urls['enable'], $urls['install'] ); } else { $url_active = 'disable'; unset( $urls['install'], $urls['enable'], $urls['configure'] ); } if (!$addon->attributes->getBoolean('is_configurable')) { unset($urls['configure']); } if ($addon->canBeUpgraded()) { $url_active = 'upgrade'; } else { unset( $urls['upgrade'] ); } if (!$addon->database->getBoolean('active_on_mobile')) { unset($urls['disable_mobile']); } else { unset($urls['enable_mobile']); } if (!$addon->canBeUpgraded()) { unset( $urls['upgrade'] ); } } elseif ( !$addon->attributes->has('origin') || $addon->disk->getBoolean('is_present') || in_array($addon->attributes->get('origin'), ['native', 'native_all', 'partner', 'customer'], true) ) { $url_active = 'install'; unset( $urls['uninstall'], $urls['enable'], $urls['disable'], $urls['enable_mobile'], $urls['disable_mobile'], $urls['reset'], $urls['upgrade'], $urls['configure'] ); } else { $url_active = 'buy'; } $urls = $this->filterAllowedActions($urls, $addon->attributes->get('name')); $addon->attributes->set('urls', $urls); $addon->attributes->set('actionTranslationDomains', self::_ACTIONS_TRANSLATION_DOMAINS_); if ($specific_action && array_key_exists($specific_action, $urls)) { $addon->attributes->set('url_active', $specific_action); } elseif ($url_active === 'buy' || array_key_exists($url_active, $urls)) { $addon->attributes->set('url_active', $url_active); } else { $addon->attributes->set('url_active', key($urls)); } $categoryParent = $this->categoriesProvider->getParentCategory($addon->attributes->get('categoryName')); $addon->attributes->set('categoryParent', $categoryParent); } return $addons; } /** * @param int $moduleId * * @return array */ public function getModuleAttributesById($moduleId) { return (array) $this->addonsDataProvider->request('module', ['id_module' => $moduleId]); } /** * @param array $modules * @param array $filters * * @return array */ protected function applyModuleFilters(array $modules, array $filters) { if (!count($filters)) { return $modules; } // We get our module IDs to keep foreach ($filters as $filter_name => $value) { $search_result = []; switch ($filter_name) { case 'search': // We build our results array. // We could remove directly the non-matching modules, but we will give that for the final loop of this function foreach (explode(' ', $value) as $keyword) { if (empty($keyword)) { continue; } // Instead of looping on the whole module list, we use $module_ids which can already be reduced // thanks to the previous array_intersect(...) foreach ($modules as $key => $module) { if (strpos($module->displayName, $keyword) !== false || strpos($module->name, $keyword) !== false || strpos($module->description, $keyword) !== false) { $search_result[] = $key; } } } break; case 'name': // exact given name (should return 0 or 1 result) $search_result[] = $value; break; default: // "the switch statement is considered a looping structure for the purposes of continue." continue 2; } $modules = array_intersect_key($modules, array_flip($search_result)); } return $modules; } /** * Load module catalogue. If not in cache, query Addons API. */ protected function loadCatalogData() { if ($this->cacheProvider && $this->cacheProvider->contains($this->languageISO . self::_CACHEKEY_MODULES_)) { $this->catalog_modules = $this->cacheProvider->fetch($this->languageISO . self::_CACHEKEY_MODULES_); } if (!$this->catalog_modules) { $params = ['format' => 'json']; $requests = [ AddonListFilterOrigin::ADDONS_MUST_HAVE => 'must-have', AddonListFilterOrigin::ADDONS_SERVICE => 'service', AddonListFilterOrigin::ADDONS_NATIVE => 'native', AddonListFilterOrigin::ADDONS_NATIVE_ALL => 'native_all', ]; if ($this->addonsDataProvider->isAddonsAuthenticated()) { $requests[AddonListFilterOrigin::ADDONS_CUSTOMER] = 'customer'; } try { $listAddons = []; // We execute each addons request foreach ($requests as $action_filter_value => $action) { if (!$this->addonsDataProvider->isAddonsUp()) { continue; } // We add the request name in each product returned by Addons, // so we know whether is bought $addons = $this->addonsDataProvider->request($action, $params); /** @var \stdClass $addon */ foreach ($addons as $addonsType => $addon) { if (empty($addon->name)) { $this->logger->error(sprintf('The addon with id %s does not have name.', $addon->id)); continue; } $addon->origin = $action; $addon->origin_filter_value = $action_filter_value; $addon->categoryParent = $this->categoriesProvider ->getParentCategory($addon->categoryName); if (isset($addon->version)) { $addon->version_available = $addon->version; } if (!isset($addon->product_type)) { $addon->productType = isset($addonsType) ? rtrim($addonsType, 's') : 'module'; } else { $addon->productType = $addon->product_type; } $listAddons[$addon->name] = $addon; } } if (!empty($listAddons)) { $this->catalog_modules = $listAddons; if ($this->cacheProvider) { $this->cacheProvider->save($this->languageISO . self::_CACHEKEY_MODULES_, $this->catalog_modules, self::_DAY_IN_SECONDS_); } } else { $this->fallbackOnCatalogCache(); } } catch (\Exception $e) { if (!$this->fallbackOnCatalogCache()) { $this->logger->error('Data from PrestaShop Addons is invalid, and cannot fallback on cache.'); } } } } /** * If cache exists, get the Catalogue from the cache. * * @return array Module loaded from the cache */ protected function fallbackOnCatalogCache() { // Fallback on data from cache if exists if ($this->cacheProvider) { $this->catalog_modules = $this->cacheProvider->fetch($this->languageISO . self::_CACHEKEY_MODULES_); } if (!$this->catalog_modules) { $this->catalog_modules = []; } $this->failed = true; return $this->catalog_modules; } }