diff --git a/.gitignore b/.gitignore index 25617dca..af1e0de1 100755 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,3 @@ config/marketplaces.json tools/vars.sh .php_cs.cache .php-cs-fixer.cache -.php-cs-fixer.dist.php diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 00000000..90fc59b3 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,60 @@ +in([ + __DIR__.'/classes', + __DIR__.'/src', + __DIR__.'/controllers', + __DIR__.'/upgrade', + __DIR__.'/webservice', +]); + +return (new PhpCsFixer\Config()) + ->setRiskyAllowed(true) + ->setRules([ + '@Symfony' => true, + 'array_indentation' => true, + 'cast_spaces' => [ + 'space' => 'single', + ], + 'combine_consecutive_issets' => true, + 'concat_space' => [ + 'spacing' => 'one', + ], + 'error_suppression' => [ + 'mute_deprecation_error' => false, + 'noise_remaining_usages' => false, + 'noise_remaining_usages_exclude' => [], + ], + 'function_to_constant' => false, + 'method_chaining_indentation' => true, + 'no_alias_functions' => false, + 'no_superfluous_phpdoc_tags' => false, + 'non_printable_character' => [ + 'use_escape_sequences_in_strings' => true, + ], + 'phpdoc_align' => [ + 'align' => 'left', + ], + 'phpdoc_summary' => false, + 'protected_to_private' => false, + 'psr_autoloading' => false, + 'self_accessor' => false, + 'yoda_style' => false, + 'single_line_throw' => false, + 'no_alias_language_construct_call' => false, + 'no_null_property_initialization' => false, + 'nullable_type_declaration_for_default_null_value' => true, + 'global_namespace_import' => [ + 'import_classes' => false, + 'import_constants' => false, + 'import_functions' => false, + ], + 'blank_line_after_opening_tag' => false, + 'no_extra_blank_lines' => [ + 'tokens' => [ + 'extra', + 'use', + ], + ], + ]) + ->setFinder($finder); diff --git a/README.md b/README.md index 1b304e53..4929fd91 100755 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Lengow for PrestaShop -- **Requires at least:** 1.7.7 -- **Tested up to:** 8.1.7 -- **Requires PHP:** 7.4 +- **Requires at least:** 8.0.0 +- **Tested up to:** 9.0.0 +- **Requires PHP:** 8.1 - **Stable tag:** 3.9.4 - **License:** Apache-2.0 - **License URI:** http://www.apache.org/licenses/LICENSE-2.0 @@ -75,7 +75,7 @@ Translations in the plugin are managed via a key system and associated yaml file Start by installing Yaml Parser: - sudo apt-get install php5-dev libyaml-dev + sudo apt-get install php-dev libyaml-dev sudo pecl install yaml To translate the project, use specific key in php code and modify the *.yml files in the directory: `lengow/translations/yml/` diff --git a/classes/controllers/LengowController.php b/classes/controllers/LengowController.php index c807da52..1c1b1377 100755 --- a/classes/controllers/LengowController.php +++ b/classes/controllers/LengowController.php @@ -22,79 +22,144 @@ /* * Lengow Controller Class */ +use Twig\Environment; + if (!defined('_PS_VERSION_')) { exit; } class LengowController { /** - * @var Lengow Lengow module instance + * @var Lengow|false Lengow module instance */ - protected $module; + protected Lengow|false $module; /** * @var Context PrestaShop context instance */ - protected $context; + protected Context $context; /** * @var LengowLink Lengow link instance */ - protected $lengowLink; + protected LengowLink $lengowLink; /** * @var LengowTranslation Lengow translation instance */ - protected $locale; + protected LengowTranslation $locale; /** * @var bool Check if is a new merchant */ - protected $isNewMerchant; + protected bool $isNewMerchant; + + /** + * @var Environment|null Twig environment instance + */ + protected ?Environment $twig = null; + + /** + * @var array Variables passed to Twig templates + */ + protected array $templateVars = []; + + /** + * @var bool Whether controller runs through Symfony bridge and must not echo/exit + */ + protected bool $bridgeMode = false; + + /** + * @var array|null JSON payload produced during postProcess in bridge mode + */ + private ?array $jsonResponsePayload = null; /** * Construct the main Lengow controller + * + * @param Context $context PrestaShop context (injected from Symfony controller on PS9, + * or resolved via LengowContext on PS8) + * @param Environment|null $twig Twig environment instance + * @param bool $bridgeMode Enable bridge mode to avoid direct output side effects */ - public function __construct() + public function __construct(Context $context, ?Environment $twig = null, bool $bridgeMode = false) { $this->module = Module::getInstanceByName('lengow'); - $this->context = Context::getContext(); + $this->context = $context; + $this->twig = $twig; + $this->bridgeMode = $bridgeMode; $this->lengowLink = new LengowLink(); - $this->locale = new LengowTranslation(); + $this->locale = new LengowTranslation($this->context); $this->isNewMerchant = LengowConfiguration::isNewMerchant(); - $this->context->smarty->assign('locale', $this->locale); + $this->templateVars['locale'] = $this->locale; $lengowPathUri = $this->module->getPathUri(); - $this->context->smarty->assign('lengowPathUri', $lengowPathUri); + $this->templateVars['lengowPathUri'] = $lengowPathUri; + $this->templateVars['lengow_link'] = $this->lengowLink; } /** * Process Post Parameters + * + * @return void */ - public function postProcess() + public function postProcess(): void { $this->prepareDisplay(); } /** * Display data page + * + * @return void */ - public function display() + public function display(): void { $this->prepareDisplay(); - $this->context->smarty->assign('total_pending_order', LengowOrder::countOrderToBeSent()); + $this->templateVars['total_pending_order'] = LengowOrder::countOrderToBeSent(); } /** - * Force Display data page + * Get all template variables + * + * @return array */ - public function forceDisplay() + public function getTemplateVars(): array { - $module = Module::getInstanceByName('lengow'); - $lengowMain = new LengowMain(); - $className = get_class($this); - $path = $lengowMain->fromCamelCase(Tools::substr($className, 0, Tools::strlen($className) - 10)); - $this->prepareDisplay(); - echo $module->display(_PS_MODULE_LENGOW_DIR_, 'views/templates/admin/' . $path . '/helpers/view/view.tpl'); + return $this->templateVars; + } + + /** + * @return array|null + */ + public function consumeJsonResponse(): ?array + { + $payload = $this->jsonResponsePayload; + $this->jsonResponsePayload = null; + + return $payload; + } + + /** + * @param array $payload + */ + protected function respondJson(array $payload): void + { + if ($this->bridgeMode) { + $this->jsonResponsePayload = $payload; + + return; + } + + echo json_encode($payload); + } + + protected function finishPostProcess(): void + { + if ($this->bridgeMode) { + return; + } + + exit; } /** @@ -102,7 +167,7 @@ public function forceDisplay() * * @return bool */ - private function showPluginUpgradeModal() + private function showPluginUpgradeModal(): bool { // never display the upgrade modal during the connection process $className = get_class($this); @@ -110,7 +175,7 @@ private function showPluginUpgradeModal() return false; } $updatedAt = LengowConfiguration::getGlobalValue(LengowConfiguration::LAST_UPDATE_PLUGIN_MODAL); - if ($updatedAt !== null && (time() - (int) $updatedAt) < 86400) { + if ($updatedAt !== '' && (time() - (int) $updatedAt) < 86400) { return false; } LengowConfiguration::updateGlobalValue(LengowConfiguration::LAST_UPDATE_PLUGIN_MODAL, time()); @@ -120,10 +185,12 @@ private function showPluginUpgradeModal() /** * affect variables to template display + * + * @return void */ - protected function prepareDisplay() + protected function prepareDisplay(): void { - $localeIsoCode = Tools::substr(Context::getContext()->language->language_code, 0, 2); + $localeIsoCode = Tools::substr($this->context->language->language_code, 0, 2); $multiShop = Shop::isFeatureActive(); $debugMode = LengowConfiguration::debugModeIsActive(); $merchantStatus = LengowSync::getStatusAccount(); @@ -145,26 +212,26 @@ protected function prepareDisplay() } // get actual plugin urls in current language $pluginLinks = LengowSync::getPluginLinks($localeIsoCode, true); - // assignment of all smarty variables for the entire plugin - - $this->context->smarty->assign('current_controller', get_class($this)); - $this->context->smarty->assign('lengow_link', $this->lengowLink); - $this->context->smarty->assign('localeIsoCode', $localeIsoCode); - $this->context->smarty->assign('version', _PS_VERSION_); - $this->context->smarty->assign('lengowVersion', $this->module->version); - $this->context->smarty->assign('lengowUrl', LengowConfiguration::getLengowUrl()); - $this->context->smarty->assign('displayToolbar', $displayToolbar); - $this->context->smarty->assign('pluginData', $pluginData); - $this->context->smarty->assign('pluginIsUpToDate', $pluginIsUpToDate); - $this->context->smarty->assign('showPluginUpgradeModal', $showPluginUpgradeModal); - $this->context->smarty->assign('lengowModalAjaxLink', $lengowModalAjaxLink); - $this->context->smarty->assign('helpCenterLink', $pluginLinks[LengowSync::LINK_TYPE_HELP_CENTER]); - $this->context->smarty->assign('updateGuideLink', $pluginLinks[LengowSync::LINK_TYPE_UPDATE_GUIDE]); - $this->context->smarty->assign('changelogLink', $pluginLinks[LengowSync::LINK_TYPE_CHANGELOG]); - $this->context->smarty->assign('supportLink', $pluginLinks[LengowSync::LINK_TYPE_SUPPORT]); - $this->context->smarty->assign('multiShop', $multiShop); - $this->context->smarty->assign('debugMode', $debugMode); - $this->context->smarty->assign('isNewMerchant', $this->isNewMerchant); - $this->context->smarty->assign('merchantStatus', $merchantStatus); + // assignment of all template variables for the entire plugin + + $this->templateVars['current_controller'] = get_class($this); + $this->templateVars['lengow_link'] = $this->lengowLink; + $this->templateVars['localeIsoCode'] = $localeIsoCode; + $this->templateVars['version'] = _PS_VERSION_; + $this->templateVars['lengowVersion'] = $this->module->version; + $this->templateVars['lengowUrl'] = LengowConfiguration::getLengowUrl(); + $this->templateVars['displayToolbar'] = $displayToolbar; + $this->templateVars['pluginData'] = $pluginData; + $this->templateVars['pluginIsUpToDate'] = $pluginIsUpToDate; + $this->templateVars['showPluginUpgradeModal'] = $showPluginUpgradeModal; + $this->templateVars['lengowModalAjaxLink'] = $lengowModalAjaxLink; + $this->templateVars['helpCenterLink'] = $pluginLinks[LengowSync::LINK_TYPE_HELP_CENTER]; + $this->templateVars['updateGuideLink'] = $pluginLinks[LengowSync::LINK_TYPE_UPDATE_GUIDE]; + $this->templateVars['changelogLink'] = $pluginLinks[LengowSync::LINK_TYPE_CHANGELOG]; + $this->templateVars['supportLink'] = $pluginLinks[LengowSync::LINK_TYPE_SUPPORT]; + $this->templateVars['multiShop'] = $multiShop; + $this->templateVars['debugMode'] = $debugMode; + $this->templateVars['isNewMerchant'] = $this->isNewMerchant; + $this->templateVars['merchantStatus'] = $merchantStatus; } } diff --git a/classes/controllers/LengowDashboardController.php b/classes/controllers/LengowDashboardController.php index 4364b530..a48df783 100644 --- a/classes/controllers/LengowDashboardController.php +++ b/classes/controllers/LengowDashboardController.php @@ -28,8 +28,10 @@ class LengowDashboardController extends LengowController { /** * Process Post Parameters + * + * @return void */ - public function postProcess() + public function postProcess(): void { $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : false; if ($action) { @@ -41,20 +43,22 @@ public function postProcess() case 'remind_me_later': $timestamp = time() + (7 * 86400); LengowConfiguration::updateGlobalValue(LengowConfiguration::LAST_UPDATE_PLUGIN_MODAL, $timestamp); - echo json_encode(['success' => true]); + $this->respondJson(['success' => true]); break; } - exit; + $this->finishPostProcess(); } } /** * Display data page + * + * @return void */ - public function display() + public function display(): void { $refreshStatus = $this->lengowLink->getAbsoluteAdminLink('AdminLengowDashboard') . '&action=refresh_status'; - $this->context->smarty->assign('refresh_status', $refreshStatus); + $this->templateVars['refresh_status'] = $refreshStatus; parent::display(); } } diff --git a/classes/controllers/LengowFeedController.php b/classes/controllers/LengowFeedController.php index f42a9654..40822aeb 100755 --- a/classes/controllers/LengowFeedController.php +++ b/classes/controllers/LengowFeedController.php @@ -30,12 +30,14 @@ class LengowFeedController extends LengowController /** * @var LengowList Lengow list instance */ - protected $list; + protected LengowList $list; /** * Process Post Parameters + * + * @return void */ - public function postProcess() + public function postProcess(): void { $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : false; if ($action) { @@ -47,7 +49,7 @@ public function postProcess() LengowConfiguration::updatevalue( LengowConfiguration::SELECTION_ENABLED, $state, - null, + false, null, $idShop ); @@ -60,21 +62,21 @@ public function postProcess() LengowConfiguration::updatevalue( LengowConfiguration::OUT_OF_STOCK_ENABLED, 1, - null, + false, null, $idShop ); LengowConfiguration::updatevalue( LengowConfiguration::VARIATION_ENABLED, 1, - null, + false, null, $idShop ); LengowConfiguration::updatevalue( LengowConfiguration::INACTIVE_ENABLED, 0, - null, + false, null, $idShop ); @@ -83,7 +85,7 @@ public function postProcess() } $result = array_merge($data, $this->reloadTotal($idShop)); - echo json_encode($result); + $this->respondJson($result); } break; case 'change_option_selected__out_of_stock': @@ -93,7 +95,7 @@ public function postProcess() LengowConfiguration::updatevalue( LengowConfiguration::OUT_OF_STOCK_ENABLED, $state, - null, + false, null, $idShop ); @@ -106,14 +108,14 @@ public function postProcess() LengowConfiguration::updatevalue( LengowConfiguration::SELECTION_ENABLED, 0, - null, + false, null, $idShop ); } $result = array_merge($data, $this->reloadTotal($idShop)); - echo json_encode($result); + $this->respondJson($result); } break; case 'change_option_selected__variation': @@ -123,7 +125,7 @@ public function postProcess() LengowConfiguration::updatevalue( LengowConfiguration::VARIATION_ENABLED, $state, - null, + false, null, $idShop ); @@ -136,14 +138,14 @@ public function postProcess() LengowConfiguration::updatevalue( LengowConfiguration::SELECTION_ENABLED, 0, - null, + false, null, $idShop ); } $result = array_merge($data, $this->reloadTotal($idShop)); - echo json_encode($result); + $this->respondJson($result); } break; case 'change_option_selected__inactive': @@ -153,7 +155,7 @@ public function postProcess() LengowConfiguration::updatevalue( LengowConfiguration::INACTIVE_ENABLED, $state, - null, + false, null, $idShop ); @@ -166,14 +168,14 @@ public function postProcess() LengowConfiguration::updatevalue( LengowConfiguration::SELECTION_ENABLED, 0, - null, + false, null, $idShop ); } $result = array_merge($data, $this->reloadTotal($idShop)); - echo json_encode($result); + $this->respondJson($result); } break; case 'select_product': @@ -182,7 +184,7 @@ public function postProcess() $productId = isset($_REQUEST['id_product']) ? $_REQUEST['id_product'] : null; if ($state !== null) { LengowProduct::publish($productId, $state, $idShop); - echo json_encode($this->reloadTotal($idShop)); + $this->respondJson($this->reloadTotal($idShop)); } break; case 'load_table': @@ -190,7 +192,7 @@ public function postProcess() $data = []; $data['shop_id'] = $idShop; $data['footer_content'] = preg_replace('/\r|\n/', '', $this->buildTable($idShop)); - echo json_encode($data); + $this->respondJson($data); break; case 'lengow_export_action': $idShop = isset($_REQUEST['id_shop']) ? (int) $_REQUEST['id_shop'] : null; @@ -234,17 +236,19 @@ public function postProcess() } else { $data['message'] = $this->locale->t('product.screen.no_product_selected'); } - echo json_encode($data); + $this->respondJson($data); break; } - exit; + $this->finishPostProcess(); } } /** * Display data page + * + * @return void */ - public function display() + public function display(): void { $shopCollection = []; if ($currentShop = Shop::getContextShopID()) { @@ -292,7 +296,7 @@ public function display() 'list' => $this->buildTable($shop->id), ]; } - $this->context->smarty->assign('shopCollection', $shopCollection); + $this->templateVars['shopCollection'] = $shopCollection; parent::display(); } @@ -301,9 +305,9 @@ public function display() * * @param int $idShop PrestaShop shop id * - * @return array Number of product exported/total for this shop + * @return array Number of product exported/total for this shop */ - public function reloadTotal($idShop) + public function reloadTotal(int $idShop): array { $lengowExport = new LengowExport([LengowExport::PARAM_SHOP_ID => $idShop]); $result = []; @@ -320,7 +324,7 @@ public function reloadTotal($idShop) * * @return string */ - public function buildTable($idShop) + public function buildTable(int $idShop): string { $fieldsList = []; @@ -453,7 +457,8 @@ public function buildTable($idShop) 'where' => $where, 'order' => 'p.id_product ASC', ], - ] + ], + $this->context ); $collection = $this->list->executeQuery(); @@ -468,7 +473,7 @@ public function buildTable($idShop) if ($collection) { for ($i = 0; $i < $nb; ++$i) { $productId = $collection[$i]['id_product']; - $nothing = ''; + $nothing = null; $collection[$i]['price_final'] = Product::getPriceStatic( $productId, true, @@ -554,33 +559,29 @@ class="lgw-btn lengow_add_to_export"> * * @param string $key row key * @param string $value row value - * @param array $item item values + * @param array $item item values * * @return string * * @throws Exception */ - public static function displayLink($key, $value, $item) + public static function displayLink(string $key, string $value, array $item): string { // this line is useless, but PrestaShop validator require it $key = $key; $link = new LengowLink(); if ($item['id_product']) { $controller = 'AdminProducts'; - if (version_compare(_PS_VERSION_, '1.7', '<')) { - $href = $link->getAbsoluteAdminLink($controller) . '&updateproduct&id_product=' . $item['id_product']; - } else { - $href = $link->getAdminLink( - $controller, - true, - [ - 'updateproduct' => 1, - 'id_product' => $item['id_product'], - ] - ); - } + $href = $link->getAdminLink( + $controller, + true, + [ + 'updateproduct' => 1, + 'id_product' => $item['id_product'], + ] + ); - return '' . $value . ''; + return '' . htmlspecialchars($value, ENT_QUOTES, 'UTF-8') . ''; } return $value; diff --git a/classes/controllers/LengowHomeController.php b/classes/controllers/LengowHomeController.php index 606a1145..a7be3de4 100755 --- a/classes/controllers/LengowHomeController.php +++ b/classes/controllers/LengowHomeController.php @@ -28,20 +28,21 @@ class LengowHomeController extends LengowController { /** * Process Post Parameters + * + * @return void */ - public function postProcess() + public function postProcess(): void { $this->prepareDisplay(); $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : false; if ($action) { switch ($action) { case 'go_to_credentials': - $module = Module::getInstanceByName('lengow'); - $displayContent = $module->display( - _PS_MODULE_LENGOW_DIR_, - 'views/templates/admin/lengow_home/helpers/view/connection_cms.tpl' + $displayContent = $this->twig->render( + '@Modules/lengow/views/templates/admin/lengow_home/helpers/view/connection_cms.html.twig', + $this->getCommonVarsForSubTemplate() ); - echo json_encode( + $this->respondJson( ['content' => preg_replace('/\r|\n/', '', $displayContent)] ); break; @@ -57,15 +58,15 @@ public function postProcess() $hasCatalogToLink = $this->hasCatalogToLink(); } } - $this->context->smarty->assign('credentialsValid', $credentialsValid); - $this->context->smarty->assign('cmsConnected', $cmsConnected); - $this->context->smarty->assign('hasCatalogToLink', $hasCatalogToLink); - $module = Module::getInstanceByName('lengow'); - $displayContent = $module->display( - _PS_MODULE_LENGOW_DIR_, - 'views/templates/admin/lengow_home/helpers/view/connection_cms_result.tpl' + $displayContent = $this->twig->render( + '@Modules/lengow/views/templates/admin/lengow_home/helpers/view/connection_cms_result.html.twig', + array_merge($this->getCommonVarsForSubTemplate(), [ + 'credentialsValid' => $credentialsValid, + 'cmsConnected' => $cmsConnected, + 'hasCatalogToLink' => $hasCatalogToLink, + ]) ); - echo json_encode( + $this->respondJson( [ 'success' => $cmsConnected, 'content' => preg_replace('/\r|\n/', '', $displayContent), @@ -77,14 +78,14 @@ public function postProcess() if ($retry) { LengowConfiguration::resetCatalogIds(); } - $this->context->smarty->assign('shopCollection', LengowShop::getActiveShops()); - $this->context->smarty->assign('catalogList', $this->getCatalogList()); - $module = Module::getInstanceByName('lengow'); - $displayContent = $module->display( - _PS_MODULE_LENGOW_DIR_, - 'views/templates/admin/lengow_home/helpers/view/connection_catalog.tpl' + $displayContent = $this->twig->render( + '@Modules/lengow/views/templates/admin/lengow_home/helpers/view/connection_catalog.html.twig', + array_merge($this->getCommonVarsForSubTemplate(), [ + 'shopCollection' => LengowShop::getActiveShops(), + 'catalogList' => $this->getCatalogList(), + ]) ); - echo json_encode( + $this->respondJson( ['content' => preg_replace('/\r|\n/', '', $displayContent)] ); break; @@ -96,12 +97,11 @@ public function postProcess() if (!empty($catalogSelected)) { $catalogsLinked = $this->saveCatalogsLinked($catalogSelected); } - $module = Module::getInstanceByName('lengow'); - $displayConnectionResult = $module->display( - _PS_MODULE_LENGOW_DIR_, - 'views/templates/admin/lengow_home/helpers/view/connection_catalog_failed.tpl' + $displayConnectionResult = $this->twig->render( + '@Modules/lengow/views/templates/admin/lengow_home/helpers/view/connection_catalog_failed.html.twig', + $this->getCommonVarsForSubTemplate() ); - echo json_encode( + $this->respondJson( [ 'success' => $catalogsLinked, 'content' => preg_replace('/\r|\n/', '', $displayConnectionResult), @@ -109,26 +109,42 @@ public function postProcess() ); break; } - exit; + $this->finishPostProcess(); } } /** * Display data page + * + * @return void */ - public function display() + public function display(): void { if ($this->isNewMerchant) { - $this->context->smarty->assign( - 'lengow_ajax_link', - $this->lengowLink->getAbsoluteAdminLink('AdminLengowHome') - ); + $this->templateVars['lengow_ajax_link'] = $this->lengowLink->getAbsoluteAdminLink('AdminLengowHome'); parent::display(); } else { Tools::redirectAdmin($this->lengowLink->getAbsoluteAdminLink('AdminLengowDashboard')); } } + /** + * Get common variables for sub-template rendering (AJAX context) + * + * @return array + */ + private function getCommonVarsForSubTemplate(): array + { + return [ + 'lengowPathUri' => $this->templateVars['lengowPathUri'] ?? $this->module->getPathUri(), + 'locale' => $this->locale, + 'lengow_link' => $this->lengowLink, + 'lengowUrl' => LengowConfiguration::getLengowUrl(), + 'helpCenterLink' => $this->templateVars['helpCenterLink'] ?? '', + 'supportLink' => $this->templateVars['supportLink'] ?? '', + ]; + } + /** * Check API credentials and save them in Database * @@ -137,7 +153,7 @@ public function display() * * @return bool */ - private function checkApiCredentials($accessToken, $secret) + private function checkApiCredentials(string $accessToken, string $secret): bool { $accessIdsSaved = false; $accountId = LengowConnector::getAccountIdByCredentials($accessToken, $secret); @@ -159,7 +175,7 @@ private function checkApiCredentials($accessToken, $secret) * * @return bool */ - private function connectCms() + private function connectCms(): bool { $cmsToken = LengowMain::getToken(); $cmsConnected = LengowSync::syncCatalog(true); @@ -196,7 +212,7 @@ private function connectCms() * * @return bool */ - private function hasCatalogToLink() + private function hasCatalogToLink(): bool { $activeShops = LengowShop::getActiveShops(true); if (empty($activeShops)) { @@ -209,9 +225,9 @@ private function hasCatalogToLink() /** * Get all catalogs available in Lengow * - * @return array + * @return array */ - private function getCatalogList() + private function getCatalogList(): array { $activeShops = LengowShop::getActiveShops(true); if (empty($activeShops)) { @@ -225,11 +241,11 @@ private function getCatalogList() /** * Save catalogs linked in database and send data to Lengow with call API * - * @param array $catalogSelected + * @param array $catalogSelected * * @return bool */ - private function saveCatalogsLinked($catalogSelected) + private function saveCatalogsLinked(array $catalogSelected): bool { $catalogsLinked = true; $catalogsByShops = []; diff --git a/classes/controllers/LengowMainSettingController.php b/classes/controllers/LengowMainSettingController.php index a5696d7f..b55cb07b 100755 --- a/classes/controllers/LengowMainSettingController.php +++ b/classes/controllers/LengowMainSettingController.php @@ -29,8 +29,10 @@ class LengowMainSettingController extends LengowController { /** * Process Post Parameters + * + * @return void */ - public function postProcess() + public function postProcess(): void { $action = Tools::getValue('action'); @@ -86,8 +88,10 @@ public function postProcess() /** * Display data page + * + * @return void */ - public function display() + public function display(): void { $form = new LengowConfigurationForm(['fields' => LengowConfiguration::getKeys()]); $form->fields[LengowConfiguration::REPORT_MAILS][LengowConfiguration::PARAM_LABEL] = ''; @@ -134,13 +138,13 @@ public function display() ) . ''; } $listFile = LengowLog::getPaths(); - $this->context->smarty->assign('list_file', $listFile); - $this->context->smarty->assign('mail_report', $mailReport); - $this->context->smarty->assign('defaultExportCarrier', $defaultExportCarrier); - $this->context->smarty->assign('ipSecurity', $ipSecurity); - $this->context->smarty->assign('debug_report', $debugReport); - $this->context->smarty->assign('debug_wrapper', $debugWrapper); - $this->context->smarty->assign('shopCatalog', $shopCatalog); + $this->templateVars['list_file'] = $listFile; + $this->templateVars['mail_report'] = $mailReport; + $this->templateVars['defaultExportCarrier'] = $defaultExportCarrier; + $this->templateVars['ipSecurity'] = $ipSecurity; + $this->templateVars['debug_report'] = $debugReport; + $this->templateVars['debug_wrapper'] = $debugWrapper; + $this->templateVars['shopCatalog'] = $shopCatalog; parent::display(); } } diff --git a/classes/controllers/LengowOrderController.php b/classes/controllers/LengowOrderController.php index b491178f..6d733fc6 100755 --- a/classes/controllers/LengowOrderController.php +++ b/classes/controllers/LengowOrderController.php @@ -29,25 +29,29 @@ class LengowOrderController extends LengowController /** * @var LengowList Lengow list instance */ - protected $list; + protected LengowList $list; /** * Display data page + * + * @return void */ - public function display() + public function display(): void { $this->assignLastImportationInfos(); $this->assignNbOrderImported(); $this->assignWarningMessages(); - $this->context->smarty->assign('showCarrierNotification', LengowCarrier::hasDefaultCarrierNotMatched()); - $this->context->smarty->assign('lengow_table', $this->buildTable()); + $this->templateVars['showCarrierNotification'] = LengowCarrier::hasDefaultCarrierNotMatched(); + $this->templateVars['lengow_table'] = $this->buildTable(); parent::display(); } /** * Process Post Parameters + * + * @return void */ - public function postProcess() + public function postProcess(): void { $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : false; if ($action) { @@ -55,7 +59,7 @@ public function postProcess() case 'load_table': $data = []; $data['order_table'] = preg_replace('/\r|\n/', '', $this->buildTable()); - echo json_encode($data); + $this->respondJson($data); break; case 're_import': $idOrderLengow = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0; @@ -67,7 +71,7 @@ public function postProcess() $data = []; $data['id_order_lengow'] = $idOrderLengow; $data['html'] = $html; - echo json_encode($data); + $this->respondJson($data); break; case 're_send': $idOrderLengow = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0; @@ -79,7 +83,7 @@ public function postProcess() $data = []; $data['id_order_lengow'] = $idOrderLengow; $data['html'] = $html; - echo json_encode($data); + $this->respondJson($data); break; case 'import_all': if (Shop::getContextShopID()) { @@ -96,22 +100,21 @@ public function postProcess() $message = $this->loadMessage($return); $this->assignLastImportationInfos(); $this->assignWarningMessages(); - $module = Module::getInstanceByName('lengow'); - $displayWarningMessage = $module->display( - _PS_MODULE_LENGOW_DIR_, - 'views/templates/admin/lengow_order/helpers/view/warning_message.tpl' + $displayWarningMessage = $this->twig->render( + '@Modules/lengow/views/templates/admin/lengow_order/helpers/view/warning_message.html.twig', + $this->templateVars ); - $displayLastImportation = $module->display( - _PS_MODULE_LENGOW_DIR_, - 'views/templates/admin/lengow_order/helpers/view/last_importation.tpl' + $displayLastImportation = $this->twig->render( + '@Modules/lengow/views/templates/admin/lengow_order/helpers/view/last_importation.html.twig', + $this->templateVars ); $orderTable = $this->buildTable(); if ($this->list->getTotal() > 0) { $displayListOrder = $orderTable; } else { - $displayListOrder = $module->display( - _PS_MODULE_LENGOW_DIR_, - 'views/templates/admin/lengow_order/helpers/view/no_order.tpl' + $displayListOrder = $this->twig->render( + '@Modules/lengow/views/templates/admin/lengow_order/helpers/view/no_order.html.twig', + $this->templateVars ); } $data = []; @@ -121,7 +124,7 @@ public function postProcess() $data['import_orders'] = $this->locale->t('order.screen.button_update_orders'); $data['list_order'] = preg_replace('/\r|\n/', '', $displayListOrder); $data['show_carrier_notification'] = LengowCarrier::hasDefaultCarrierNotMatched(); - echo json_encode($data); + $this->respondJson($data); break; case 'synchronize': $idOrder = isset($_REQUEST['id_order']) ? (int) $_REQUEST['id_order'] : 0; @@ -174,7 +177,7 @@ public function postProcess() LengowLog::CODE_IMPORT, 'Updated shipping method : ' . $shippingMethod, false, - $idOrder + (string) $idOrder ); } else { $response['message'] = 'No changes or errors'; @@ -183,8 +186,86 @@ public function postProcess() $response['message'] = 'Error: ' . $e->getMessage(); } } - header('Content-Type: application/json'); - echo json_encode($response); + if (!$this->bridgeMode) { + header('Content-Type: application/json'); + } + $this->respondJson($response); + break; + case 'save_return_tracking': + $idOrder = (int) Tools::getValue('id_order'); + $value = (string) Tools::getValue('value', ''); + $response = ['success' => false, 'message' => '']; + if (!$idOrder) { + $response['message'] = 'Missing order id'; + } else { + try { + LengowOrderDetail::updateOrderReturnTrackingNumber($value, $idOrder); + $response['success'] = true; + } catch (Exception $e) { + $response['message'] = $e->getMessage(); + } + } + if (!$this->bridgeMode) { + header('Content-Type: application/json'); + } + $this->respondJson($response); + break; + case 'save_return_carrier': + $idOrder = (int) Tools::getValue('id_order'); + $value = (string) Tools::getValue('value', ''); + $response = ['success' => false, 'message' => '']; + if (!$idOrder) { + $response['message'] = 'Missing order id'; + } else { + try { + LengowOrderDetail::updateOrderReturnCarrier($value, $idOrder); + $response['success'] = true; + } catch (Exception $e) { + $response['message'] = $e->getMessage(); + } + } + if (!$this->bridgeMode) { + header('Content-Type: application/json'); + } + $this->respondJson($response); + break; + case 'save_refund_reason': + $idOrder = (int) Tools::getValue('id_order'); + $value = (string) Tools::getValue('value', ''); + $response = ['success' => false, 'message' => '']; + if (!$idOrder) { + $response['message'] = 'Missing order id'; + } else { + $db = Db::getInstance(); + $result = $db->update('lengow_orders', ['refund_reason' => pSQL($value)], 'id_order = ' . $idOrder); + $response['success'] = (bool) $result; + if (!$result) { + $response['message'] = 'No changes or error'; + } + } + if (!$this->bridgeMode) { + header('Content-Type: application/json'); + } + $this->respondJson($response); + break; + case 'save_refund_mode': + $idOrder = (int) Tools::getValue('id_order'); + $value = (string) Tools::getValue('value', ''); + $response = ['success' => false, 'message' => '']; + if (!$idOrder) { + $response['message'] = 'Missing order id'; + } else { + $db = Db::getInstance(); + $result = $db->update('lengow_orders', ['refund_mode' => pSQL($value)], 'id_order = ' . $idOrder); + $response['success'] = (bool) $result; + if (!$result) { + $response['message'] = 'No changes or error'; + } + } + if (!$this->bridgeMode) { + header('Content-Type: application/json'); + } + $this->respondJson($response); break; case 'force_resend': $idOrder = isset($_REQUEST['id_order']) ? (int) $_REQUEST['id_order'] : 0; @@ -194,14 +275,16 @@ public function postProcess() Tools::redirectAdmin(self::getOrderAdminLink($idOrder)); break; } - exit; + $this->finishPostProcess(); } } /** * Get all warning messages + * + * @return void */ - public function assignWarningMessages() + public function assignWarningMessages(): void { $warningMessages = []; if (LengowConfiguration::debugModeIsActive()) { @@ -221,13 +304,15 @@ public function assignWarningMessages() } else { $message = false; } - $this->context->smarty->assign('warning_message', $message); + $this->templateVars['warning_message'] = $message; } /** * Get all last importation data + * + * @return void */ - public function assignLastImportationInfos() + public function assignLastImportationInfos(): void { $lastImport = LengowMain::getLastImport(); $orderCollection = [ @@ -238,15 +323,17 @@ public function assignLastImportationInfos() 'link' => LengowMain::getCronUrl(), ]; $reportMailEnabled = (bool) LengowConfiguration::getGlobalValue(LengowConfiguration::REPORT_MAIL_ENABLED); - $this->context->smarty->assign('reportMailEnabled', $reportMailEnabled); - $this->context->smarty->assign('report_mail_address', LengowConfiguration::getReportEmailAddress()); - $this->context->smarty->assign('orderCollection', $orderCollection); + $this->templateVars['reportMailEnabled'] = $reportMailEnabled; + $this->templateVars['report_mail_address'] = LengowConfiguration::getReportEmailAddress(); + $this->templateVars['orderCollection'] = $orderCollection; } /** * Display data page + * + * @return void */ - public function assignNbOrderImported() + public function assignNbOrderImported(): void { $sql = 'SELECT COUNT(*) as `total` FROM `' . _DB_PREFIX_ . 'lengow_orders`'; try { @@ -255,7 +342,7 @@ public function assignNbOrderImported() } catch (PrestaShopDatabaseException $e) { $nbOrderImported = 0; } - $this->context->smarty->assign('nb_order_imported', $nbOrderImported); + $this->templateVars['nb_order_imported'] = $nbOrderImported; } /** @@ -263,7 +350,7 @@ public function assignNbOrderImported() * * @return LengowList */ - public function loadTable() + public function loadTable(): LengowList { $fieldsList = []; $fieldsList['log_status'] = [ @@ -467,7 +554,8 @@ public function loadTable() 'select_having' => $selectHaving, 'order' => 'IF (order_lengow_state = "waiting_shipment",1,0) DESC, order_date DESC', ], - ] + ], + $this->context ); } @@ -476,7 +564,7 @@ public function loadTable() * * @return string */ - public function buildTable() + public function buildTable(): string { $this->list = $this->loadTable(); $this->list->executeQuery(); @@ -507,9 +595,9 @@ class="lgw-btn lengow_link_tooltip lengow_mass_re_send btn btn-primary"> /** * Get Marketplace (name and label) * - * @return array + * @return array */ - public function getMarketplaces() + public function getMarketplaces(): array { $marketplaces = []; $sql = 'SELECT DISTINCT(marketplace_name) as name, @@ -533,9 +621,9 @@ public function getMarketplaces() /** * Get shop (ID and name) * - * @return array + * @return array */ - public function getShops() + public function getShops(): array { $shops = []; $sql = 'SELECT id_shop, name FROM ' . _DB_PREFIX_ . 'shop WHERE active = 1'; @@ -556,11 +644,11 @@ public function getShops() * * @param string $key row key * @param string $value row value - * @param array $item item values + * @param array $item item values * * @return string */ - public static function displayLengowState($key, $value, $item) + public static function displayLengowState(string $key, string $value, array $item): string { // this two lines are useless, but PrestaShop validator require it $key = $key; @@ -578,14 +666,14 @@ public static function displayLengowState($key, $value, $item) * * @param string $key row key * @param string $value row value - * @param array $item item values + * @param array $item item values * * @return string */ - public static function displayOrderTypes($key, $value, $item) + public static function displayOrderTypes(string $key, string $value, array $item): string { $return = '
'; - $orderTypes = $value !== null ? json_decode($value, true) : []; + $orderTypes = $value !== '' ? json_decode($value, true) : []; if (isset($orderTypes[LengowOrder::TYPE_EXPRESS]) || isset($orderTypes[LengowOrder::TYPE_PRIME])) { $iconLabel = isset($orderTypes[LengowOrder::TYPE_PRIME]) ? $orderTypes[LengowOrder::TYPE_PRIME] @@ -613,18 +701,18 @@ public static function displayOrderTypes($key, $value, $item) * * @param string $key row key * @param string $value row value - * @param array $item item values + * @param array $item item values * * @return string */ - public static function displayOrderLink($key, $value, $item) + public static function displayOrderLink(string $key, string $value, array $item): string { // this line is useless, but PrestaShop validator require it $key = $key; if ($item[LengowOrder::FIELD_ORDER_ID]) { $href = self::getOrderAdminLink($item[LengowOrder::FIELD_ORDER_ID]); - return '' . $value . ''; + return '' . htmlspecialchars($value, ENT_QUOTES, 'UTF-8') . ''; } return $value; @@ -635,11 +723,11 @@ public static function displayOrderLink($key, $value, $item) * * @param string $key row key * @param string $value row value - * @param array $item item values + * @param array $item item values * * @return string */ - public static function displayMarketplaceName($key, $value, $item) + public static function displayMarketplaceName(string $key, string $value, array $item): string { // this line is useless, but PrestaShop validator require it $key = $key; @@ -653,11 +741,11 @@ public static function displayMarketplaceName($key, $value, $item) * * @param string $key row key * @param string $value row value - * @param array $item item values + * @param array $item item values * * @return string */ - public static function displayLogStatus($key, $value, $item) + public static function displayLogStatus(string $key, string $value, array $item): string { if ($item[$key] && (int) $item[LengowOrder::FIELD_ORDER_PROCESS_STATE] !== LengowOrder::PROCESS_STATE_FINISH) { $errorMessages = []; @@ -701,9 +789,10 @@ class="lengow_re_import lengow_link_tooltip lgw-btn lgw-btn-white" } } else { // check if order actions in progress - if (($item[LengowOrder::FIELD_ORDER_ID] > 0 - && (int) $item[LengowOrder::FIELD_ORDER_PROCESS_STATE] - === LengowOrder::PROCESS_STATE_IMPORT) || LengowOrder::PROCESS_STATE_FINISH + if ($item[LengowOrder::FIELD_ORDER_ID] > 0 + && ((int) $item[LengowOrder::FIELD_ORDER_PROCESS_STATE] + === LengowOrder::PROCESS_STATE_IMPORT || (int) $item[LengowOrder::FIELD_ORDER_PROCESS_STATE] + === LengowOrder::PROCESS_STATE_FINISH) ) { $lastActionType = LengowAction::getLastOrderActionType($item[LengowOrder::FIELD_ORDER_ID]); if ($lastActionType) { @@ -728,11 +817,11 @@ class="lengow_re_import lengow_link_tooltip lgw-btn lgw-btn-white" /** * Generate message array (new, update and errors) * - * @param array $return + * @param array $return * - * @return array + * @return array */ - public function loadMessage($return) + public function loadMessage(array $return): array { $messages = []; // if global error return this @@ -786,7 +875,7 @@ public function loadMessage($return) * * @return string */ - public static function generateOrderTypeIcon($iconLabel, $iconColor, $iconMod) + public static function generateOrderTypeIcon(string $iconLabel, string $iconColor, string $iconMod): string { return ' '; if (!empty($legend)) { - $html .= '' . $legend . ''; + $html .= '' . htmlspecialchars($legend, ENT_QUOTES, 'UTF-8') . ''; } break; case self::TYPE_SELECT: - $html .= ' - '; foreach ($input[LengowConfiguration::PARAM_COLLECTION] as $row) { $selected = $row['id'] == $value ? 'selected' : ''; - $html .= ''; + $html .= ''; } $html .= ''; if (!empty($legend)) { - $html .= '' . $legend . ''; + $html .= '' . htmlspecialchars($legend, ENT_QUOTES, 'UTF-8') . ''; } $html .= '
'; break; case self::TYPE_DAY: - $html .= ' + $html .= '
@@ -180,18 +180,18 @@ class="form-control"
'; if (!empty($legend)) { - $html .= '' . $legend . ''; + $html .= '' . htmlspecialchars($legend, ENT_QUOTES, 'UTF-8') . ''; } $html .= '
'; break; case self::TYPE_OPTIONS: - $html .= ' - '; if (!empty($legend)) { - $html .= '' . $legend . ''; + $html .= '' . htmlspecialchars($legend, ENT_QUOTES, 'UTF-8') . ''; } $html .= ''; @@ -205,9 +205,11 @@ class="form-control" /** * Save Lengow settings * - * @param array $checkboxKeys Lengow checkbox + * @param list $checkboxKeys Lengow checkbox + * + * @return void */ - public function postProcess($checkboxKeys) + public function postProcess(array $checkboxKeys): void { try { $sql = 'SELECT id_shop FROM ' . _DB_PREFIX_ . 'shop WHERE active = 1'; @@ -283,8 +285,10 @@ public function postProcess($checkboxKeys) * @param string $key name of Lengow setting * @param mixed $value setting value * @param int $idShop PrestaShop shop id + * + * @return void */ - public function checkAndLog($key, $value, $idShop = null) + public function checkAndLog(string $key, mixed $value, ?int $idShop = null): void { if (array_key_exists($key, $this->fields)) { $setting = $this->fields[$key]; diff --git a/classes/models/LengowConnector.php b/classes/models/LengowConnector.php index 1fce1ceb..718d3f3b 100755 --- a/classes/models/LengowConnector.php +++ b/classes/models/LengowConnector.php @@ -80,17 +80,17 @@ class LengowConnector public const REQUEST_LIMIT = 500; /** - * @var array success HTTP codes for request + * @var list success HTTP codes for request */ - protected $successCodes = [ + protected array $successCodes = [ self::CODE_200, self::CODE_201, ]; /** - * @var array authorization HTTP codes for request + * @var list authorization HTTP codes for request */ - protected $authorizationCodes = [ + protected array $authorizationCodes = [ self::CODE_401, self::CODE_403, ]; @@ -98,12 +98,12 @@ class LengowConnector /** * @var int Authorization token lifetime */ - protected $tokenLifetime = 3000; + protected int $tokenLifetime = 3000; /** - * @var array default options for curl + * @var array default options for curl */ - protected $curlOpts = [ + protected array $curlOpts = [ CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10, @@ -113,22 +113,22 @@ class LengowConnector /** * @var string the access token to connect */ - protected $accessToken; + protected string $accessToken; /** * @var string the secret to connect */ - protected $secret; + protected string $secret; /** - * @var string temporary token for the authorization + * @var string|null temporary token for the authorization */ - protected $token; + protected ?string $token = null; /** - * @var array lengow url for curl timeout + * @var array lengow url for curl timeout */ - protected $lengowUrls = [ + protected array $lengowUrls = [ self::API_ORDER => 20, self::API_ORDER_MOI => 10, self::API_ORDER_ACTION => 15, @@ -141,18 +141,18 @@ class LengowConnector ]; /** - * @var array API requiring no arguments in the call url + * @var list API requiring no arguments in the call url */ - protected $apiWithoutUrlArgs = [ + protected array $apiWithoutUrlArgs = [ self::API_ACCESS_TOKEN, self::API_ORDER_ACTION, self::API_ORDER_MOI, ]; /** - * @var array API requiring no authorization for the call url + * @var list API requiring no authorization for the call url */ - protected static $apiWithoutAuthorizations = [ + protected static array $apiWithoutAuthorizations = [ self::API_PLUGIN, ]; @@ -162,7 +162,7 @@ class LengowConnector * @param string $accessToken your access token * @param string $secret your secret */ - public function __construct($accessToken, $secret) + public function __construct(string $accessToken, string $secret) { $this->accessToken = $accessToken; $this->secret = $secret; @@ -175,7 +175,7 @@ public function __construct($accessToken, $secret) * * @return bool */ - public static function isValidAuth($logOutput = false) + public static function isValidAuth(bool $logOutput = false): bool { if (!LengowToolbox::isCurlActivated()) { return false; @@ -209,13 +209,13 @@ public static function isValidAuth($logOutput = false) * * @param string $type request type (GET / POST / PUT / PATCH) * @param string $api request api - * @param array $args request params + * @param array $args request params * @param string $body body data for request * @param bool $logOutput see log or not * - * @return array|false + * @return mixed */ - public static function queryApi($type, $api, $args = [], $body = '', $logOutput = false) + public static function queryApi(string $type, string $api, array $args = [], string $body = '', bool $logOutput = false): mixed { if (!in_array($type, [self::GET, self::POST, self::PUT, self::PATCH])) { return false; @@ -226,7 +226,7 @@ public static function queryApi($type, $api, $args = [], $body = '', $logOutput if ($accountId === null && $authorizationRequired) { return false; } - $connector = new LengowConnector($accessToken, $secret); + $connector = new LengowConnector($accessToken ?? '', $secret ?? ''); $type = (string) Tools::strtolower($type); $args = $authorizationRequired ? array_merge([LengowImport::ARG_ACCOUNT_ID => $accountId], $args) @@ -258,7 +258,7 @@ public static function queryApi($type, $api, $args = [], $body = '', $logOutput * * @return int|null */ - public static function getAccountIdByCredentials($accessToken, $secret, $logOutput = false) + public static function getAccountIdByCredentials(string $accessToken, string $secret, bool $logOutput = false): ?int { $connector = new LengowConnector($accessToken, $secret); try { @@ -296,17 +296,18 @@ public static function getAccountIdByCredentials($accessToken, $secret, $logOutp * @param bool $force Force cache Update * @param bool $logOutput see log or not * + * @return void + * * @throws LengowException */ - public function connect($force = false, $logOutput = false) + public function connect(bool $force = false, bool $logOutput = false): void { $token = LengowConfiguration::getGlobalValue(LengowConfiguration::AUTHORIZATION_TOKEN); $updatedAt = LengowConfiguration::getGlobalValue(LengowConfiguration::LAST_UPDATE_AUTHORIZATION_TOKEN); if (!$force - && $token !== null - && $updatedAt !== null && $token !== '' - && (time() - $updatedAt) < $this->tokenLifetime + && $updatedAt !== '' + && (time() - (int) $updatedAt) < $this->tokenLifetime ) { $authorizationToken = $token; } else { @@ -321,7 +322,7 @@ public function connect($force = false, $logOutput = false) * Get API call * * @param string $api Lengow method API call - * @param array $args Lengow method API parameters + * @param array $args Lengow method API parameters * @param string $format return format of API * @param string $body body data for request * @param bool $logOutput see log or not @@ -330,7 +331,7 @@ public function connect($force = false, $logOutput = false) * * @throws LengowException */ - public function get($api, $args = [], $format = self::FORMAT_JSON, $body = '', $logOutput = false) + public function get(string $api, array $args = [], string $format = self::FORMAT_JSON, string $body = '', bool $logOutput = false): mixed { return $this->call($api, $args, self::GET, $format, $body, $logOutput); } @@ -339,7 +340,7 @@ public function get($api, $args = [], $format = self::FORMAT_JSON, $body = '', $ * Post API call * * @param string $api Lengow method API call - * @param array $args Lengow method API parameters + * @param array $args Lengow method API parameters * @param string $format return format of API * @param string $body body data for request * @param bool $logOutput see log or not @@ -348,7 +349,7 @@ public function get($api, $args = [], $format = self::FORMAT_JSON, $body = '', $ * * @throws LengowException */ - public function post($api, $args = [], $format = self::FORMAT_JSON, $body = '', $logOutput = false) + public function post(string $api, array $args = [], string $format = self::FORMAT_JSON, string $body = '', bool $logOutput = false): mixed { return $this->call($api, $args, self::POST, $format, $body, $logOutput); } @@ -357,7 +358,7 @@ public function post($api, $args = [], $format = self::FORMAT_JSON, $body = '', * Put API call * * @param string $api Lengow method API call - * @param array $args Lengow method API parameters + * @param array $args Lengow method API parameters * @param string $format return format of API * @param string $body body data for request * @param bool $logOutput see log or not @@ -366,7 +367,7 @@ public function post($api, $args = [], $format = self::FORMAT_JSON, $body = '', * * @throws LengowException */ - public function put($api, $args = [], $format = self::FORMAT_JSON, $body = '', $logOutput = false) + public function put(string $api, array $args = [], string $format = self::FORMAT_JSON, string $body = '', bool $logOutput = false): mixed { return $this->call($api, $args, self::PUT, $format, $body, $logOutput); } @@ -375,7 +376,7 @@ public function put($api, $args = [], $format = self::FORMAT_JSON, $body = '', $ * Patch API call * * @param string $api Lengow method API call - * @param array $args Lengow method API parameters + * @param array $args Lengow method API parameters * @param string $format return format of API * @param string $body body data for request * @param bool $logOutput see log or not @@ -384,7 +385,7 @@ public function put($api, $args = [], $format = self::FORMAT_JSON, $body = '', $ * * @throws LengowException */ - public function patch($api, $args = [], $format = self::FORMAT_JSON, $body = '', $logOutput = false) + public function patch(string $api, array $args = [], string $format = self::FORMAT_JSON, string $body = '', bool $logOutput = false): mixed { return $this->call($api, $args, self::PATCH, $format, $body, $logOutput); } @@ -393,7 +394,7 @@ public function patch($api, $args = [], $format = self::FORMAT_JSON, $body = '', * The API method * * @param string $api Lengow method API call - * @param array $args Lengow method API parameters + * @param array $args Lengow method API parameters * @param string $type type of request GET|POST|PUT|PATCH * @param string $format return format of API * @param string $body body data for request @@ -403,7 +404,7 @@ public function patch($api, $args = [], $format = self::FORMAT_JSON, $body = '', * * @throws LengowException */ - private function call($api, $args, $type, $format, $body, $logOutput) + private function call(string $api, array $args, string $type, string $format, string $body, bool $logOutput): mixed { try { if (!in_array($api, self::$apiWithoutAuthorizations, true)) { @@ -433,7 +434,7 @@ private function call($api, $args, $type, $format, $body, $logOutput) * Call API action * * @param string $api Lengow method API call - * @param array $args Lengow method API parameters + * @param array $args Lengow method API parameters * @param string $type type of request GET|POST|PUT|PATCH * @param string $format return format of API * @param string $body body data for request @@ -443,7 +444,7 @@ private function call($api, $args, $type, $format, $body, $logOutput) * * @throws LengowException */ - private function callAction($api, $args, $type, $format, $body, $logOutput) + private function callAction(string $api, array $args, string $type, string $format, string $body, bool $logOutput): mixed { $this->rateLimitingRequests($api); $result = $this->makeRequest($type, $api, $args, $this->token, $body, $logOutput); @@ -535,7 +536,7 @@ private function getWaitLimitActionRequests(): ?int * * @throws LengowException */ - private function getAuthorizationToken($logOutput) + private function getAuthorizationToken(bool $logOutput): string { // reset temporary token for the new authorization $this->token = null; @@ -554,7 +555,7 @@ private function getAuthorizationToken($logOutput) if (!isset($data['token'])) { throw new LengowException(LengowMain::setLogMessage('log.connector.token_not_return'), self::CODE_500); } - if (Tools::strlen($data['token']) === 0) { + if (mb_strlen((string) $data['token']) === 0) { throw new LengowException(LengowMain::setLogMessage('log.connector.token_is_empty'), self::CODE_500); } @@ -566,8 +567,8 @@ private function getAuthorizationToken($logOutput) * * @param string $type type of request GET|POST|PUT|PATCH * @param string $api Lengow method API call - * @param array $args Lengow method API parameters - * @param string $token temporary authorization token + * @param array $args Lengow method API parameters + * @param string|null $token temporary authorization token * @param string $body body data for request * @param bool $logOutput see log or not * @@ -575,10 +576,8 @@ private function getAuthorizationToken($logOutput) * * @throws LengowException */ - private function makeRequest($type, $api, $args, $token, $body, $logOutput) + private function makeRequest(string $type, string $api, array $args, ?string $token, string $body, bool $logOutput): mixed { - // define CURLE_OPERATION_TIMEDOUT for old php versions - defined('CURLE_OPERATION_TIMEDOUT') || define('CURLE_OPERATION_TIMEDOUT', CURLE_OPERATION_TIMEOUTED); $ch = curl_init(); // get default curl options $opts = $this->curlOpts; @@ -588,6 +587,7 @@ private function makeRequest($type, $api, $args, $token, $body, $logOutput) } // get base url for a specific environment $url = LengowConfiguration::getLengowApiUrl() . $api; + $opts[CURLOPT_CUSTOMREQUEST] = Tools::strtoupper($type); $url = parse_url($url); if (isset($url['port'])) { @@ -610,7 +610,7 @@ private function makeRequest($type, $api, $args, $token, $body, $logOutput) $opts[CURLOPT_HTTPHEADER], [ 'Content-Type: application/json', - 'Content-Length: ' . Tools::strlen($body), + 'Content-Length: ' . mb_strlen((string) $body), ] ); $opts[CURLOPT_POSTFIELDS] = $body; @@ -636,7 +636,6 @@ private function makeRequest($type, $api, $args, $token, $body, $logOutput) $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $curlError = curl_error($ch); $curlErrorNumber = curl_errno($ch); - curl_close($ch); $this->checkReturnRequest($result, $httpCode, $curlError, $curlErrorNumber); return $result; @@ -645,18 +644,20 @@ private function makeRequest($type, $api, $args, $token, $body, $logOutput) /** * Check return request and generate exception if needed * - * @param string $result Curl return call + * @param string|false $result Curl return call * @param int $httpCode request http code * @param string $curlError Curl error - * @param string $curlErrorNumber Curl error number + * @param int $curlErrorNumber Curl error number + * + * @return void * * @throws LengowException */ - private function checkReturnRequest($result, $httpCode, $curlError, $curlErrorNumber) + private function checkReturnRequest(string|false $result, int $httpCode, string $curlError, int $curlErrorNumber): void { if ($result === false) { // recovery of Curl errors - if (in_array($curlErrorNumber, [CURLE_OPERATION_TIMEDOUT, CURLE_OPERATION_TIMEOUTED], true)) { + if ($curlErrorNumber === CURLE_OPERATION_TIMEDOUT) { throw new LengowException(LengowMain::setLogMessage('log.connector.timeout_api'), self::CODE_504); } throw new LengowException(LengowMain::setLogMessage('log.connector.error_curl', ['error_code' => $curlErrorNumber, 'error_message' => $curlError]), self::CODE_500); @@ -679,7 +680,7 @@ private function checkReturnRequest($result, $httpCode, $curlError, $curlErrorNu * * @return mixed */ - private function format($data, $format = self::FORMAT_JSON) + private function format(mixed $data, string $format = self::FORMAT_JSON): mixed { switch ($format) { case self::FORMAT_STREAM: diff --git a/classes/models/LengowContext.php b/classes/models/LengowContext.php new file mode 100644 index 00000000..3edef1ac --- /dev/null +++ b/classes/models/LengowContext.php @@ -0,0 +1,62 @@ + + * @copyright 2021 Lengow SAS + * @license http://www.apache.org/licenses/LICENSE-2.0 + */ +if (!defined('_PS_VERSION_')) { + exit; +} + +/** + * Centralised context provider for the Lengow module. + * + * In PrestaShop 9 the legacy global context helper is deprecated in favour + * of dependency injection. This class acts as the single bridge: + * - The module constructor calls setContext() immediately after parent::__construct() + * so the instance is available before any other class is instantiated. + * - Symfony controllers call setContext() via the @required setter injection in + * AbstractLengowAdminController, ensuring the context is always wired on PS9. + * - All other module classes call LengowContext::getContext() to retrieve it. + */ +class LengowContext +{ + /** @var Context|null Context instance set at module boot */ + private static ?Context $instance = null; + + /** + * Register the Context instance (called from the module constructor). + */ + public static function setContext(Context $context): void + { + self::$instance = $context; + } + + /** + * Retrieve the Context instance. + * + * @throws RuntimeException if setContext() was never called + */ + public static function getContext(): Context + { + if (self::$instance === null) { + throw new RuntimeException('LengowContext has not been initialised. Ensure the Lengow module is loaded before calling LengowContext::getContext().'); + } + + return self::$instance; + } +} diff --git a/classes/models/LengowCountry.php b/classes/models/LengowCountry.php index ca09f4d5..057a7fcb 100755 --- a/classes/models/LengowCountry.php +++ b/classes/models/LengowCountry.php @@ -33,9 +33,9 @@ class LengowCountry * * @return string */ - public static function getNameByIso($isoCode) + public static function getNameByIso(string $isoCode): string { - $idLang = (int) Context::getContext()->language->id; + $idLang = (int) LengowContext::getContext()->language->id; if ($idLang > 0) { $where = 'AND id_lang = ' . $idLang; } else { @@ -54,14 +54,14 @@ public static function getNameByIso($isoCode) * * @param int $idCountry PrestaShop country id * - * @return array|false + * @return array|false */ - public static function getCountry($idCountry) + public static function getCountry(int $idCountry): array|false { return Db::getInstance()->getRow( 'SELECT c.id_country, c.iso_code, cl.name FROM ' . _DB_PREFIX_ . 'country as c INNER JOIN ' . _DB_PREFIX_ . 'country_lang as cl ON c.id_country = cl.id_country - AND cl.id_lang = ' . (int) Context::getContext()->language->id . ' + AND cl.id_lang = ' . (int) LengowContext::getContext()->language->id . ' WHERE c.id_country = ' . (int) $idCountry ); } diff --git a/classes/models/LengowCustomer.php b/classes/models/LengowCustomer.php index 37df9e9d..3d79ed47 100755 --- a/classes/models/LengowCustomer.php +++ b/classes/models/LengowCustomer.php @@ -31,14 +31,14 @@ class LengowCustomer extends Customer /** * @var string customer full name */ - public $fullName; + public string $fullName; /** * Get definition array * - * @return array + * @return array */ - public static function getFieldDefinition() + public static function getFieldDefinition(): array { return self::$definition['fields']; } @@ -46,19 +46,19 @@ public static function getFieldDefinition() /** * Assign API data * - * @param array $data API data + * @param array $data API data * * @return LengowCustomer */ - public function assign($data = []) + public function assign(array $data = []): LengowCustomer { $this->company = LengowAddress::cleanName((string) $data['company']); $this->email = $data['email']; $this->firstname = $data['first_name']; $this->lastname = $data['last_name']; $this->fullName = $data['full_name']; - $this->passwd = md5(rand()); - $this->id_gender = LengowGender::getGender((string) $data['civility']); + $this->passwd = md5((string) rand()); + $this->id_gender = (int) LengowGender::getGender((string) $data['civility']); $this->id_default_group = LengowConfiguration::get(LengowConfiguration::ORDER_CUSTOMER_GROUP); return $this; @@ -71,10 +71,14 @@ public function assign($data = []) * * @throws Exception|LengowException invalid object */ - public function validateLengow() + public function validateLengow(): bool { $definition = self::getFieldDefinition(); + $allowedFields = array_keys($definition); foreach ($definition as $fieldName => $constraints) { + if (!in_array($fieldName, $allowedFields, true)) { + continue; + } if (isset($constraints['required']) && $constraints['required'] && !$this->{$fieldName}) { $this->validateFieldLengow($fieldName, LengowAddress::LENGOW_EMPTY_ERROR); } @@ -96,9 +100,11 @@ public function validateLengow() * Modify a field according to the type of error * * @param string $fieldName incorrect field - * @param string $errorType type of error + * @param int $errorType type of error + * + * @return void */ - public function validateFieldLengow($fieldName, $errorType) + public function validateFieldLengow(string $fieldName, int $errorType): void { switch ($errorType) { case LengowAddress::LENGOW_EMPTY_ERROR: @@ -116,9 +122,15 @@ public function validateFieldLengow($fieldName, $errorType) * Modify an empty field * * @param string $fieldName field name + * + * @return void */ - public function validateEmptyLengow($fieldName) + public function validateEmptyLengow(string $fieldName): void { + $allowedFields = array_keys(self::getFieldDefinition()); + if (!in_array($fieldName, $allowedFields, true)) { + return; + } switch ($fieldName) { case 'lastname': case 'firstname': @@ -152,54 +164,20 @@ public function validateEmptyLengow($fieldName) * Modify a field to fit its size * * @param string $fieldName field name + * + * @return void */ - public function validateSizeLengow($fieldName) + public function validateSizeLengow(string $fieldName): void { - switch ($fieldName) { - case 'address1': - case 'address2': - case 'other': - $addressFullArray = explode(' ', $this->address_full); - if (count($addressFullArray) < 1) { - $definition = self::getFieldDefinition(); - $address1MaxLength = $definition['address1']['size']; - $address2MaxLength = $definition['address1']['size']; - $otherMaxLength = $definition['other']['size']; - $this->address1 = ''; - $this->address2 = ''; - $this->other = ''; - foreach ($addressFullArray as $addressPart) { - if (Tools::strlen($this->address1) < $address1MaxLength) { - if (!empty($this->address1)) { - $this->address1 .= ' '; - } - $this->address1 .= $addressPart; - continue; - } - if (Tools::strlen($this->address2) < $address2MaxLength) { - if (!empty($this->address2)) { - $this->address2 .= ' '; - } - $this->address2 .= $addressPart; - continue; - } - if (Tools::strlen($this->other) < $otherMaxLength) { - if (!empty($this->other)) { - $this->other .= ' '; - } - $this->other .= $addressPart; - } - } - } - break; - case 'phone': - $this->phone = LengowMain::cleanPhone($this->phone); - break; - case 'phone_mobile': - $this->phone_mobile = LengowMain::cleanPhone($this->phone_mobile); - break; - default: - break; + // Customer fields are validated by their own definition. + // Address-specific fields (address1, address2, other, phone, phone_mobile) + // are handled by LengowAddress::validateSizeLengow() instead. + $definition = self::getFieldDefinition(); + if (!array_key_exists($fieldName, $definition)) { + return; + } + if (isset($definition[$fieldName]['size'])) { + $this->{$fieldName} = Tools::substr($this->{$fieldName}, 0, $definition[$fieldName]['size']); } } @@ -211,7 +189,7 @@ public function validateSizeLengow($fieldName) * * @return LengowCustomer|false */ - public function getByEmailAndShop($email, $idShop) + public function getByEmailAndShop(string $email, int $idShop): LengowCustomer|false { $sql = 'SELECT * FROM `' . _DB_PREFIX_ . 'customer` @@ -223,7 +201,12 @@ public function getByEmailAndShop($email, $idShop) return false; } $this->id = $result['id_customer']; + $allowedKeys = array_keys(self::getFieldDefinition()); + $allowedKeys[] = 'id_customer'; foreach ($result as $key => $value) { + if (!in_array($key, $allowedKeys, true)) { + continue; + } if (property_exists($this, $key)) { $this->{$key} = $value; } diff --git a/classes/models/LengowExport.php b/classes/models/LengowExport.php index 75781975..1ef35b50 100755 --- a/classes/models/LengowExport.php +++ b/classes/models/LengowExport.php @@ -58,14 +58,14 @@ class LengowExport public const PARAM_LEGACY_LANGUAGE = 'lang'; /** - * @var array default fields for export + * @var array default fields for export */ - public static $defaultFields; + public static array $defaultFields = []; /** - * @var array all available params for export + * @var list all available params for export */ - public static $exportParams = [ + public static array $exportParams = [ self::PARAM_MODE, self::PARAM_FORMAT, self::PARAM_STREAM, @@ -86,9 +86,9 @@ class LengowExport ]; /** - * @var array new fields for v3 + * @var array new fields for v3 */ - protected $newFields = [ + protected array $newFields = [ 'id' => 'id', 'sku' => 'sku', 'sku_supplier' => 'sku_supplier', @@ -149,9 +149,9 @@ class LengowExport ]; /** - * @var array legacy fields for export + * @var array legacy fields for export */ - protected $legacyFields = [ + protected array $legacyFields = [ 'id_product' => 'id', 'name_product' => 'name', 'reference_product' => 'sku', @@ -213,112 +213,112 @@ class LengowExport /** * @var string format to return */ - protected $format; + protected string $format; /** * @var Carrier PrestaShop Carrier instance */ - protected $carrier; + protected Carrier $carrier; /** * @var LengowFeed Feed */ - protected $feed; + protected LengowFeed $feed; /** * @var int PrestaShop shop id */ - protected $idShop; + protected int $idShop; /** * @var bool stream return */ - protected $stream = true; + protected bool $stream = true; /** * @var bool export Lengow selection */ - protected $selection = false; + protected bool $selection = false; /** * @var bool export out of stock product */ - protected $outOfStock = false; + protected bool $outOfStock = false; /** - * @var string export language + * @var Language export language */ - protected $language; + protected Language $language; /** * @var bool export product variations */ - protected $variation = true; + protected bool $variation = true; /** * @var bool include active products */ - protected $inactive = false; + protected bool $inactive = false; /** * @var bool see log or not */ - protected $logOutput; + protected bool $logOutput; /** - * @var bool use legacy fields + * @var bool|null use legacy fields */ - protected $legacy = false; + protected ?bool $legacy = null; /** * @var int amount of products to export */ - protected $limit = 0; + protected int $limit = 0; /** * @var int offset of total product */ - protected $offset = 0; + protected int $offset = 0; /** - * @var array product ids to be exported + * @var array product ids to be exported */ - protected $productIds = []; + protected array $productIds = []; /** * @var bool update export date */ - protected $updateExportDate; + protected bool $updateExportDate; /** - * @var array cache combination + * @var array>> cache combination */ - protected $cacheCombination; + protected array $cacheCombination; /** - * @var array excluded products for export + * @var array excluded products for export */ - protected $excludedProducts = []; + protected array $excludedProducts = []; /** * Construct new Lengow export * - * @param array $params optional options - * integer limit The number of product to be exported - * integer offset From what product export - * integer shop_id Shop id for export - * integer language_id language for export - * string product_ids Ids product to export - * string format Export Format (csv|yaml|xml|json) - * boolean stream Display file when call script (1) | Save File (0) - * boolean out_of_stock Export product in stock and out stock (1) | Export Only in stock product (0) - * boolean selection Export selected product (1) | Export all products (0) - * boolean inactive Export active and inactive product (1) | Export Only active product (0) - * boolean variation Export product variation (1) | Export Only simple product (0) - * boolean legacy_fields Export with legacy fields (1) | Export with new fields (0) - * boolean update_export_date Update 'LENGOW_LAST_EXPORT' when launching export process (1) or not - */ - public function __construct($params = []) + * @param array $params optional options + * integer limit The number of product to be exported + * integer offset From what product export + * integer shop_id Shop id for export + * integer language_id language for export + * string product_ids Ids product to export + * string format Export Format (csv|yaml|xml|json) + * boolean stream Display file when call script (1) | Save File (0) + * boolean out_of_stock Export product in stock and out stock (1) | Export Only in stock product (0) + * boolean selection Export selected product (1) | Export all products (0) + * boolean inactive Export active and inactive product (1) | Export Only active product (0) + * boolean variation Export product variation (1) | Export Only simple product (0) + * boolean legacy_fields Export with legacy fields (1) | Export with new fields (0) + * boolean update_export_date Update 'LENGOW_LAST_EXPORT' when launching export process (1) or not + */ + public function __construct(array $params = []) { $this->setFormat(isset($params[self::PARAM_FORMAT]) ? $params[self::PARAM_FORMAT] : LengowFeed::FORMAT_CSV); $this->offset = isset($params[self::PARAM_OFFSET]) ? (int) $params[self::PARAM_OFFSET] : false; @@ -328,11 +328,11 @@ public function __construct($params = []) $this->idShop = (int) ( isset($params[self::PARAM_SHOP_ID]) ? $params[self::PARAM_SHOP_ID] - : Context::getContext()->shop->id + : LengowContext::getContext()->shop->id ); $this->language = isset($params[self::PARAM_LANGUAGE_ID]) ? new Language($params[self::PARAM_LANGUAGE_ID]) - : new Language(Configuration::get('PS_LANG_DEFAULT', null, null, $this->idShop)); + : new Language((int) Configuration::get('PS_LANG_DEFAULT', null, null, $this->idShop)); // get specific params in database $selection = LengowConfiguration::get(LengowConfiguration::SELECTION_ENABLED, null, null, $this->idShop); $outOfStock = LengowConfiguration::get(LengowConfiguration::OUT_OF_STOCK_ENABLED, null, null, $this->idShop); @@ -340,25 +340,29 @@ public function __construct($params = []) $inactive = LengowConfiguration::get(LengowConfiguration::INACTIVE_ENABLED, null, null, $this->idShop); // set default value for new shop if ($selection === null) { - LengowConfiguration::updateValue(LengowConfiguration::SELECTION_ENABLED, 0, null, null, $this->idShop); + LengowConfiguration::updateValue(LengowConfiguration::SELECTION_ENABLED, 0, + false, null, $this->idShop); $selection = false; } else { $selection = (bool) $selection; } if ($outOfStock === null) { - LengowConfiguration::updateValue(LengowConfiguration::OUT_OF_STOCK_ENABLED, 1, null, null, $this->idShop); + LengowConfiguration::updateValue(LengowConfiguration::OUT_OF_STOCK_ENABLED, 1, + false, null, $this->idShop); $outOfStock = true; } else { $outOfStock = (bool) $outOfStock; } if ($variation === null) { - LengowConfiguration::updateValue(LengowConfiguration::VARIATION_ENABLED, 1, null, null, $this->idShop); + LengowConfiguration::updateValue(LengowConfiguration::VARIATION_ENABLED, 1, + false, null, $this->idShop); $variation = true; } else { $variation = (bool) $variation; } if ($inactive === null) { - LengowConfiguration::updateValue(LengowConfiguration::INACTIVE_ENABLED, 0, null, null, $this->idShop); + LengowConfiguration::updateValue(LengowConfiguration::INACTIVE_ENABLED, 0, + false, null, $this->idShop); $inactive = false; } else { $inactive = (bool) $inactive; @@ -376,8 +380,8 @@ public function __construct($params = []) } $this->updateExportDate = !isset($params[self::PARAM_UPDATE_EXPORT_DATE]) || $params[self::PARAM_UPDATE_EXPORT_DATE]; - if (!Context::getContext()->currency) { - Context::getContext()->currency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT')); + if (!LengowContext::getContext()->currency) { + LengowContext::getContext()->currency = new Currency((int) Configuration::get('PS_CURRENCY_DEFAULT')); } $this->legacy = isset($params[self::PARAM_LEGACY_FIELDS]) ? (bool) $params[self::PARAM_LEGACY_FIELDS] : null; } @@ -386,16 +390,20 @@ public function __construct($params = []) * Set format to export * * @param string $format The export format + * + * @return void */ - public function setFormat($format) + public function setFormat(string $format): void { $this->format = in_array($format, LengowFeed::$availableFormats, true) ? $format : LengowFeed::FORMAT_CSV; } /** * Execute export process + * + * @return void */ - public function exec() + public function exec(): void { try { // clean logs @@ -469,9 +477,9 @@ public function exec() * * @throws LengowException illegal currency */ - public function checkCurrency() + public function checkCurrency(): bool { - if (!Context::getContext()->currency) { + if (!LengowContext::getContext()->currency) { throw new LengowException(LengowMain::setLogMessage('log.export.error_illegal_currency')); } @@ -485,7 +493,7 @@ public function checkCurrency() * * @throws LengowException no default carrier selected */ - public function setCarrier() + public function setCarrier(): bool { $carrier = LengowCarrier::getDefaultExportCarrier(); if (!$carrier) { @@ -498,8 +506,10 @@ public function setCarrier() /** * Set or not legacy fields to export + * + * @return void */ - public function setLegacyFields() + public function setLegacyFields(): void { if ($this->legacy === null) { $merchantStatus = LengowSync::getStatusAccount(); @@ -515,28 +525,30 @@ public function setLegacyFields() /** * Export products * - * @param array $products list of products to be exported - * @param array $fields list of fields + * @param list $products list of products to be exported + * @param list $fields list of fields * @param Shop $shop PrestaShop shop being exported * + * @return void + * * @throws Exception|LengowException folder not writable */ - public function export($products, $fields, $shop) + public function export(array $products, array $fields, Shop $shop): void { $productCount = 0; $this->feed = new LengowFeed( $this->stream, $this->format, $this->legacy, - isset($shop->name) ? $shop->name : 'default' + $shop->name !== '' ? $shop->name : 'default' ); $this->feed->write(LengowFeed::HEADER, $fields); $isFirst = true; // get the maximum of character for yaml format $maxCharacter = 0; foreach ($fields as $field) { - if (Tools::strlen($field) > $maxCharacter) { - $maxCharacter = Tools::strlen($field); + if (mb_strlen((string) $field) > $maxCharacter) { + $maxCharacter = mb_strlen((string) $field); } } foreach ($products as $p) { @@ -637,13 +649,13 @@ public function export($products, $fields, $shop) * Load cache combinations * * @param LengowProduct $product Lengow product instance - * @param array $fields list of fields + * @param list $fields list of fields * * @return bool * * @throws Exception */ - public function loadCacheCombinations($product, $fields) + public function loadCacheCombinations(LengowProduct $product, array $fields): bool { if (!isset($this->cacheCombination[$product->id])) { $this->cacheCombination = []; @@ -677,7 +689,7 @@ public function loadCacheCombinations($product, $fields) * * @return int */ - public function getTotalProduct() + public function getTotalProduct(): int { $join = ' INNER JOIN ' . _DB_PREFIX_ . 'product_shop ps ON (ps.id_product = p.id_product AND ps.id_shop = ' . (int) $this->idShop . ') '; @@ -708,7 +720,7 @@ public function getTotalProduct() * * @return int */ - public function getTotalExportProduct() + public function getTotalExportProduct(): int { if ($this->variation) { $query = ' SELECT SUM(total) as total FROM ( ( '; @@ -735,7 +747,7 @@ public function getTotalExportProduct() * * @return string */ - public function buildTotalQuery($variation = false) + public function buildTotalQuery(bool $variation = false): string { $where = []; $query = ' FROM ' . _DB_PREFIX_ . 'product p'; @@ -759,7 +771,7 @@ public function buildTotalQuery($variation = false) // verify if multishop and share stock is active if ( Configuration::get('PS_MULTISHOP_FEATURE_ACTIVE') == 1 - && Context::getContext()->shop->getContextShopGroup()->share_stock === 1 + && LengowContext::getContext()->shop->getContextShopGroup()->share_stock === 1 ) { $query .= ' INNER JOIN ' . _DB_PREFIX_ . 'stock_available sa ON (sa.id_product=p.id_product @@ -790,9 +802,9 @@ public function buildTotalQuery($variation = false) /** * Get the products to export * - * @return array + * @return array */ - public function exportIds() + public function exportIds(): array { if ($this->variation) { $query = ' SELECT * FROM ( ( '; @@ -820,9 +832,9 @@ public function exportIds() /** * Get fields to export * - * @return array + * @return array */ - protected function getFields() + protected function getFields(): array { $fields = []; // check field name to lower to avoid duplicates @@ -869,7 +881,7 @@ protected function getFields() * * @return string */ - public function getFileName() + public function getFileName(): string { return $this->feed->getFilename(); } @@ -879,7 +891,7 @@ public function getFileName() * * @return string */ - public function getExportParams() + public function getExportParams(): string { $params = []; foreach (self::$exportParams as $param) { @@ -954,11 +966,11 @@ public function getExportParams() /** * Override this function in override/lengow.export.class.php to add header * - * @param array $fields fields to export + * @param list $fields fields to export * - * @return array + * @return array */ - public static function setAdditionalFields($fields) + public static function setAdditionalFields(array $fields): array { /* * Write here your process @@ -973,11 +985,11 @@ public static function setAdditionalFields($fields) * * @param LengowProduct $product Lengow product instance * @param int|null $idProductAttribute PrestaShop product attribute id - * @param array|null $arrayProduct product data + * @param array|null $arrayProduct product data * - * @return array + * @return array */ - public static function setAdditionalFieldsValues($product, $idProductAttribute = null, $arrayProduct = null) + public static function setAdditionalFieldsValues(LengowProduct $product, ?int $idProductAttribute = null, ?array $arrayProduct = null): array { /** * Write here your process diff --git a/classes/models/LengowFeed.php b/classes/models/LengowFeed.php index 17b35d1c..e6791308 100755 --- a/classes/models/LengowFeed.php +++ b/classes/models/LengowFeed.php @@ -55,42 +55,42 @@ class LengowFeed /** * @var LengowFile Lengow file instance */ - protected $file; + protected LengowFile $file; /** * @var string feed content */ - protected $content = ''; + protected string $content = ''; /** * @var bool stream or file */ - protected $stream; + protected bool $stream; /** * @var string feed format */ - protected $format; + protected string $format; /** * @var bool Use legacy fields */ - protected $legacy; + protected bool $legacy; /** * @var string|null export shop folder */ - protected $shopFolder; + protected ?string $shopFolder = null; /** * @var string full export folder */ - protected $exportFolder; + protected string $exportFolder; /** - * @var array formats available for export + * @var list formats available for export */ - public static $availableFormats = [ + public static array $availableFormats = [ self::FORMAT_CSV, self::FORMAT_YAML, self::FORMAT_XML, @@ -107,13 +107,13 @@ class LengowFeed * * @throws LengowException unable to create folder */ - public function __construct($stream, $format, $legacy, $shopName = null) + public function __construct(bool $stream, string $format, bool $legacy, ?string $shopName = null) { $this->stream = $stream; $this->format = $format; $this->legacy = $legacy; if ($shopName === null) { - $shopName = Context::getContext()->shop->name; + $shopName = LengowContext::getContext()->shop->name; } $this->shopFolder = LengowMain::getShopNameCleaned($shopName); if (!$this->stream) { @@ -124,9 +124,11 @@ public function __construct($stream, $format, $legacy, $shopName = null) /** * Create export file * + * @return void + * * @throws LengowException unable to create folder */ - public function initExportFile() + public function initExportFile(): void { $sep = DIRECTORY_SEPARATOR; $this->exportFolder = LengowMain::FOLDER_EXPORT . $sep . $this->shopFolder; @@ -134,7 +136,7 @@ public function initExportFile() if (!file_exists($folderPath) && !mkdir($folderPath) && !is_dir($folderPath)) { throw new LengowException(LengowMain::setLogMessage('log.export.error_unable_to_create_folder', ['folder_path' => $folderPath])); } - $fileName = 'flux-' . Context::getContext()->language->iso_code . '-' . time() . '.' . $this->format; + $fileName = 'flux-' . LengowContext::getContext()->language->iso_code . '-' . time() . '.' . $this->format; $this->file = new LengowFile($this->exportFolder, $fileName); } @@ -142,11 +144,13 @@ public function initExportFile() * Write feed * * @param string $type data type (header, body or footer) - * @param array $data export data + * @param array $data export data * @param bool|null $isFirst is first product - * @param bool|null $maxCharacter max characters for yaml format + * @param int|null $maxCharacter max characters for yaml format + * + * @return void */ - public function write($type, $data = [], $isFirst = null, $maxCharacter = null) + public function write(string $type, array $data = [], ?bool $isFirst = null, ?int $maxCharacter = null): void { switch ($type) { case self::HEADER: @@ -173,11 +177,11 @@ public function write($type, $data = [], $isFirst = null, $maxCharacter = null) /** * Return feed header * - * @param array $data export data + * @param array $data export data * * @return string */ - protected function getHeader($data) + protected function getHeader(array $data): string { switch ($this->format) { case self::FORMAT_CSV: @@ -202,13 +206,13 @@ protected function getHeader($data) /** * Get feed body * - * @param array $data feed data + * @param array $data feed data * @param bool $isFirst is first product * @param int $maxCharacter max characters for yaml format * * @return string */ - protected function getBody($data, $isFirst, $maxCharacter) + protected function getBody(array $data, bool $isFirst, int $maxCharacter): string { switch ($this->format) { case self::FORMAT_CSV: @@ -260,7 +264,7 @@ protected function getBody($data, $isFirst, $maxCharacter) * * @return string */ - protected function getFooter() + protected function getFooter(): string { switch ($this->format) { case self::FORMAT_XML: @@ -276,8 +280,10 @@ protected function getFooter() * Flush feed content * * @param string $content feed content to be flushed + * + * @return void */ - public function flush($content) + public function flush(string $content): void { if ($this->stream) { echo $content; @@ -294,11 +300,11 @@ public function flush($content) * * @throws LengowException */ - public function end() + public function end(): bool { $this->write(self::FOOTER); if (!$this->stream) { - $oldFileName = 'flux-' . Context::getContext()->language->iso_code . '.' . $this->format; + $oldFileName = 'flux-' . LengowContext::getContext()->language->iso_code . '.' . $this->format; $oldFile = new LengowFile($this->exportFolder, $oldFileName); if ($oldFile->exists()) { $oldFilePath = $oldFile->getPath(); @@ -324,7 +330,7 @@ public function end() * * @return string */ - public function getUrl() + public function getUrl(): string { return $this->file->getLink(); } @@ -334,7 +340,7 @@ public function getUrl() * * @return string */ - public function getFileName() + public function getFileName(): string { return $this->file->getPath(); } @@ -344,7 +350,7 @@ public function getFileName() * * @return string */ - protected function getHtmlHeader() + protected function getHtmlHeader(): string { switch ($this->format) { case self::FORMAT_CSV: @@ -368,7 +374,7 @@ protected function getHtmlHeader() * * @return string */ - public static function formatFields($str, $format, $legacy = false) + public static function formatFields(string $str, string $format, bool $legacy = false): string { switch ($format) { case self::FORMAT_CSV: @@ -412,13 +418,13 @@ public static function formatFields($str, $format, $legacy = false) * For YAML, add spaces to have good indentation * * @param string $name the field name - * @param string $maxSize space limit + * @param int $maxSize space limit * * @return string */ - protected function indentYaml($name, $maxSize) + protected function indentYaml(string $name, int $maxSize): string { - $strlen = Tools::strlen($name); + $strlen = mb_strlen((string) $name); $spaces = ''; for ($i = $strlen; $i < $maxSize; ++$i) { $spaces .= ' '; diff --git a/classes/models/LengowFile.php b/classes/models/LengowFile.php index 62c9c576..e99964cd 100755 --- a/classes/models/LengowFile.php +++ b/classes/models/LengowFile.php @@ -29,20 +29,20 @@ class LengowFile /** * @var string file name */ - public $fileName; + public string $fileName; /** * @var string folder name that contains the file */ - public $folderName; + public string $folderName; /** - * @var string file link + * @var string|null file link */ - public $link; + public ?string $link = null; /** - * @var resource a file pointer resource + * @var resource|null a file pointer resource */ public $instance; @@ -55,7 +55,7 @@ class LengowFile * * @throws LengowException unable to create file */ - public function __construct($folderName, $fileName = null, $mode = 'a+') + public function __construct(string $folderName, ?string $fileName = null, string $mode = 'a+') { $this->fileName = $fileName; $this->folderName = $folderName; @@ -77,8 +77,10 @@ public function __destruct() * Write content in file * * @param string $txt text to be written + * + * @return void */ - public function write($txt) + public function write(string $txt): void { if (!$this->instance) { $this->instance = fopen($this->getPath(), 'a+'); @@ -88,8 +90,10 @@ public function write($txt) /** * Delete file + * + * @return void */ - public function delete() + public function delete(): void { if ($this->exists()) { if ($this->instance) { @@ -105,10 +109,14 @@ public function delete() * @param string $path path to the file * @param string $mode type of access * - * @return resource + * @return resource|false */ - public static function getResource($path, $mode = 'a+') + public static function getResource(string $path, string $mode = 'a+'): mixed { + if (!LengowMain::isPathAllowed($path, _PS_MODULE_LENGOW_DIR_)) { + return false; + } + return fopen($path, $mode); } @@ -117,7 +125,7 @@ public static function getResource($path, $mode = 'a+') * * @return string */ - public function getLink() + public function getLink(): string { if (empty($this->link)) { if (!$this->exists()) { @@ -135,7 +143,7 @@ public function getLink() * * @return string */ - public function getPath() + public function getPath(): string { $sep = DIRECTORY_SEPARATOR; @@ -147,7 +155,7 @@ public function getPath() * * @return string */ - public function getFolderPath() + public function getFolderPath(): string { $sep = DIRECTORY_SEPARATOR; @@ -161,15 +169,17 @@ public function getFolderPath() * * @return bool */ - public function rename($newName) + public function rename(string $newName): bool { return rename($this->getPath(), $newName); } /** * Close file handle + * + * @return void */ - public function close() + public function close(): void { if (is_resource($this->instance)) { fclose($this->instance); @@ -181,7 +191,7 @@ public function close() * * @return bool */ - public function exists() + public function exists(): bool { return file_exists($this->getPath()); } @@ -191,9 +201,9 @@ public function exists() * * @param string $folder folder name * - * @return array|false + * @return array|false */ - public static function getFilesFromFolder($folder) + public static function getFilesFromFolder(string $folder): array|false { $sep = DIRECTORY_SEPARATOR; $folderPath = LengowMain::getLengowFolder() . $sep . $folder; diff --git a/classes/models/LengowGender.php b/classes/models/LengowGender.php index 27e6dc9f..2a7f21e9 100755 --- a/classes/models/LengowGender.php +++ b/classes/models/LengowGender.php @@ -27,9 +27,9 @@ class LengowGender extends Gender { /** - * @var array current alias of mister + * @var list current alias of mister */ - public static $currentMale = [ + public static array $currentMale = [ 'M', 'M.', 'Mr', @@ -46,9 +46,9 @@ class LengowGender extends Gender ]; /** - * @var array current alias of miss + * @var list current alias of miss */ - public static $currentFemale = [ + public static array $currentFemale = [ 'Mme', 'MME', 'mme', @@ -83,7 +83,7 @@ class LengowGender extends Gender * * @return string */ - public static function getGender($name) + public static function getGender(string $name): string { if (empty($name)) { return ''; @@ -99,7 +99,7 @@ public static function getGender($name) $result = Db::getInstance()->ExecuteS($query); if ($result && is_array($result)) { - return (string) $result[0]['id_gender'] ?? ''; + return (string) ($result[0]['id_gender'] ?? ''); } return ''; diff --git a/classes/models/LengowHook.php b/classes/models/LengowHook.php index fd84ccfe..578585c7 100755 --- a/classes/models/LengowHook.php +++ b/classes/models/LengowHook.php @@ -26,78 +26,31 @@ } class LengowHook { - /* PrestaShop track pages */ - public const LENGOW_TRACK_HOMEPAGE = 'homepage'; - public const LENGOW_TRACK_PAGE = 'page'; - public const LENGOW_TRACK_PAGE_LIST = 'listepage'; - public const LENGOW_TRACK_PAGE_PAYMENT = 'payment'; - public const LENGOW_TRACK_PAGE_CART = 'basket'; - public const LENGOW_TRACK_PAGE_CONFIRMATION = 'confirmation'; - - /** - * @var string PrestaShop current page type - */ - private static $currentPageType = 'page'; - - /** - * @var string PrestaShop order id - */ - private static $idOrder = ''; - - /** - * @var string PrestaShop cart id - */ - private static $idCart = ''; - - /** - * @var string order payment - */ - private static $orderPayment = ''; - - /** - * @var string order currency - */ - private static $orderCurrency = ''; - - /** - * @var string total order - */ - private static $orderTotal = ''; - - /** - * @var string product cart ids - */ - private static $idsProductCart = ''; - - /** - * @var string PrestaShop category id - */ - private static $idCategory = ''; - /** - * @var array order is already shipped + * @var array order is already shipped */ - protected $alreadyShipped = []; + protected array $alreadyShipped = []; /** * @var Lengow Lengow module instance */ - private $module; + private Lengow $module; /** * @var Context PrestaShop context */ - private $context; + private Context $context; /** * Construct * * @param Lengow $module Lengow module instance + * @param Context $context PrestaShop context */ - public function __construct($module) + public function __construct(Lengow $module, Context $context) { $this->module = $module; - $this->context = Context::getContext(); + $this->context = $context; } /** @@ -105,15 +58,14 @@ public function __construct($module) * * @return bool */ - public function registerHooks() + public function registerHooks(): bool { $error = false; $lengowHooks = [ // common version 'postUpdateOrderStatus' => '1.4', - 'paymentTop' => '1.4', + 'displayPaymentTop' => '1.4', 'displayAdminOrder' => '1.4', - 'home' => '1.4', 'actionOrderStatusUpdate' => '1.4', 'orderConfirmation' => '1.4', // version 1.5 @@ -123,14 +75,30 @@ public function registerHooks() 'displayAdminOrderSide' => '1.6', // version 8.0 'displayHome' => '8.0', - 'actionOrderStatusPostUpdate' => '8.0' + 'actionOrderStatusPostUpdate' => '8.0', + 'actionProductCancel' => '8.0', + // PS 8.0+ — order page tabs + 'displayAdminOrderTabLink' => '8.0', + 'displayAdminOrderTabContent' => '8.0', + // PS routing: maps legacy webservice/*.php URLs to the FO controllers + 'moduleRoutes' => '1.5', ]; + foreach ($lengowHooks as $hook => $version) { if ((float) $version <= (float) Tools::substr(_PS_VERSION_, 0, 3)) { if ($this->module->isRegisteredInHook($hook)) { continue; } - if (!$this->module->registerHook($hook)) { + try { + $registered = $this->module->registerHook($hook); + } catch (PrestaShopDatabaseException $e) { + LengowMain::log( + LengowLog::CODE_INSTALL, + LengowMain::setLogMessage('log.install.registering_hook_success', ['hook' => $hook]) + ); + continue; + } + if (!$registered) { LengowMain::log( LengowLog::CODE_INSTALL, LengowMain::setLogMessage('log.install.registering_hook_error', ['hook' => $hook]) @@ -145,31 +113,47 @@ public function registerHooks() } } + // Cleanup: If the deprecated 'home' hook is registered, unregister it to avoid + // PrestaShop deprecation warnings. New hook name is 'displayHome'. + if ($this->module->isRegisteredInHook('home')) { + $this->module->unregisterHook('home'); + LengowMain::log( + LengowLog::CODE_INSTALL, + LengowMain::setLogMessage('log.install.unregistering_deprecated_hook', ['hook' => 'home']) + ); + } + return !$error; } /** * Hook to display the icon + * + * @return void */ - public function hookDisplayBackOfficeHeader() + public function hookDisplayBackOfficeHeader(): void { $this->context->controller->addCss(_PS_MODULE_LENGOW_DIR_ . 'views/css/lengow-tab.css'); } /** * Hook on Home page + * + * @return void */ - public function hookDisplayHome() + public function hookDisplayHome(): void { - self::$currentPageType = self::LENGOW_TRACK_HOMEPAGE; + // tracker is disabled now } /** * Hook on Payment page + * + * @return void */ - public function hookPaymentTop() + public function hookPaymentTop(): void { - self::$currentPageType = self::LENGOW_TRACK_PAGE; + // tracker is disabled now } /** @@ -177,7 +161,7 @@ public function hookPaymentTop() * * @return mixed */ - public function hookFooter() + public function hookFooter(): mixed { // tracker is disabled now return ''; @@ -186,70 +170,26 @@ public function hookFooter() /** * Hook on order confirmation page to init order's product list * - * @param array $args arguments of hook + * @param array $args arguments of hook * - * @return mixed null|void + * @return void */ - public function hookOrderConfirmation($args) + public function hookOrderConfirmation(array $args): void { - if (!isset($args['objOrder']) && !isset($args['order'])) { - return; - } - $i = 0; - $productsCart = []; - $order = isset($args['objOrder']) ? $args['objOrder'] : $args['order']; - $orderTotal = Tools::ps_round($order->total_paid, 2); - $paymentMethod = LengowMain::replaceAccentedChars(Tools::strtolower(str_replace(' ', '_', $order->payment))); - $currency = new Currency($order->id_currency); - $productsList = $order->getProducts(); - foreach ($productsList as $p) { - ++$i; - switch (LengowConfiguration::get(LengowConfiguration::TRACKING_ID)) { - case 'upc': - $idProduct = $p['upc']; - break; - case 'ean': - $idProduct = $p['ean13']; - break; - case 'ref': - $idProduct = $p['reference']; - break; - default: - if ($p['product_attribute_id']) { - $idProduct = $p['product_id'] . '_' . $p['product_attribute_id']; - } else { - $idProduct = $p['product_id']; - } - break; - } - $price = isset($p['product_price_wt']) ? $p['product_price_wt'] : $p['unit_price_tax_incl']; - // basket product - $productsCart[] = [ - 'product_id' => $idProduct, - 'price' => Tools::ps_round($price, 2), - 'quantity' => $p['product_quantity'], - ]; - } - self::$idsProductCart = json_encode($productsCart); - self::$currentPageType = self::LENGOW_TRACK_PAGE_CONFIRMATION; - self::$idOrder = $order->id; - self::$idCart = $order->id_cart; - self::$orderTotal = $orderTotal; - self::$orderPayment = $paymentMethod; - self::$orderCurrency = $currency->iso_code; + // tracker is disabled now } /** * Hook on admin page's order * - * @param array $args arguments of hook + * @param array $args arguments of hook * * @return mixed */ - public function hookAdminOrder($args) + public function hookAdminOrder(array $args): mixed { if (!isset($args['id_order'])) { - return; + return null; } if (LengowOrder::isFromLengow($args['id_order'])) { $lengowLink = new LengowLink(); @@ -317,11 +257,11 @@ public function hookAdminOrder($args) /** * Hook on admin page's order side * - * @param array $args Arguments of hook + * @param array $params Arguments of hook * * @return mixed */ - public function hookAdminOrderSide($params) + public function hookAdminOrderSide(array $params): mixed { $id_order = (int) $params['id_order']; $lengowOrder = LengowOrder::getLengowOrderByPrestashopId($id_order); @@ -347,11 +287,11 @@ public function hookAdminOrderSide($params) /** * Hook before an status' update to synchronize status with lengow * - * @param array $args arguments of hook + * @param array $args arguments of hook * - * @return mixed null|void + * @return void */ - public function hookUpdateOrderStatus($args) + public function hookUpdateOrderStatus(array $args): void { if (!isset($args['id_order']) || !(bool) LengowConfiguration::get(LengowConfiguration::SEND_EMAIL_DISABLED)) { return; @@ -369,11 +309,11 @@ public function hookUpdateOrderStatus($args) /** * Hook after an status' update to synchronize status with lengow * - * @param array $args arguments of hook + * @param array $args arguments of hook * - * @return mixed null|void + * @return void */ - public function hookActionOrderStatusPostUpdate($args) + public function hookActionOrderStatusPostUpdate(array $args): void { if (!isset($args['id_order'])) { return; @@ -418,17 +358,17 @@ public function hookActionOrderStatusPostUpdate($args) /** * Update, if isset tracking number * - * @param array $args arguments of hook + * @param array $args arguments of hook * - * @return mixed null|void + * @return void */ - public function hookActionObjectUpdateAfter($args) + public function hookActionObjectUpdateAfter(array $args): void { if (!isset($args['object']->id) || !$args['object'] instanceof Order) { return; } - if (($args['object'] instanceof Order) && LengowOrder::isFromLengow($args['object']->id)) { + if (LengowOrder::isFromLengow($args['object']->id)) { $lengowOrder = new LengowOrder($args['object']->id); // Check if the tracking field has been updated @@ -447,22 +387,109 @@ public function hookActionObjectUpdateAfter($args) } } + /** + * Hook to add a Lengow tab link in the order detail tabs + * + * @param array $params arguments of hook + * + * @return string + */ + public function hookDisplayAdminOrderTabLink(array $params): string + { + $idOrder = (int) ($params['id_order'] ?? 0); + if (!$idOrder || !LengowOrder::isFromLengow($idOrder)) { + return ''; + } + + $lengowOrder = new LengowOrder($idOrder); + $marketplace = $lengowOrder->getMarketplace(); + if (!$marketplace) { + return ''; + } + + $hasContent = $marketplace->hasReturnTrackingNumber() + || $marketplace->hasReturnTrackingCarrier() + || !empty($marketplace->getRefundReasons()) + || !empty($marketplace->getRefundModes()); + + if (!$hasContent) { + return ''; + } + + return ''; + } + + /** + * Hook to add a Lengow tab content (return tracking, refund reason/mode) in the order detail tabs + * + * @param array $params arguments of hook + * + * @return string + */ + public function hookDisplayAdminOrderTabContent(array $params): string + { + $idOrder = (int) ($params['id_order'] ?? 0); + if (!$idOrder || !LengowOrder::isFromLengow($idOrder)) { + return ''; + } + + $lengowOrder = new LengowOrder($idOrder); + $marketplace = $lengowOrder->getMarketPlace(); + if (!$marketplace) { + return ''; + } + + $isActiveReturnTrackingNumber = $marketplace->hasReturnTrackingNumber(); + $isActiveReturnCarrier = $marketplace->hasReturnTrackingCarrier(); + $refundReasons = $marketplace->getRefundReasons(); + $refundModes = $marketplace->getRefundModes(); + $refundSelectedDatas = $lengowOrder->getRefundDataFromLengowOrder($idOrder, $marketplace->name); + + $locale = new LengowTranslation(); + + $this->context->smarty->assign([ + 'orderId' => $idOrder, + 'ajax_url' => $this->context->link->getAdminLink('AdminLengowOrder', true), + 'isActiveReturnTrackingNumber' => $isActiveReturnTrackingNumber, + 'isActiveReturnCarrier' => $isActiveReturnCarrier, + 'returnTrackingNumber' => $isActiveReturnTrackingNumber ? LengowOrderDetail::getOrderReturnTrackingNumber($idOrder) : '', + 'returnCarrier' => $isActiveReturnCarrier ? LengowOrderDetail::getOrderReturnCarrier($idOrder) : '', + 'returnTrackingNumberLabel' => $locale->t('order.screen.return_tracking_number_label'), + 'returnCarrierLabel' => $locale->t('order.screen.return_carrier_label'), + 'carriers' => $isActiveReturnCarrier ? LengowCarrier::getCarriersChoices($this->context->language->id) : [], + 'refundReasons' => $refundReasons, + 'refundModes' => $refundModes, + 'refundReasonSelected' => $refundSelectedDatas['refund_reason'] ?? '', + 'refundModeSelected' => $refundSelectedDatas['refund_mode'] ?? '', + ]); + + return $this->module->display(_PS_MODULE_LENGOW_DIR_, 'views/templates/hook/order/admin_order_tab.tpl'); + } + /** * Hook on product cancel + * + * @param array $args + * + * @return void */ - public function hookActionProductCancel(array $args) + public function hookActionProductCancel(array $args): void { if (!isset($args['order'])) { return; } $order = $args['order']; $lengowOrder = new LengowOrder($order->id); - if ($lengowOrder instanceof LengowOrder && LengowOrder::isFromLengow($order->id)) { + if (LengowOrder::isFromLengow($order->id)) { $idOrderDetail = (int) $args['id_order_detail']; $cancelQuantity = (int) $args['cancel_quantity']; $orderDetail = new OrderDetail($idOrderDetail); - if (!$orderDetail instanceof OrderDetail) { + if (!Validate::isLoadedObject($orderDetail)) { return; } $lengowOrderLine = LengowOrderLine::findOrderLineByOrderDetailId($orderDetail->id); diff --git a/classes/models/LengowImport.php b/classes/models/LengowImport.php index 1eca203f..68395490 100755 --- a/classes/models/LengowImport.php +++ b/classes/models/LengowImport.php @@ -112,17 +112,17 @@ class LengowImport /** * @var bool import is processing */ - public static $processing; + public static bool $processing = false; /** - * @var string order id being imported + * @var int|string order id being imported */ - public static $currentOrder = -1; + public static int|string $currentOrder = -1; /** - * @var array valid states lengow to create a Lengow order + * @var list valid states lengow to create a Lengow order */ - public static $lengowStates = [ + public static array $lengowStates = [ LengowOrder::STATE_WAITING_SHIPMENT, LengowOrder::STATE_SHIPPED, LengowOrder::STATE_CLOSED, @@ -132,168 +132,168 @@ class LengowImport /** * @var int PrestaShop lang id */ - private $idLang; + private int $idLang; /** * @var int|null PrestaShop shop id */ - private $idShop; + private ?int $idShop = null; /** * @var int PrestaShop shop group id */ - private $idShopGroup; + private int $idShopGroup; /** * @var bool use debug mode */ - private $debugMode; + private bool $debugMode; /** * @var bool display log messages */ - private $logOutput; + private bool $logOutput; /** * @var string|null marketplace order sku */ - private $marketplaceSku; + private ?string $marketplaceSku = null; /** * @var string|null marketplace name */ - private $marketplaceName; + private ?string $marketplaceName = null; /** * @var int|null delivery address id */ - private $deliveryAddressId; + private ?int $deliveryAddressId = null; /** * @var int maximum number of new orders created */ - private $limit; + private int $limit; /** * @var bool force import order even if there are errors */ - private $forceSync; + private bool $forceSync; /** * @var bool import inactive & out of stock products */ - private $forceProduct; + private bool $forceProduct; /** * @var int|false imports orders updated since (timestamp) */ - private $updatedFrom = false; + private int|false $updatedFrom = false; /** * @var int|false imports orders updated until (timestamp) */ - private $updatedTo = false; + private int|false $updatedTo = false; /** * @var int|false imports orders created since (timestamp) */ - private $createdFrom = false; + private int|false $createdFrom = false; /** * @var int|false imports orders created until (timestamp) */ - private $createdTo = false; + private int|false $createdTo = false; /** * @var string Lengow account id */ - private $accountId; + private string $accountId; /** * @var LengowConnector Lengow connector */ - private $connector; + private LengowConnector $connector; /** - * @var Context Context for import order + * @var Context|null Context for import order */ - private $context; + private ?Context $context = null; /** * @var string type import (manual or cron) */ - private $typeImport; + private string $typeImport; /** * @var bool import one order */ - private $importOneOrder = false; + private bool $importOneOrder = false; /** - * @var array shop catalog ids for import + * @var list shop catalog ids for import */ - private $shopCatalogIds = []; + private array $shopCatalogIds = []; /** - * @var array catalog ids already imported + * @var array catalog ids already imported */ - private $catalogIds = []; + private array $catalogIds = []; /** - * @var int id of lengow order record + * @var int|null id of lengow order record */ - private $idOrderLengow; + private ?int $idOrderLengow = null; /** - * @var array all orders created during the process + * @var array all orders created during the process */ - private $ordersCreated = []; + private array $ordersCreated = []; /** - * @var array all orders updated during the process + * @var array all orders updated during the process */ - private $ordersUpdated = []; + private array $ordersUpdated = []; /** - * @var array all orders failed during the process + * @var array all orders failed during the process */ - private $ordersFailed = []; + private array $ordersFailed = []; /** - * @var array all orders ignored during the process + * @var array all orders ignored during the process */ - private $ordersIgnored = []; + private array $ordersIgnored = []; /** - * @var array all incorrectly formatted orders that cannot be processed + * @var array all incorrectly formatted orders that cannot be processed */ - private $ordersNotFormatted = []; + private array $ordersNotFormatted = []; /** - * @var array all synchronization error (global or by shop) + * @var array all synchronization error (global or by shop) */ - private $errors = []; + private array $errors = []; /** * Construct the import manager * - * @param array $params optional options - * string marketplace_sku Lengow marketplace order id to synchronize - * string marketplace_name Lengow marketplace name to synchronize - * string type Type of current synchronization - * string created_from Synchronization of orders since - * string created_to Synchronization of orders until - * integer delivery_address_id Lengow delivery address id to synchronize - * integer id_order_lengow Lengow order id in PrestaShop - * integer shop_id Shop id for current synchronization - * float days Synchronization interval time - * integer limit Maximum number of new orders created - * boolean log_output Display log messages - * boolean debug_mode Activate debug mode - * boolean force_sync Force synchronization order even if there are errors - * boolean force_product Force import product when quantity is insufficient + * @param array $params optional options + * string marketplace_sku Lengow marketplace order id to synchronize + * string marketplace_name Lengow marketplace name to synchronize + * string type Type of current synchronization + * string created_from Synchronization of orders since + * string created_to Synchronization of orders until + * integer delivery_address_id Lengow delivery address id to synchronize + * integer id_order_lengow Lengow order id in PrestaShop + * integer shop_id Shop id for current synchronization + * float days Synchronization interval time + * integer limit Maximum number of new orders created + * boolean log_output Display log messages + * boolean debug_mode Activate debug mode + * boolean force_sync Force synchronization order even if there are errors + * boolean force_product Force import product when quantity is insufficient */ - public function __construct($params = []) + public function __construct(array $params = []) { // get generic params for synchronisation $this->debugMode = isset($params[self::PARAM_DEBUG_MODE]) @@ -359,9 +359,9 @@ public function __construct($params = []) /** * Execute import : fetch orders and import them * - * @return array + * @return array */ - public function exec() + public function exec(): array { // checks if a synchronization is not already in progress if (!$this->canExecuteSynchronization()) { @@ -370,7 +370,7 @@ public function exec() $syncOk = true; // get initial context type - $initialContextShop = Context::getContext()->shop; + $initialContextShop = LengowContext::getContext()->shop; $initialContextType = $initialContextShop::getContext(); // starts some processes necessary for synchronization $this->setupSynchronization(); @@ -406,7 +406,7 @@ public function exec() LengowMain::updateDateImport($this->typeImport); } // clean Context type with initial type if different - $currentContextShop = Context::getContext()->shop; + $currentContextShop = LengowContext::getContext()->shop; if ($initialContextType !== $currentContextShop::getContext()) { try { $currentContextShop::setContext($initialContextType); @@ -417,7 +417,7 @@ public function exec() $this->logOutput ); } - Context::getContext()->shop = $currentContextShop; + LengowContext::getContext()->shop = $currentContextShop; } // complete synchronization and start all necessary processes $this->releaseLock(self::LOCK_NAME); @@ -434,7 +434,7 @@ public function exec() * * @return bool */ - public static function checkState($orderStateMarketplace, $marketplace) + public static function checkState(string $orderStateMarketplace, LengowMarketplace $marketplace): bool { if (empty($orderStateMarketplace)) { return false; @@ -448,9 +448,9 @@ public static function checkState($orderStateMarketplace, $marketplace) * * @return bool */ - public static function isInProcess() + public static function isInProcess(): bool { - $timestamp = LengowConfiguration::getGlobalValue(LengowConfiguration::SYNCHRONIZATION_IN_PROGRESS); + $timestamp = (int) LengowConfiguration::getGlobalValue(LengowConfiguration::SYNCHRONIZATION_IN_PROGRESS); if ($timestamp <= 0) { return false; } @@ -469,9 +469,9 @@ public static function isInProcess() * * @return int */ - public static function restTimeToImport() + public static function restTimeToImport(): int { - $timestamp = LengowConfiguration::getGlobalValue(LengowConfiguration::SYNCHRONIZATION_IN_PROGRESS); + $timestamp = (int) LengowConfiguration::getGlobalValue(LengowConfiguration::SYNCHRONIZATION_IN_PROGRESS); return $timestamp > 0 ? $timestamp + (60 * self::MINUTE_INTERVAL_TIME) - time() : 0; } @@ -483,8 +483,10 @@ public static function restTimeToImport() * @param float|null $days Import period * @param string|null $createdFrom Import of orders since * @param string|null $createdTo Import of orders until + * + * @return void */ - private function setIntervalTime($minutes = null, $days = null, $createdFrom = null, $createdTo = null) + private function setIntervalTime(?float $minutes = null, ?float $days = null, ?string $createdFrom = null, ?string $createdTo = null): void { if ($createdFrom && $createdTo) { // retrieval of orders created from ... until ... @@ -505,8 +507,7 @@ private function setIntervalTime($minutes = null, $days = null, $createdFrom = n if ($minutes) { $intervalTime = floor($minutes * 60); // convert minutes to seconds $intervalTime = $intervalTime > self::MAX_INTERVAL_TIME ? self::MAX_INTERVAL_TIME : $intervalTime; - } - elseif ($days) { + } elseif ($days) { $intervalTime = floor($days * self::MIN_INTERVAL_TIME); // convert days to seconds $intervalTime = $intervalTime > self::MAX_INTERVAL_TIME ? self::MAX_INTERVAL_TIME : $intervalTime; } else { @@ -540,7 +541,7 @@ private function setIntervalTime($minutes = null, $days = null, $createdFrom = n * * @return bool */ - private function canExecuteSynchronization() + private function canExecuteSynchronization(): bool { if (!$this->acquireLock(self::LOCK_NAME)) { $message = LengowMain::setLogMessage( @@ -581,8 +582,10 @@ private function canExecuteSynchronization() /** * Starts some processes necessary for synchronization + * + * @return void */ - private function setupSynchronization() + private function setupSynchronization(): void { // suppress log files when too old LengowMain::cleanLog(); @@ -592,6 +595,9 @@ private function setupSynchronization() // checks Lengow catalogs and carriers for order synchronization if (!$this->importOneOrder && $this->typeImport === self::TYPE_MANUAL) { LengowSync::syncCatalog(); + } + // sync marketplace/carrier data on every import type so new marketplaces are registered in DB + if (!$this->importOneOrder) { LengowSync::syncCarrier(); } LengowMain::log( @@ -615,7 +621,7 @@ private function setupSynchronization() * * @return bool */ - private function checkCredentials() + private function checkCredentials(): bool { if (LengowConnector::isValidAuth($this->logOutput)) { list($this->accountId, $accessToken, $secretToken) = LengowConfiguration::getAccessIds(); @@ -630,9 +636,9 @@ private function checkCredentials() /** * Return the synchronization result * - * @return array + * @return array */ - private function getResult() + private function getResult(): array { $nbOrdersCreated = count($this->ordersCreated); $nbOrdersUpdated = count($this->ordersUpdated); @@ -668,7 +674,7 @@ private function getResult() * * @return bool */ - private function synchronizeOrdersByShop($shop) + private function synchronizeOrdersByShop(LengowShop $shop): bool { LengowMain::log( LengowLog::CODE_IMPORT, @@ -761,7 +767,7 @@ private function synchronizeOrdersByShop($shop) * * @return bool */ - private function checkCatalogIds($shop) + private function checkCatalogIds(LengowShop $shop): bool { if ($this->importOneOrder) { return true; @@ -813,15 +819,16 @@ private function checkCatalogIds($shop) * * @param int $idShop PrestaShop shop Id * + * @return void + * * @throws Exception */ - private function changeContext($idShop) + private function changeContext(int $idShop): void { - $this->context = Context::getContext()->cloneContext(); - if ($shop = new Shop($idShop)) { - $shop::setContext(Shop::CONTEXT_SHOP, $shop->id); - $this->context->shop = $shop; - } + $this->context = LengowContext::getContext()->cloneContext(); + $shop = new Shop($idShop); + $shop::setContext(Shop::CONTEXT_SHOP, $shop->id); + $this->context->shop = $shop; $this->idLang = $this->context->language->id; $this->idShopGroup = $this->context->shop->id_shop_group; } @@ -831,11 +838,11 @@ private function changeContext($idShop) * * @param LengowShop $shop * - * @return array + * @return array * * @throws LengowException no connection with the webservice / credentials not valid */ - private function getOrdersFromApi($shop) + private function getOrdersFromApi(LengowShop $shop): array { $page = 1; $orders = []; @@ -943,8 +950,10 @@ private function getOrdersFromApi($shop) * * @param mixed $orders API orders * @param int $idShop PrestaShop shop Id + * + * @return void */ - private function importOrders($orders, $idShop) + private function importOrders(mixed $orders, int $idShop): void { $importFinished = false; foreach ($orders as $orderData) { @@ -1049,8 +1058,10 @@ private function importOrders($orders, $idShop) * @param string $marketplaceSku id lengow of current order * @param string $errorMessage Error message * @param mixed $orderData API order data + * + * @return void */ - private function addOrderNotFormatted($marketplaceSku, $errorMessage, $orderData) + private function addOrderNotFormatted(string $marketplaceSku, string $errorMessage, mixed $orderData): void { $messageDecoded = LengowMain::decodeLogMessage($errorMessage, LengowTranslation::DEFAULT_ISO_CODE); $this->ordersNotFormatted[] = [ @@ -1070,9 +1081,11 @@ private function addOrderNotFormatted($marketplaceSku, $errorMessage, $orderData /** * Synchronize the merchant order id with Lengow * - * @param array $result synchronization order result + * @param array $result synchronization order result + * + * @return void */ - private function synchronizeMerchantOrderId($result) + private function synchronizeMerchantOrderId(array $result): void { if (!$this->debugMode && $result[LengowImportOrder::RESULT_TYPE] === LengowImportOrder::RESULT_CREATED) { $lengowOrder = new LengowOrder((int) $result[LengowImportOrder::MERCHANT_ORDER_ID]); @@ -1095,9 +1108,11 @@ private function synchronizeMerchantOrderId($result) /** * Save the result of the order synchronization by type * - * @param array $result synchronization order result + * @param array $result synchronization order result + * + * @return void */ - private function saveSynchronizationResult($result) + private function saveSynchronizationResult(array $result): void { $resultType = $result[LengowImportOrder::RESULT_TYPE]; unset($result[LengowImportOrder::RESULT_TYPE]); @@ -1119,8 +1134,10 @@ private function saveSynchronizationResult($result) /** * Complete synchronization and start all necessary processes + * + * @return void */ - private function finishSynchronization() + private function finishSynchronization(): void { // finish synchronization process self::setEnd(); @@ -1150,8 +1167,10 @@ private function finishSynchronization() /** * Set import to "in process" state + * + * @return void */ - private static function setInProcess() + private static function setInProcess(): void { self::$processing = true; LengowConfiguration::updateGlobalValue(LengowConfiguration::SYNCHRONIZATION_IN_PROGRESS, time()); @@ -1159,8 +1178,10 @@ private static function setInProcess() /** * Set import to finished + * + * @return void */ - private static function setEnd() + private static function setEnd(): void { self::$processing = false; LengowConfiguration::updateGlobalValue(LengowConfiguration::SYNCHRONIZATION_IN_PROGRESS, -1); @@ -1169,22 +1190,21 @@ private static function setEnd() /** * Acquire a named lock * - * @param string $lockName Name of the lock - * @param int $timeout Timeout in seconds + * @param string $lockName Name of the lock + * @param int $timeout Timeout in seconds * * @return bool True if the lock was acquired, false otherwise */ private function acquireLock(string $lockName, int $timeout = 0): bool { try { - $db = \Db::getInstance(); + $db = Db::getInstance(); $result = $db->getValue( 'SELECT GET_LOCK("' . pSQL($lockName) . '", ' . (int) $timeout . ')' ); return (bool) $result; - - } catch (\Exception $e) { + } catch (Exception $e) { LengowMain::log( LengowLog::CODE_IMPORT, LengowMain::setLogMessage( @@ -1201,21 +1221,20 @@ private function acquireLock(string $lockName, int $timeout = 0): bool /** * Release a named lock * - * @param string $lockName Name of the lock + * @param string $lockName Name of the lock * * @return bool True if the lock was released, false otherwise */ private function releaseLock(string $lockName): bool { try { - $db = \Db::getInstance(); + $db = Db::getInstance(); $result = $db->getValue( 'SELECT RELEASE_LOCK("' . pSQL($lockName) . '")' ); return (bool) $result; - - } catch (\Exception $e) { + } catch (Exception $e) { LengowMain::log( LengowLog::CODE_IMPORT, LengowMain::setLogMessage( diff --git a/classes/models/LengowImportOrder.php b/classes/models/LengowImportOrder.php index 9e10eb72..edd71cef 100755 --- a/classes/models/LengowImportOrder.php +++ b/classes/models/LengowImportOrder.php @@ -64,187 +64,187 @@ class LengowImportOrder /** * @var int|null PrestaShop shop id */ - private $idShop; + private ?int $idShop = null; /** * @var int PrestaShop shop group id */ - private $idShopGroup; + private int $idShopGroup; /** * @var int PrestaShop lang id */ - private $idLang; + private int $idLang; /** * @var Context PrestaShop Context for import order */ - private $context; + private Context $context; /** * @var bool force import order even if there are errors */ - private $forceSync; + private bool $forceSync; /** * @var bool import inactive & out of stock products */ - private $forceProduct; + private bool $forceProduct; /** * @var bool use debug mode */ - private $debugMode; + private bool $debugMode; /** * @var bool display log messages */ - private $logOutput; + private bool $logOutput; /** * @var string id lengow of current order */ - private $marketplaceSku; + private string $marketplaceSku; /** * @var string marketplace label */ - private $marketplaceLabel; + private string $marketplaceLabel = ''; /** * @var int id of delivery address for current order */ - private $deliveryAddressId; + private int $deliveryAddressId; /** * @var mixed API order data */ - private $orderData; + private mixed $orderData; /** * @var mixed API package data */ - private $packageData; + private mixed $packageData; /** * @var bool is first package */ - private $firstPackage; + private bool $firstPackage; /** * @var bool import one order var from lengow import */ - private $importOneOrder; + private bool $importOneOrder; /** * @var bool re-import order */ - private $isReimported; + private bool $isReimported = false; /** * @var int id of the record Lengow order table */ - private $idOrderLengow; + private int $idOrderLengow = 0; /** * @var int id of the record PrestaShop order table */ - private $idOrder; + private ?int $idOrder = null; /** - * @var int PrestaShop order reference + * @var string PrestaShop order reference */ - private $orderReference; + private ?string $orderReference = null; /** * @var string order types data */ - private $orderTypes; + private string $orderTypes = ''; /** - * @var LengowMarketplace Lengow marketplace instance + * @var LengowMarketplace|null Lengow marketplace instance */ - private $marketplace; + private ?LengowMarketplace $marketplace = null; /** * @var string marketplace order state */ - private $orderStateMarketplace; + private string $orderStateMarketplace = ''; /** * @var string Lengow order state */ - private $orderStateLengow; + private string $orderStateLengow = ''; /** * @var string Previous Lengow order state */ - private $previousOrderStateLengow; + private string $previousOrderStateLengow = ''; /** * @var float order processing fee */ - private $processingFee; + private float $processingFee = 0.0; /** * @var float order shipping cost */ - private $shippingCost; + private float $shippingCost = 0.0; /** * @var float order total amount */ - private $orderAmount; + private float $orderAmount = 0.0; /** * @var int number of order items */ - private $orderItems; + private int $orderItems = 0; /** * @var string|null carrier name */ - private $carrierName; + private ?string $carrierName = null; /** * @var string|null carrier method */ - private $carrierMethod; + private ?string $carrierMethod = null; /** * @var string|null carrier tracking number */ - private $trackingNumber; + private ?string $trackingNumber = null; /** * @var string|null carrier relay id */ - private $relayId; + private ?string $relayId = null; /** * @var bool if order shipped by marketplace */ - private $shippedByMp = false; + private bool $shippedByMp = false; /** * @var LengowAddress Lengow Address instance */ - private $shippingAddress; + private LengowAddress $shippingAddress; /** * @var string Marketplace order comment */ - private $orderComment; + private string $orderComment = ''; /** - * @var array order errors + * @var array order errors */ - private $errors = []; + private array $errors = []; /** * Construct the import manager * - * @param array $params optional options + * @param array $params optional options * * integer shop_id Id shop for current order * integer shop_group_id Id shop group for current order @@ -260,7 +260,7 @@ class LengowImportOrder * mixed package_data package data * boolean first_package it is the first package */ - public function __construct($params = []) + public function __construct(array $params = []) { $this->idShop = $params[self::PARAM_SHOP_ID]; $this->idShopGroup = $params[self::PARAM_SHOP_GROUP_ID]; @@ -281,9 +281,9 @@ public function __construct($params = []) /** * Create or update order * - * @return array + * @return array */ - public function importOrder() + public function importOrder(): array { // load marketplace singleton and marketplace data if (!$this->loadMarketplaceData()) { @@ -352,7 +352,7 @@ public function importOrder() * * @return bool */ - private function loadMarketplaceData() + private function loadMarketplaceData(): bool { try { // get marketplace and Lengow order state @@ -379,9 +379,9 @@ private function loadMarketplaceData() * * @param string $resultType Type of result (created, updated, failed or ignored) * - * @return array + * @return array */ - private function returnResult($resultType) + private function returnResult(string $resultType): array { return [ self::MERCHANT_ORDER_ID => $this->idOrder, @@ -403,7 +403,7 @@ private function returnResult($resultType) * * @return bool */ - private function orderErrorAlreadyExist() + private function orderErrorAlreadyExist(): bool { // if log import exist and not finished $importLog = LengowOrderError::getLastImportLogNotFinished( @@ -443,7 +443,7 @@ private function orderErrorAlreadyExist() * * @return bool */ - private function checkAndUpdateOrder($idOrder) + private function checkAndUpdateOrder(int $idOrder): bool { $orderUpdated = false; LengowMain::log( @@ -527,7 +527,7 @@ private function checkAndUpdateOrder($idOrder) * * @return bool */ - private function canCreateOrder() + private function canCreateOrder(): bool { if ($this->importOneOrder) { return true; @@ -569,7 +569,7 @@ private function canCreateOrder() * * @return bool */ - private function externalIdAlreadyExist() + private function externalIdAlreadyExist(): bool { if (empty($this->orderData->merchant_order_id) || $this->debugMode || $this->isReimported) { return false; @@ -592,7 +592,7 @@ private function externalIdAlreadyExist() * * @return bool */ - private function orderStatusIsValid() + private function orderStatusIsValid(): bool { if (LengowImport::checkState($this->orderStateMarketplace, $this->marketplace)) { return true; @@ -627,7 +627,7 @@ private function orderStatusIsValid() * * @return bool */ - private function createLengowOrder() + private function createLengowOrder(): bool { // load order comment from marketplace $this->loadOrderComment(); @@ -693,8 +693,10 @@ private function createLengowOrder() /** * Load order comment from marketplace + * + * @return void */ - private function loadOrderComment() + private function loadOrderComment(): void { if (isset($this->orderData->comments) && is_array($this->orderData->comments)) { $orderComment = implode(',', $this->orderData->comments); @@ -706,8 +708,10 @@ private function loadOrderComment() /** * Load order types data and update Lengow order record + * + * @return void */ - private function loadOrderTypesData() + private function loadOrderTypesData(): void { $orderTypes = []; if ($this->orderData->order_types !== null && !empty($this->orderData->order_types)) { @@ -726,7 +730,7 @@ private function loadOrderTypesData() * * @return string */ - private function getOrderDate() + private function getOrderDate(): string { $orderDate = $this->orderData->marketplace_order_date !== null ? (string) $this->orderData->marketplace_order_date @@ -740,7 +744,7 @@ private function getOrderDate() * * @return string|null */ - private function getVatNumberFromOrderData() + private function getVatNumberFromOrderData(): ?string { if (isset($this->orderData->billing_address->vat_number)) { return $this->orderData->billing_address->vat_number; @@ -757,7 +761,7 @@ private function getVatNumberFromOrderData() * * @return bool */ - private function checkAndUpdateLengowOrderData() + private function checkAndUpdateLengowOrderData(): bool { // Checks if all necessary order data are present if (!$this->checkOrderData()) { @@ -798,7 +802,7 @@ private function checkAndUpdateLengowOrderData() * * @return bool */ - private function checkOrderData() + private function checkOrderData(): bool { $errorMessages = []; if (empty($this->packageData->cart)) { @@ -849,8 +853,10 @@ private function checkOrderData() /** * Load order amount, processing fees and shipping costs + * + * @return void */ - private function loadOrderAmount() + private function loadOrderAmount(): void { $this->processingFee = (float) $this->orderData->processing_fee; $this->shippingCost = (float) $this->orderData->shipping; @@ -895,8 +901,10 @@ private function loadOrderAmount() /** * Load tracking data + * + * @return void */ - private function loadTrackingData() + private function loadTrackingData(): void { $tracks = $this->packageData->delivery->trackings; if (!empty($tracks)) { @@ -913,7 +921,7 @@ private function loadTrackingData() * * @return string */ - private function getCustomerName() + private function getCustomerName(): string { $firstName = (string) $this->orderData->billing_address->first_name; $lastName = (string) $this->orderData->billing_address->last_name; @@ -937,7 +945,7 @@ private function getCustomerName() * * @return string */ - private function getCustomerEmail() + private function getCustomerEmail(): string { return $this->orderData->billing_address->email !== null ? (string) $this->orderData->billing_address->email @@ -949,7 +957,7 @@ private function getCustomerEmail() * * @return bool */ - private function canCreateOrderShippedByMarketplace() + private function canCreateOrderShippedByMarketplace(): bool { // check if the order is shipped by marketplace if ($this->shippedByMp) { @@ -977,7 +985,7 @@ private function canCreateOrderShippedByMarketplace() * * @return bool */ - private function createOrder() + private function createOrder(): bool { try { // search and get all products @@ -1063,11 +1071,11 @@ private function createOrder() /** * Get products from API data * - * @return array + * @return array * * @throws Exception|LengowException product is a parent / product no be found */ - private function getProducts() + private function getProducts(): array { $products = []; foreach ($this->packageData->cart as $product) { @@ -1173,11 +1181,13 @@ private function getProducts() /** * Create a PrestaShop cart * + * @param mixed $products + * * @return LengowCart * * @throws Exception|LengowException */ - private function createCart($products) + private function createCart(mixed $products): LengowCart { // create PrestaShop Customer, addresses and load cart data $cartData = $this->getCartData(); @@ -1185,7 +1195,7 @@ private function createCart($products) $cart = new LengowCart(); $cart->assign($cartData); $cart->validateLengow(); - $cart->force_product = $this->forceProduct; + $cart->forceProduct = $this->forceProduct; // add products to cart $cart->addProducts($products); // removes non-Lengow products from cart @@ -1199,11 +1209,11 @@ private function createCart($products) /** * Create PrestaShop Customer, addresses and load cart data * - * @return array + * @return array * * @throws LengowException */ - private function getCartData() + private function getCartData(): array { $cartData = []; $cartData['id_lang'] = $this->idLang; @@ -1222,7 +1232,7 @@ private function getCartData() if (LengowConfiguration::getTypedGlobalValue(LengowConfiguration::ANONYMIZE_EMAIL)) { $domain = !LengowMain::getHost() ? 'prestashop.shop' : LengowMain::getHost(); if (LengowConfiguration::getTypedGlobalValue(LengowConfiguration::TYPE_ANONYMIZE_EMAIL) === 0) { - $billingData['email'] = md5($this->marketplaceSku . '-' . $this->marketplace->name) . '@' . strtolower($domain); + $billingData['email'] = substr(hash('sha256', $this->marketplaceSku . '-' . $this->marketplace->name), 0, 32) . '@' . strtolower($domain); } elseif (LengowConfiguration::getTypedGlobalValue(LengowConfiguration::TYPE_ANONYMIZE_EMAIL) === 1) { $billingData['email'] = $this->marketplaceSku . '-' . $this->marketplace->name . '@' . $domain; } @@ -1287,11 +1297,11 @@ private function getCartData() /** * Create or load customer based on API data * - * @param array $customerData API data + * @param array $customerData API data * * @return LengowCustomer */ - private function getCustomer($customerData = []) + private function getCustomer(array $customerData = []): LengowCustomer { $customer = new LengowCustomer(); // check if customer already exists in PrestaShop @@ -1309,12 +1319,12 @@ private function getCustomer($customerData = []) * Create or load address based on API data * * @param int $idCustomer PrestaShop customer id - * @param array $addressData address data + * @param array $addressData address data * @param bool $shippingData is shipping address * * @return LengowAddress */ - private function getAddress($idCustomer, $addressData = [], $shippingData = false) + private function getAddress(int $idCustomer, array $addressData = [], bool $shippingData = false): LengowAddress { // if tracking_information exist => get id_relay if ($shippingData && $this->relayId !== null) { @@ -1379,19 +1389,21 @@ private function getAddress($idCustomer, $addressData = [], $shippingData = fals * * @throws LengowException shipping country no country / no default carrier for country */ - private function getCarrierId() + private function getCarrierId(): int { $idCarrier = false; $matchingFound = false; - if (!isset($this->shippingAddress->id_country)) { - throw new LengowException(LengowMain::setLogMessage('lengow_log.exception.carrier_shipping_address_no_country')); - } $idCountry = (int) $this->shippingAddress->id_country; if ($idCountry === 0) { throw new LengowException(LengowMain::setLogMessage('lengow_log.exception.carrier_shipping_address_no_country')); } // get marketplace id by marketplace name $idMarketplace = LengowMarketplace::getIdMarketplace($this->marketplace->name); + if ($idMarketplace === false) { + // marketplace not yet in DB — force a carrier sync to populate it + LengowSync::syncCarrier(true); + $idMarketplace = LengowMarketplace::getIdMarketplace($this->marketplace->name); + } $hasCarriers = $this->marketplace->hasCarriers(); $hasShippingMethods = $this->marketplace->hasShippingMethods(); // if the marketplace has neither carrier nor shipping methods, use semantic matching @@ -1507,13 +1519,13 @@ private function getCarrierId() * Create and validate PrestaShop order * * @param LengowCart $cart Lengow cart instance - * @param array $products List of Lengow products + * @param array $products List of Lengow products * - * @return array + * @return array * * @throws LengowException */ - private function createAndValidatePayment($cart, $products) + private function createAndValidatePayment(LengowCart $cart, array $products): array { $idOrderState = LengowMain::getPrestashopStateId( $this->orderStateMarketplace, @@ -1552,9 +1564,11 @@ private function createAndValidatePayment($cart, $products) /** * Ensure carrier compatibility with SoColissimo & Mondial Relay * - * @param LengowOrder $order order imported + * @param Order $order PrestaShop order instance + * + * @return void */ - private function checkCarrierCompatibility($order) + private function checkCarrierCompatibility(Order $order): void { try { $carrierCompatibility = LengowCarrier::carrierCompatibility( @@ -1587,14 +1601,16 @@ private function checkCarrierCompatibility($order) * @param int $idOrder PrestaShop order id * @param string $comment order comment * + * @return void + * * @throws Exception */ - private function addCommentOrder($idOrder, $comment) + private function addCommentOrder(int $idOrder, string $comment): void { if (!empty($comment)) { $msg = new Message(); $msg->id_order = $idOrder; - $msg->private = 1; + $msg->private = true; $msg->message = $comment; $msg->add(); } @@ -1603,10 +1619,12 @@ private function addCommentOrder($idOrder, $comment) /** * Save order line in lengow orders line table * - * @param LengowOrder $order Lengow order instance - * @param array $products order products + * @param Order $order PrestaShop order instance + * @param array $products order products + * + * @return void */ - private function saveLengowOrderLine($order, $products) + private function saveLengowOrderLine(Order $order, array $products): void { $orderLineSaved = false; foreach ($products as $idProduct => $values) { @@ -1652,11 +1670,13 @@ private function saveLengowOrderLine($order, $products) /** * Add quantity back to stock * - * @param array $products list of products + * @param array $products list of products + * + * @return void * * @throws Exception */ - private function addQuantityBack($products) + private function addQuantityBack(array $products): void { // add quantity back for re-import order and order shipped by marketplace if ($this->isReimported @@ -1670,7 +1690,7 @@ private function addQuantityBack($products) LengowMain::log(LengowLog::CODE_IMPORT, $logMessage, $this->logOutput, $this->marketplaceSku); foreach ($products as $sku => $productData) { $idsProduct = explode('_', $sku); - $idProductAttribute = isset($idsProduct[1]) ? $idsProduct[1] : null; + $idProductAttribute = isset($idsProduct[1]) ? (int) $idsProduct[1] : null; StockAvailable::updateQuantity( (int) $idsProduct[0], $idProductAttribute, @@ -1685,8 +1705,10 @@ private function addQuantityBack($products) * Launch validateOrder hook for carrier plugins * * @param Order $order PrestaShop order instance + * + * @return void */ - private function launchValidateOrderHook($order) + private function launchValidateOrderHook(Order $order): void { LengowMain::log( LengowLog::CODE_IMPORT, diff --git a/classes/models/LengowInstall.php b/classes/models/LengowInstall.php index 8c9752fa..0ba09aee 100755 --- a/classes/models/LengowInstall.php +++ b/classes/models/LengowInstall.php @@ -27,9 +27,9 @@ class LengowInstall { /** - * @var array all module tables + * @var list all module tables */ - public static $tables = [ + public static array $tables = [ LengowOrder::TABLE_ORDER, LengowOrderLine::TABLE_ORDER_LINE, LengowOrderError::TABLE_ORDER_ERROR, @@ -48,42 +48,47 @@ class LengowInstall /** * @var string old version for update scripts */ - public static $oldVersion; + public static string $oldVersion = ''; /** * @var bool installation status */ - protected static $installationStatus; + protected static bool $installationStatus = false; /** * @var Lengow Lengow module instance */ - private $lengowModule; + private Lengow $lengowModule; + + /** + * @var Context PrestaShop context + */ + private Context $context; /** * @var LengowHook Lengow hook instance */ - private $lengowHook; + private LengowHook $lengowHook; /** - * @var array all module tabs + * @var array all module tabs */ - private $tabs = [ - 'tab.home' => ['name' => 'AdminLengowHome', 'active' => true], - 'tab.dashboard' => ['name' => 'AdminLengowDashboard', 'active' => false], - 'tab.product' => ['name' => 'AdminLengowFeed', 'active' => false], - 'tab.order' => ['name' => 'AdminLengowOrder', 'active' => false], - 'tab.order_setting' => ['name' => 'AdminLengowOrderSetting', 'active' => false], - 'tab.help' => ['name' => 'AdminLengowHelp', 'active' => false], - 'tab.main_setting' => ['name' => 'AdminLengowMainSetting', 'active' => false], - 'tab.legals' => ['name' => 'AdminLengowLegals', 'active' => false], - 'tab.toolbox' => ['name' => 'AdminLengowToolbox', 'active' => false], + private array $tabs = [ + 'tab.home' => ['name' => 'AdminLengowHome', 'active' => true, 'route_name' => 'lengow_home'], + 'tab.dashboard' => ['name' => 'AdminLengowDashboard', 'active' => false, 'route_name' => 'lengow_dashboard'], + 'tab.product' => ['name' => 'AdminLengowFeed', 'active' => false, 'route_name' => 'lengow_feed'], + 'tab.order' => ['name' => 'AdminLengowOrder', 'active' => false, 'route_name' => 'lengow_order'], + 'tab.order_setting' => ['name' => 'AdminLengowOrderSetting', 'active' => false, 'route_name' => 'lengow_order_setting'], + 'tab.help' => ['name' => 'AdminLengowHelp', 'active' => false, 'route_name' => 'lengow_help'], + 'tab.main_setting' => ['name' => 'AdminLengowMainSetting', 'active' => false, 'route_name' => 'lengow_main_setting'], + 'tab.legals' => ['name' => 'AdminLengowLegals', 'active' => false, 'route_name' => 'lengow_legals'], + 'tab.toolbox' => ['name' => 'AdminLengowToolbox', 'active' => false, 'route_name' => 'lengow_toolbox'], ]; /** - * @var array all old files to remove + * @var list all old files to remove */ - private $oldFiles = [ + private array $oldFiles = [ 'AdminLengow14.php', 'AdminLengowLog14.php', 'classes/models/LengowCurrency.php', @@ -114,9 +119,9 @@ class LengowInstall ]; /** - * @var array old configuration keys to remove + * @var list old configuration keys to remove */ - private $oldConfigurationKeys = [ + private array $oldConfigurationKeys = [ 'LENGOW_ID_ACCOUNT', 'LENGOW_SECRET', 'LENGOW_CRON', @@ -163,11 +168,13 @@ class LengowInstall * Construct * * @param Lengow $module Lengow module instance + * @param Context $context PrestaShop context */ - public function __construct($module) + public function __construct(Lengow $module, Context $context) { $this->lengowModule = $module; - $this->lengowHook = new LengowHook($module); + $this->context = $context; + $this->lengowHook = new LengowHook($module, $context); } /** @@ -175,7 +182,7 @@ public function __construct($module) * * @return bool */ - public function reset() + public function reset(): bool { return LengowConfiguration::resetAll(true); } @@ -185,9 +192,9 @@ public function reset() * * @return bool */ - public function install() + public function install(): bool { - if (version_compare(_PS_VERSION_, '1.7.8.0', '<')) { + if (version_compare(_PS_VERSION_, '8.0.0', '<')) { return false; } LengowMain::log( @@ -196,6 +203,7 @@ public function install() ); $oldVersion = LengowConfiguration::getGlobalValue(LengowConfiguration::PLUGIN_VERSION); $oldVersion = $oldVersion ?: false; + self::setInstallationStatus(false); $this->setDefaultValues(); $this->update($oldVersion); LengowMain::log( @@ -212,7 +220,7 @@ public function install() * * @return bool */ - public function uninstall() + public function uninstall(): bool { LengowMain::log( LengowLog::CODE_UNINSTALL, @@ -224,15 +232,16 @@ public function uninstall() LengowMain::setLogMessage('log.uninstall.uninstall_end', ['version' => $this->lengowModule->version]) ); - return true; } /** * Clear PrestaShop caches * general cache, asset cache, smarty cache, symfony cache + * + * @return void */ - public function clearCaches() + public function clearCaches(): void { try { Tools::clearCache(); // Clears PrestaShop general cache @@ -243,7 +252,6 @@ public function clearCaches() LengowLog::CODE_INSTALL, LengowMain::setLogMessage('log.install.clear_cache_success') ); - } catch (Exception $e) { LengowMain::log( LengowLog::CODE_INSTALL, @@ -262,7 +270,7 @@ public function clearCaches() * * @return bool */ - public function update($oldVersion = false) + public function update($oldVersion = false): bool { if (self::isInstallationInProgress()) { return true; @@ -331,7 +339,7 @@ public function update($oldVersion = false) * * @return bool */ - public static function checkTableExists($table) + public static function checkTableExists(string $table): bool { $sql = 'SHOW TABLES LIKE \'' . _DB_PREFIX_ . $table . '\''; try { @@ -351,7 +359,7 @@ public static function checkTableExists($table) * * @return bool */ - public static function checkIndexExists($table, $index) + public static function checkIndexExists(string $table, string $index): bool { $sql = 'SHOW INDEXES FROM ' . _DB_PREFIX_ . $table . ' WHERE `Column_name` = \'' . $index . '\''; try { @@ -371,7 +379,7 @@ public static function checkIndexExists($table, $index) * * @return bool */ - public static function checkFieldExists($table, $field) + public static function checkFieldExists(string $table, string $field): bool { $sql = 'SHOW COLUMNS FROM ' . _DB_PREFIX_ . $table . ' LIKE \'' . $field . '\''; try { @@ -388,8 +396,10 @@ public static function checkFieldExists($table, $field) * * @param string $table Lengow table * @param string $field Lengow field + * + * @return void */ - public static function checkFieldAndDrop($table, $field) + public static function checkFieldAndDrop(string $table, string $field): void { if (self::checkFieldExists($table, $field)) { Db::getInstance()->execute('ALTER TABLE ' . _DB_PREFIX_ . $table . ' DROP COLUMN `' . $field . '`'); @@ -401,7 +411,7 @@ public static function checkFieldAndDrop($table, $field) * * @return bool */ - public static function dropTable() + public static function dropTable(): bool { foreach (self::$tables as $table) { LengowMain::log( @@ -411,25 +421,17 @@ public static function dropTable() Db::getInstance()->execute('DROP TABLE IF EXISTS ' . _DB_PREFIX_ . $table); } $name = 'order_carrier'; - $column = LengowAction::ARG_RETURN_TRACKING_NUMBER; - if (self::checkTableExists($name) && self::checkFieldExists($name, $column)) { - $sql = 'ALTER TABLE ' . _DB_PREFIX_ . 'order_carrier ' - . 'DROP COLUMN `' . Db::getInstance()->_escape($column) . '`;'; - Db::getInstance()->execute($sql); - LengowMain::log( - LengowLog::CODE_UNINSTALL, - LengowMain::setLogMessage('log.uninstall.column_deleted', ['name' => $column]) - ); - } - $column = LengowAction::ARG_RETURN_CARRIER; - if (self::checkTableExists($name) && self::checkFieldExists($name, $column)) { - $sql = 'ALTER TABLE ' . _DB_PREFIX_ . 'order_carrier ' - . 'DROP COLUMN `' . Db::getInstance()->_escape($column) . '`;'; - Db::getInstance()->execute($sql); - LengowMain::log( - LengowLog::CODE_UNINSTALL, - LengowMain::setLogMessage('log.uninstall.column_deleted', ['name' => $column]) - ); + $allowedColumns = [LengowAction::ARG_RETURN_TRACKING_NUMBER, LengowAction::ARG_RETURN_CARRIER]; + foreach ($allowedColumns as $column) { + if (self::checkTableExists($name) && self::checkFieldExists($name, $column)) { + $sql = 'ALTER TABLE ' . _DB_PREFIX_ . 'order_carrier ' + . 'DROP COLUMN `' . bqSQL($column) . '`;'; + Db::getInstance()->execute($sql); + LengowMain::log( + LengowLog::CODE_UNINSTALL, + LengowMain::setLogMessage('log.uninstall.column_deleted', ['name' => $column]) + ); + } } return true; @@ -439,8 +441,10 @@ public static function dropTable() * Set Installation Status * * @param bool $status installation status + * + * @return void */ - public static function setInstallationStatus($status) + public static function setInstallationStatus(bool $status): void { LengowConfiguration::updateGlobalValue(LengowConfiguration::INSTALLATION_IN_PROGRESS, (int) $status); self::$installationStatus = $status; @@ -451,7 +455,7 @@ public static function setInstallationStatus($status) * * @return bool */ - public static function isInstallationInProgress() + public static function isInstallationInProgress(): bool { $sql = 'SELECT `value` FROM ' . _DB_PREFIX_ . 'configuration WHERE `name` = \'LENGOW_INSTALLATION_IN_PROGRESS\''; @@ -464,10 +468,15 @@ public static function isInstallationInProgress() * Delete old files * * @param string $file name of file to delete + * + * @return void */ - public static function removeFile($file) + public static function removeFile(string $file): void { $filePath = _PS_MODULE_LENGOW_DIR_ . $file; + if (!LengowMain::isPathAllowed($filePath, _PS_MODULE_LENGOW_DIR_)) { + return; + } if (file_exists($filePath)) { if (is_dir($filePath)) { self::deleteDir($filePath); @@ -484,7 +493,7 @@ public static function removeFile($file) * * @return bool */ - public static function deleteDir($dirPath) + public static function deleteDir(string $dirPath): bool { $length = Tools::strlen(_PS_MODULE_LENGOW_DIR_); if (Tools::substr($dirPath, 0, $length) !== _PS_MODULE_LENGOW_DIR_) { @@ -512,15 +521,17 @@ public static function deleteDir($dirPath) * @param string $oldKey old configuration key * @param string $newKey new configuration key * @param bool $shopConfiguration configuration by shop or global + * + * @return void */ - public static function renameConfigurationKey($oldKey, $newKey, $shopConfiguration = false) + public static function renameConfigurationKey(string $oldKey, string $newKey, bool $shopConfiguration = false): void { if (LengowConfiguration::checkKeyExists($oldKey)) { $globalValue = LengowConfiguration::getGlobalValue($oldKey); if ($shopConfiguration) { $shops = LengowShop::findAll(true); foreach ($shops as $shop) { - $shopValue = LengowConfiguration::get($oldKey, false, null, $shop['id_shop']); + $shopValue = LengowConfiguration::get($oldKey, null, null, $shop['id_shop']); $shopValue = $shopValue === null ? $globalValue : $shopValue; LengowConfiguration::updateValue($newKey, $shopValue, false, null, $shop['id_shop']); } @@ -536,7 +547,7 @@ public static function renameConfigurationKey($oldKey, $newKey, $shopConfigurati * * @return bool */ - private function createLengowTables() + private function createLengowTables(): bool { // create table lengow_product $name = LengowProduct::TABLE_PRODUCT; @@ -916,7 +927,7 @@ private function createLengowTables() * * @return bool */ - private function createTab() + private function createTab(): bool { try { $tabParent = new Tab(); @@ -931,6 +942,9 @@ private function createTab() $tab->id_parent = $tabParent->id; $tab->active = $values['active']; $tab->module = $this->lengowModule->name; + if (version_compare(_PS_VERSION_, '9.0.0', '>=') && isset($values['route_name'])) { + $tab->route_name = $values['route_name']; + } $languages = Language::getLanguages(false); foreach ($languages as $language) { $tab->name[$language['id_lang']] = LengowMain::decodeLogMessage($name, $language['iso_code']); @@ -953,7 +967,7 @@ private function createTab() * * @return bool */ - private function uninstallTab() + private function uninstallTab(): bool { try { $sql = 'SELECT `id_tab`, `class_name` FROM `' . _DB_PREFIX_ . 'tab` WHERE `module` = \'lengow\''; @@ -988,7 +1002,7 @@ private function uninstallTab() * * @return bool */ - private function setDefaultValues() + private function setDefaultValues(): bool { return LengowConfiguration::resetAll(); } @@ -998,7 +1012,7 @@ private function setDefaultValues() * * @return bool */ - private function addStatusError() + private function addStatusError(): bool { // add Lengow order error status try { @@ -1064,8 +1078,10 @@ private function addStatusError() /** * Delete old files + * + * @return void */ - private function removeOldFiles() + private function removeOldFiles(): void { foreach ($this->oldFiles as $file) { self::removeFile($file); @@ -1074,8 +1090,10 @@ private function removeOldFiles() /** * Delete old configuration keys + * + * @return void */ - private function removeOldConfigurationKeys() + private function removeOldConfigurationKeys(): void { foreach ($this->oldConfigurationKeys as $configuration) { Configuration::deleteByName($configuration); @@ -1084,8 +1102,10 @@ private function removeOldConfigurationKeys() /** * Delete all lengow config files + * + * @return void */ - private function removeConfigFiles() + private function removeConfigFiles(): void { $files = scandir(_PS_MODULE_LENGOW_DIR_); foreach ($files as $file) { @@ -1097,8 +1117,10 @@ private function removeConfigFiles() /** * Save Override directory + * + * @return void */ - private function saveOverride() + private function saveOverride(): void { $directoryBackup = _PS_MODULE_LENGOW_DIR_ . 'backup/'; $directory = _PS_MODULE_LENGOW_DIR_ . 'override/'; @@ -1116,12 +1138,14 @@ private function saveOverride() } /** - * Create Lengow customer group if not exists - */ - private function createLengowCustomerGroup() + * Create Lengow customer group if not exists + * + * @return void + */ + private function createLengowCustomerGroup(): void { $marketplaceGroupId = null; - $groups = Group::getGroups(Context::getContext()->language->id); + $groups = Group::getGroups($this->context->language->id); foreach ($groups as $group) { if ($group['name'] === LengowCustomer::LENGOW_GROUP_NAME) { $marketplaceGroupId = $group['id_group']; @@ -1131,12 +1155,15 @@ private function createLengowCustomerGroup() if (is_null($marketplaceGroupId)) { $group = new Group(); $languages = Language::getLanguages(false); + if (empty($languages)) { + $languages = [['id_lang' => (int) Configuration::get('PS_LANG_DEFAULT')]]; + } foreach ($languages as $language) { $group->name[$language['id_lang']] = LengowCustomer::LENGOW_GROUP_NAME; } - $group->reduction = 0; + $group->reduction = '0'; $group->price_display_method = PS_TAX_EXC; - $group->show_prices = 1; + $group->show_prices = true; $group->date_add = date('Y-m-d H:i:s'); $group->date_upd = date('Y-m-d H:i:s'); $group->save(); diff --git a/classes/models/LengowLink.php b/classes/models/LengowLink.php index e84fb607..41170186 100755 --- a/classes/models/LengowLink.php +++ b/classes/models/LengowLink.php @@ -33,18 +33,10 @@ class LengowLink extends LinkCore * * @return string */ - public function getAbsoluteAdminLink($controller) + public function getAbsoluteAdminLink(string $controller): string { - $adminPath = Tools::getShopDomainSsl(true, true) . - __PS_BASE_URI__ . Tools::substr(_PS_ADMIN_DIR_, strrpos(_PS_ADMIN_DIR_, '/') + 1); try { - if (_PS_VERSION_ < '1.6') { - $adminPath .= '/index.php?tab=' . $controller . '&token=' . Tools::getAdminTokenLite($controller); - } elseif (_PS_VERSION_ < '1.7') { - $adminPath .= '/' . $this->getAdminLink($controller); - } else { - $adminPath = $this->getAdminLink($controller); - } + $adminPath = $this->getAdminLink($controller); } catch (Exception $e) { return ''; } diff --git a/classes/models/LengowList.php b/classes/models/LengowList.php index a7e617ae..dd064e61 100755 --- a/classes/models/LengowList.php +++ b/classes/models/LengowList.php @@ -27,129 +27,131 @@ class LengowList { /** - * @var array list of fields + * @var array list of fields */ - protected $fieldsList; + protected array $fieldsList; /** - * @var array collection of result + * @var array collection of result */ - protected $collection; + protected array $collection; /** * @var int total number of results */ - protected $total; + protected int $total; /** * @var string name of the identifier */ - protected $identifier; + protected string $identifier; /** * @var bool if attribute is selected */ - protected $selection; + protected bool $selection; /** * @var string specific selection condition */ - protected $selectionCondition; + protected string $selectionCondition; /** * @var string name of Lengow controller */ - protected $controller; + protected string $controller; /** * @var int PrestaShop shop id */ - protected $shopId; + protected int $shopId = 0; /** * @var int number of the current page */ - protected $currentPage; + protected int $currentPage; /** - * @var array choice of number of results per page + * @var array choice of number of results per page */ - protected $nbPerPageList; + protected array $nbPerPageList; /** * @var int number of results per page */ - protected $nbPerPage; + protected int $nbPerPage; /** * @var int maximum number of pages */ - protected $nbMaxPage; + protected int $nbMaxPage; /** * @var int pagination from */ - protected $paginationFrom; + protected int $paginationFrom; /** * @var int pagination to */ - protected $paginationTo; + protected int $paginationTo; /** - * @var array all params for sql request + * @var array all params for sql request */ - protected $sql; + protected array $sql; /** * @var string shop identifier */ - protected $id; + protected string $id; /** * @var bool is ajax request */ - protected $ajax; + protected bool $ajax; /** * @var Context PrestaShop context instance */ - protected $context; + protected Context $context; /** * @var LengowTranslation Lengow translation instance */ - protected $locale; + protected LengowTranslation $locale; /** - * @var array PrestaShop currency by iso code + * @var array PrestaShop currency by iso code */ - protected $currencyCode; + protected array $currencyCode; /** * @var string order value condition */ - protected $orderValue; + protected string $orderValue; /** * @var string order column condition */ - protected $orderColumn; + protected string $orderColumn; /** * Construct * - * @param array $params list of parameters + * @param array $params list of parameters + * @param Context|null $context PrestaShop context (injected from legacy controller where available) */ - public function __construct($params) + public function __construct(array $params, ?Context $context = null) { + $ctx = $context ?? LengowContext::getContext(); $this->id = $params['id']; $this->fieldsList = $params['fields_list']; $this->identifier = $params['identifier']; $this->selection = $params['selection']; $this->selectionCondition = isset($params['selection_condition']) ? $params['selection_condition'] : false; $this->controller = $params['controller']; - $this->shopId = isset($params['shop_id']) ? $params['shop_id'] : null; + $this->shopId = isset($params['shop_id']) ? (int) $params['shop_id'] : (int) ($ctx->shop->id ?? 0); $this->currentPage = isset($params['current_page']) ? $params['current_page'] : 1; $this->nbPerPageList = [20, 50, 100, 200]; $this->nbPerPage = (isset($params['nb_per_page']) && $params['nb_per_page'] != null) @@ -158,8 +160,8 @@ public function __construct($params) $this->sql = $params['sql']; $this->orderValue = isset($params['order_value']) ? $params['order_value'] : ''; $this->orderColumn = isset($params['order_column']) ? $params['order_column'] : ''; - $this->locale = new LengowTranslation(); - $this->context = Context::getContext(); + $this->locale = new LengowTranslation($ctx); + $this->context = $ctx; } /** @@ -169,7 +171,7 @@ public function __construct($params) * * @return string */ - public function displayHeader($order) + public function displayHeader(string $order): string { $tableClass = empty($this->collection) ? 'table_no_result' : ''; $newOrder = (empty($this->orderValue) || $this->orderValue === 'ASC') ? 'DESC' : 'ASC'; @@ -187,8 +189,8 @@ public function displayHeader($order) } $html .= ''; if (isset($values['filter_order']) && $values['filter_order']) { - $html .= '' . $values['title'] . ''; + $html .= '' . $values['title'] . ''; } else { $html .= $values['title']; } @@ -198,7 +200,7 @@ public function displayHeader($order) $html .= ''; if ($this->selection) { - $html .= 'id, ENT_QUOTES, 'UTF-8') . '" class="lengow_select_all lengow_link_tooltip"/>'; } foreach ($this->fieldsList as $key => $values) { @@ -213,28 +215,28 @@ class="lengow_select_all lengow_link_tooltip"/>'; } switch ($type) { case 'text': - $html .= ''; + $html .= ''; break; case 'select': - $html .= ''; $html .= ''; foreach ($values['filter_collection'] as $row) { $selected = $row['id'] == $value ? 'selected' : ''; - $html .= ''; + $html .= ''; } $html .= ''; break; case 'date': $from = isset($value['from']) ? $value['from'] : null; $to = isset($value['to']) ? $value['to'] : null; - $html .= '
'; - $html .= ''; + $html .= '
'; + value="' . htmlspecialchars((string) $to, ENT_QUOTES, 'UTF-8') . '" class="lengow_datepicker" />'; break; } } elseif (isset($values['button_search']) && $values['button_search']) { @@ -254,7 +256,7 @@ class="lgw-btn lgw-btn-white">'; * * @return string */ - public function displayContent() + public function displayContent(): string { $html = ''; if (empty($this->collection)) { @@ -275,31 +277,31 @@ public function displayContent() /** * Display Table Row * - * @param string $item item of the collection + * @param array $item item of the collection * * @return string */ - public function displayRow($item) + public function displayRow(array $item): string { $lengowLink = new LengowLink(); $html = ''; - $html .= 'identifier] . ' class="table_row">'; + $html .= 'identifier], ENT_QUOTES, 'UTF-8') . ' class="table_row">'; if ($this->selection) { if ($this->selectionCondition) { if ($item[$this->selectionCondition] > 0) { $html .= ' '; + name="selection[' . htmlspecialchars($item[$this->identifier], ENT_QUOTES, 'UTF-8') . ']" value="1">'; } else { $html .= ''; } } else { $html .= ''; + name="selection[' . htmlspecialchars($item[$this->identifier], ENT_QUOTES, 'UTF-8') . ']" value="1">'; } } foreach ($this->fieldsList as $key => $values) { if (isset($values['display_callback'])) { - $value = call_user_func_array($values['display_callback'], [$key, $item[$key], $item]); + $value = call_user_func_array($values['display_callback'], [$key, $item[$key] ?? '', $item]); } elseif (isset($values['type'])) { switch ($values['type']) { case 'date': @@ -312,11 +314,8 @@ public function displayRow($item) ); break; case 'price': - if (isset($item['currency'])) { - $value = Tools::displayPrice($item[$key], $this->getCurrencyByCode($item['currency'])); - } else { - $value = Tools::displayPrice($item[$key]); - } + $currency = isset($item['currency']) ? $this->getCurrencyByCode($item['currency']) : null; + $value = $this->formatPrice((float) $item[$key], $currency); break; case 'switch_product': $value = '
identifier] . '" + name="lengow_product_selection[' . htmlspecialchars($item[$this->identifier], ENT_QUOTES, 'UTF-8') . ']" + lengow_product_selection_' . htmlspecialchars($item[$this->identifier], ENT_QUOTES, 'UTF-8') . '" data-href="' . $lengowLink->getAbsoluteAdminLink($this->controller) . '" data-action="select_product" - data-id_shop="' . $this->shopId . '" - data-id_product="' . $item[$this->identifier] . '" + data-id_shop="' . (int) $this->shopId . '" + data-id_product="' . htmlspecialchars($item[$this->identifier], ENT_QUOTES, 'UTF-8') . '" value="1" ' . ($item[$key] ? 'checked="checked"' : '') . '/>
'; break; case 'flag_country': if ($item[$key]) { $isoCode = Tools::strtoupper($item[$key]); $value = ''; + data-original-title="' . htmlspecialchars(LengowCountry::getNameByIso($isoCode), ENT_QUOTES, 'UTF-8') . '"/>'; } else { $value = ''; } @@ -363,7 +362,7 @@ class="lengow_link_tooltip" * * @return string */ - public function displayFooter() + public function displayFooter(): string { return ''; } @@ -373,15 +372,15 @@ public function displayFooter() * * @return string */ - public function display() + public function display(): string { $lengowLink = new LengowLink(); - $html = '
id, ENT_QUOTES, 'UTF-8') . '" class="lengow_form_table" data-href="' . $lengowLink->getAbsoluteAdminLink($this->controller) . '">'; - $html .= ''; - $html .= ''; - $html .= ''; - $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; $html .= $this->displayHeader($this->orderColumn) . $this->displayContent() . $this->displayFooter(); $html .= ''; $html .= '
'; @@ -394,7 +393,7 @@ public function display() * * @return mixed */ - public function executeQuery() + public function executeQuery(): mixed { $sql = $this->buildQuery(); try { @@ -403,8 +402,8 @@ public function executeQuery() $this->collection = []; } $sqlTotal = $this->buildQuery(true); - $this->total = Db::getInstance()->getValue($sqlTotal, false); - $this->nbMaxPage = ceil($this->total / $this->nbPerPage); + $this->total = (int) Db::getInstance()->getValue($sqlTotal, false); + $this->nbMaxPage = (int) ceil($this->total / $this->nbPerPage); $this->paginationFrom = ($this->currentPage - 1) * $this->nbPerPage + 1; if ($this->total === 0) { $this->paginationFrom = 0; @@ -427,9 +426,9 @@ public function executeQuery() * * @param string $where where conditions * - * @return array + * @return array */ - public function getRow($where) + public function getRow(string $where): array { if (!isset($this->sql['where'])) { $this->sql['where'] = []; @@ -452,9 +451,9 @@ public function getRow($where) * * @param string $keyToSearch key search in field list * - * @return bool + * @return array|false */ - public function findValueByKey($keyToSearch) + public function findValueByKey(string $keyToSearch): array|false { foreach ($this->fieldsList as $key => $value) { if ($keyToSearch === $key) { @@ -473,7 +472,7 @@ public function findValueByKey($keyToSearch) * * @return string */ - public function buildQuery($total = false, $selectAll = false) + public function buildQuery(bool $total = false, bool $selectAll = false): string { $where = isset($this->sql['where']) ? $this->sql['where'] : []; $groupBy = false; @@ -498,7 +497,7 @@ public function buildQuery($total = false, $selectAll = false) break; case 'select': case 'text': - if (Tools::strlen($value) > 0) { + if (mb_strlen((string) $value) > 0) { $where[] = ' ' . pSQL($fieldValue['filter_key']) . ' LIKE "%' . pSQL($value) . '%"'; } break; @@ -525,7 +524,7 @@ public function buildQuery($total = false, $selectAll = false) } break; case 'order_types': - if (Tools::strlen($value) > 0) { + if (mb_strlen((string) $value) > 0) { if ($value === LengowOrder::TYPE_EXPRESS) { $where[] = ' (lo.order_types LIKE "%' . pSQL(LengowOrder::TYPE_EXPRESS) . '%" OR lo.order_types LIKE "%' . pSQL(LengowOrder::TYPE_PRIME) . '%")'; @@ -569,7 +568,7 @@ public function buildQuery($total = false, $selectAll = false) $sql .= ' HAVING ' . implode(' AND ', $having); } if (!$total && !$selectAll) { - if (Tools::strlen($this->orderColumn) > 0 && in_array($this->orderValue, ['ASC', 'DESC'])) { + if (mb_strlen((string) $this->orderColumn) > 0 && in_array($this->orderValue, ['ASC', 'DESC'])) { $sql .= ' ORDER BY ' . pSQL($this->orderColumn) . ' ' . $this->orderValue; if (isset($this->sql['order'])) { $sql .= ', ' . $this->sql['order']; @@ -589,9 +588,11 @@ public function buildQuery($total = false, $selectAll = false) /** * Update collection * - * @param array $collection collection of result + * @param array $collection collection of result + * + * @return void */ - public function updateCollection($collection) + public function updateCollection(array $collection): void { $this->collection = $collection; } @@ -599,11 +600,11 @@ public function updateCollection($collection) /** * Render pagination * - * @param array $params pagination params + * @param array $params pagination params * * @return string */ - public function renderPagination($params = []) + public function renderPagination(array $params = []): string { $navClass = isset($params['nav_class']) ? $params['nav_class'] : ''; $lengowLink = new LengowLink(); @@ -690,20 +691,36 @@ public function renderPagination($params = []) * * @return Currency */ - private function getCurrencyByCode($isoCode) + private function getCurrencyByCode(string $isoCode): Currency { - if ($isoCode) { - if (isset($this->currencyCode[$isoCode])) { - return $this->currencyCode[$isoCode]; + if (!$isoCode) { + return $this->context->currency; + } + + if (isset($this->currencyCode[$isoCode])) { + $cached = $this->currencyCode[$isoCode]; + if ($cached instanceof Currency) { + return $cached; } - $currency = Currency::getCurrency(Currency::getIdByIsoCode($isoCode)); - if ($currency) { - $this->currencyCode[$isoCode] = $currency; - } else { - $this->currencyCode[$isoCode] = $this->context->currency; + if (is_array($cached)) { + $id = isset($cached['id_currency']) ? (int) $cached['id_currency'] : (isset($cached['id']) ? (int) $cached['id'] : 0); + if ($id > 0) { + $currencyObj = new Currency($id); + $this->currencyCode[$isoCode] = $currencyObj; + + return $currencyObj; + } } - return $this->currencyCode[$isoCode]; + return $this->context->currency; + } + + $id = Currency::getIdByIsoCode($isoCode); + if ($id) { + $currencyObj = new Currency((int) $id); + $this->currencyCode[$isoCode] = $currencyObj; + + return $currencyObj; } return $this->context->currency; @@ -714,8 +731,22 @@ private function getCurrencyByCode($isoCode) * * @return int */ - public function getTotal() + public function getTotal(): int { return $this->total; } + + protected function formatPrice(float $price, ?Currency $currency = null): string + { + if ($currency === null) { + $currency = $this->context->currency; + } + + $locale = Tools::getContextLocale($this->context); + + return $locale->formatPrice( + $price, + $currency->iso_code + ); + } } diff --git a/classes/models/LengowLog.php b/classes/models/LengowLog.php index e187b076..cd9fc1ac 100755 --- a/classes/models/LengowLog.php +++ b/classes/models/LengowLog.php @@ -44,7 +44,7 @@ class LengowLog extends LengowFile /** * @var LengowFile Lengow file instance */ - protected $file; + protected LengowFile $file; /** * Construct @@ -53,7 +53,7 @@ class LengowLog extends LengowFile * * @throws LengowException */ - public function __construct($fileName = null) + public function __construct(?string $fileName = null) { if (empty($fileName)) { $this->fileName = 'logs-' . date(LengowMain::DATE_DAY) . '.txt'; @@ -70,8 +70,10 @@ public function __construct($fileName = null) * @param string $message log message * @param bool $logOutput display on screen * @param string|null $marketplaceSku Lengow order id + * + * @return void */ - public function write($category, $message = '', $logOutput = false, $marketplaceSku = null) + public function write(string $category, string $message = '', bool $logOutput = false, ?string $marketplaceSku = null): void { $decodedMessage = LengowMain::decodeLogMessage($message, LengowTranslation::DEFAULT_ISO_CODE); $log = date(LengowMain::DATE_FULL); @@ -88,9 +90,9 @@ public function write($category, $message = '', $logOutput = false, $marketplace /** * Get log files path * - * @return array + * @return array */ - public static function getPaths() + public static function getPaths(): array { $logs = []; $files = self::getFiles(); @@ -116,7 +118,7 @@ public static function getPaths() * * @return string */ - public function getFileName() + public function getFileName(): string { $sep = DIRECTORY_SEPARATOR; @@ -126,9 +128,9 @@ public function getFileName() /** * Get log files * - * @return array + * @return array */ - public static function getFiles() + public static function getFiles(): array { return LengowFile::getFilesFromFolder(LengowMain::FOLDER_LOG); } @@ -137,8 +139,10 @@ public static function getFiles() * Download log file * * @param string|null $date date for a specific log file + * + * @return void */ - public static function download($date = null) + public static function download(?string $date = null): void { /* @var LengowFile[] $logFiles */ if ($date && preg_match('/^(\d{4}-\d{2}-\d{2})$/', $date, $match)) { @@ -172,6 +176,9 @@ public static function download($date = null) if (strrpos($fileInfo['basename'], 'logs') === false) { continue; } + if (!LengowMain::isPathAllowed($filePath, _PS_MODULE_LENGOW_DIR_)) { + continue; + } $handle = fopen($filePath, 'rb'); $fileSize = filesize($filePath); if ($fileSize > 0) { @@ -180,7 +187,8 @@ public static function download($date = null) } } header('Content-type: text/plain'); - header('Content-Disposition: attachment; filename="' . $fileName . '"'); + $safeFileName = preg_replace('/[^a-zA-Z0-9._\-]/', '', str_replace(["\r", "\n"], '', $fileName)); + header('Content-Disposition: attachment; filename="' . $safeFileName . '"'); echo $contents; exit; } @@ -188,8 +196,10 @@ public static function download($date = null) /** * Logs potential PHP fatal error on shutdown. * Can be useful when the script crash silently + * + * @return void */ - public static function registerShutdownFunction() + public static function registerShutdownFunction(): void { ini_set('log_errors_max_len', 10240); register_shutdown_function( @@ -208,7 +218,7 @@ function () { E_USER_ERROR => 'E_USER_ERROR', E_USER_WARNING => 'E_USER_WARNING', E_USER_NOTICE => 'E_USER_NOTICE', - E_STRICT => 'E_STRICT', + // E_STRICT is deprecated in PHP 8.4 E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR', E_DEPRECATED => 'E_DEPRECATED', E_USER_DEPRECATED => 'E_USER_DEPRECATED', diff --git a/classes/models/LengowMain.php b/classes/models/LengowMain.php index 02832037..80cae605 100755 --- a/classes/models/LengowMain.php +++ b/classes/models/LengowMain.php @@ -34,11 +34,6 @@ class LengowMain public const FOLDER_TRANSLATION = 'translations'; public const FOLDER_WEBSERVICE = 'webservice'; - /* Lengow webservices */ - public const WEBSERVICE_EXPORT = 'export.php'; - public const WEBSERVICE_CRON = 'cron.php'; - public const WEBSERVICE_TOOLBOX = 'toolbox.php'; - /* Date formats */ public const DATE_FULL = 'Y-m-d H:i:s'; public const DATE_DAY = 'Y-m-d'; @@ -50,19 +45,19 @@ class LengowMain public const LOG_LIFE = 20; /** - * @var LengowLog Lengow log file instance + * @var LengowLog|null Lengow log file instance */ - public static $log; + public static ?LengowLog $log = null; /** - * @var array marketplace registers + * @var array marketplace registers */ - public static $registers; + public static array $registers = []; /** - * @var array product ids available to track products + * @var array product ids available to track products */ - public static $trackerChoiceId = [ + public static array $trackerChoiceId = [ 'id' => 'Product ID', 'ean' => 'Product EAN', 'upc' => 'Product UPC', @@ -70,9 +65,9 @@ class LengowMain ]; /** - * @var array Lengow Authorized IPs + * @var list Lengow Authorized IPs */ - protected static $ipsLengow = [ + protected static array $ipsLengow = [ '127.0.0.1', '10.0.4.150', '46.19.183.204', @@ -104,18 +99,18 @@ class LengowMain ]; /** - * @var array PrestaShop mail configuration + * @var array PrestaShop mail configuration */ - protected static $mailConfigurations = []; + protected static array $mailConfigurations = []; /** * The PrestaShop compare version with current version. * * @param string $version the version to compare * - * @return bool + * @return int */ - public static function compareVersion($version = '1.4') + public static function compareVersion(string $version = '1.4'): int { $subVersion = Tools::substr(_PS_VERSION_, 0, 3); @@ -127,7 +122,7 @@ public static function compareVersion($version = '1.4') * * @return string */ - public static function getLengowFolder() + public static function getLengowFolder(): string { return _PS_MODULE_DIR_ . self::FOLDER_LENGOW; } @@ -137,9 +132,9 @@ public static function getLengowFolder() * * @param string $state state to be matched * - * @return int + * @return int|false */ - public static function getOrderState($state) + public static function getOrderState(string $state): int|false { switch ($state) { case LengowOrder::STATE_ACCEPTED: @@ -164,8 +159,10 @@ public static function getOrderState($state) /** * Temporary enable mail sending + * + * @return void */ - public static function enableMail() + public static function enableMail(): void { if (isset(self::$mailConfigurations['method'])) { Configuration::set('PS_MAIL_METHOD', (int) self::$mailConfigurations['method']); @@ -174,8 +171,10 @@ public static function enableMail() /** * Temporary disable mail sending + * + * @return void */ - public static function disableMail() + public static function disableMail(): void { self::$mailConfigurations = [ 'method' => Configuration::get('PS_MAIL_METHOD'), @@ -188,8 +187,10 @@ public static function disableMail() * Record the date of the last import * * @param string $type last import type (cron or manual) + * + * @return void */ - public static function updateDateImport($type) + public static function updateDateImport(string $type): void { if ($type === LengowImport::TYPE_CRON) { LengowConfiguration::updateGlobalValue(LengowConfiguration::LAST_UPDATE_CRON_SYNCHRONIZATION, time()); @@ -201,35 +202,35 @@ public static function updateDateImport($type) /** * Get last import (type and timestamp) * - * @return array + * @return array */ - public static function getLastImport() + public static function getLastImport(): array { - $timestampCron = LengowConfiguration::getGlobalValue(LengowConfiguration::LAST_UPDATE_CRON_SYNCHRONIZATION); - $timestampManual = LengowConfiguration::getGlobalValue(LengowConfiguration::LAST_UPDATE_MANUAL_SYNCHRONIZATION); + $timestampCron = (int) LengowConfiguration::getGlobalValue(LengowConfiguration::LAST_UPDATE_CRON_SYNCHRONIZATION); + $timestampManual = (int) LengowConfiguration::getGlobalValue(LengowConfiguration::LAST_UPDATE_MANUAL_SYNCHRONIZATION); if ($timestampCron && $timestampManual) { - if ((int) $timestampCron > (int) $timestampManual) { + if ($timestampCron > $timestampManual) { return [ 'type' => LengowImport::TYPE_CRON, - 'timestamp' => (int) $timestampCron, + 'timestamp' => $timestampCron, ]; } return [ 'type' => LengowImport::TYPE_MANUAL, - 'timestamp' => (int) $timestampManual, + 'timestamp' => $timestampManual, ]; } - if ($timestampCron && !$timestampManual) { + if ($timestampCron) { return [ 'type' => LengowImport::TYPE_CRON, - 'timestamp' => (int) $timestampCron, + 'timestamp' => $timestampCron, ]; } - if ($timestampManual && !$timestampCron) { + if ($timestampManual) { return [ 'type' => LengowImport::TYPE_MANUAL, - 'timestamp' => (int) $timestampManual, + 'timestamp' => $timestampManual, ]; } @@ -244,7 +245,7 @@ public static function getLastImport() * * @return string */ - public static function getDateInCorrectFormat($timestamp, $second = false) + public static function getDateInCorrectFormat(int $timestamp, bool $second = false): string { if ($second) { $format = 'l d F Y @ H:i:s'; @@ -264,7 +265,7 @@ public static function getDateInCorrectFormat($timestamp, $second = false) * * @throws LengowException */ - public static function getMarketplaceSingleton($name) + public static function getMarketplaceSingleton(string $name): ?LengowMarketplace { if (empty($name)) { return null; @@ -289,14 +290,14 @@ public static function getMarketplaceSingleton($name) * * @return string */ - public static function cleanHtml($html) + public static function cleanHtml(string $html): string { - $string = str_replace('
', ' ', nl2br($html)); + $string = str_replace('
', ' ', nl2br((string) $html)); $string = trim(strip_tags(htmlspecialchars_decode($string))); $string = preg_replace('`[\s]+`sim', ' ', $string); $string = preg_replace('`"`sim', '', $string); $string = nl2br($string); - $pattern = '@<[\/\!]*?[^<>]*?>@si'; + $pattern = '@<[/!]*?[^<>]*?>@si'; $string = preg_replace($pattern, ' ', $string); $string = preg_replace('/[\s]+/', ' ', $string); $string = trim($string); @@ -311,11 +312,11 @@ public static function cleanHtml($html) /** * Format float * - * @param float $float the float to format + * @param float|string $float the float to format * - * @return float + * @return string */ - public static function formatNumber($float) + public static function formatNumber($float): string { return number_format(round($float, 2), 2, '.', ''); } @@ -325,11 +326,11 @@ public static function formatNumber($float) * * @return string Hostname */ - public static function getHost() + public static function getHost(): string { $domain = defined('_PS_SHOP_DOMAIN_') ? _PS_SHOP_DOMAIN_ : _PS_BASE_URL_; preg_match('`([a-zàâäéèêëôöùûüîïç0-9-]+\.[a-z]+)`', $domain, $out); - if ($out[1]) { + if (!empty($out[1])) { return $out[1]; } @@ -344,18 +345,13 @@ public static function getHost() * * @return bool */ - public static function checkWebservicesAccess($token, $idShop = null) + public static function checkWebservicesAccess(string $token, ?int $idShop = null): bool { - if (!(bool) LengowConfiguration::get(LengowConfiguration::AUTHORIZED_IP_ENABLED) - && self::checkToken($token, $idShop) - ) { - return true; - } - if (self::checkIp()) { - return true; + if ((bool) LengowConfiguration::get(LengowConfiguration::AUTHORIZED_IP_ENABLED)) { + return self::checkToken($token, $idShop) || self::checkIp(); } - return false; + return self::checkToken($token, $idShop); } /** @@ -366,7 +362,7 @@ public static function checkWebservicesAccess($token, $idShop = null) * * @return bool */ - public static function checkToken($token, $idShop = null) + public static function checkToken(string $token, ?int $idShop = null): bool { $storeToken = self::getToken($idShop); @@ -380,7 +376,7 @@ public static function checkToken($token, $idShop = null) * * @return string */ - public static function getToken($idShop = null) + public static function getToken(?int $idShop = null): string { if ($idShop === null) { $token = LengowConfiguration::getGlobalValue(LengowConfiguration::CMS_TOKEN); @@ -395,7 +391,8 @@ public static function getToken($idShop = null) return $token; } $token = bin2hex(openssl_random_pseudo_bytes(16)); - LengowConfiguration::updateValue(LengowConfiguration::SHOP_TOKEN, $token, null, null, $idShop); + LengowConfiguration::updateValue(LengowConfiguration::SHOP_TOKEN, $token, + false, null, $idShop); } return $token; @@ -406,7 +403,7 @@ public static function getToken($idShop = null) * * @return bool */ - public static function checkIp() + public static function checkIp(): bool { $authorizedIps = array_merge(LengowConfiguration::getAuthorizedIps(), self::$ipsLengow); if (isset($_SERVER['SERVER_ADDR'])) { @@ -423,8 +420,10 @@ public static function checkIp() * @param string $txt log message * @param bool $logOutput output on screen * @param string|null $marketplaceSku Lengow marketplace sku + * + * @return void */ - public static function log($category, $txt, $logOutput = false, $marketplaceSku = null) + public static function log(string $category, string $txt, bool $logOutput = false, ?string $marketplaceSku = null): void { $log = self::getLogInstance(); if ($log) { @@ -436,13 +435,13 @@ public static function log($category, $txt, $logOutput = false, $marketplaceSku * Set message with params for translation * * @param string $key log key - * @param array|null $params log parameters + * @param array|null $params log parameters * * @return string */ - public static function setLogMessage($key, $params = null) + public static function setLogMessage(string $key, ?array $params = null): string { - if ($params === null || (is_array($params) && empty($params))) { + if ($params === null || empty($params)) { return $key; } $allParams = []; @@ -459,26 +458,24 @@ public static function setLogMessage($key, $params = null) * * @param string $message log message * @param string|null $isoCode iso code for translation - * @param array|null $params log parameters + * @param array|null $params log parameters * * @return string */ - public static function decodeLogMessage($message, $isoCode = null, $params = null) + public static function decodeLogMessage(string $message, ?string $isoCode = null, ?array $params = null): string { - if (preg_match('/^(([a-z\_]*\.){1,3}[a-z\_]*)(\[(.*)\]|)$/', $message, $result)) { - if (isset($result[1])) { - $key = $result[1]; - if (isset($result[4]) && $params === null) { - $strParam = $result[4]; - $allParams = explode('|', $strParam); - foreach ($allParams as $param) { - $result = explode('==', $param); - $params[$result[0]] = $result[1]; - } + if (preg_match('/^(([a-z_]*\.){1,3}[a-z_]*)(\[(.*)\]|)$/', $message, $result)) { + $key = $result[1]; + if (isset($result[4]) && $params === null) { + $strParam = $result[4]; + $allParams = explode('|', (string) $strParam); + foreach ($allParams as $param) { + $result = explode('==', (string) $param); + $params[$result[0]] = $result[1]; } - $locale = new LengowTranslation(); - $message = $locale->t($key, $params, $isoCode); } + $locale = new LengowTranslation(); + $message = $locale->t($key, $params ?? [], $isoCode); } return $message; @@ -486,8 +483,10 @@ public static function decodeLogMessage($message, $isoCode = null, $params = nul /** * Suppress log files when too old + * + * @return void */ - public static function cleanLog() + public static function cleanLog(): void { $days = []; $days[] = 'logs-' . date(self::DATE_DAY) . '.txt'; @@ -513,7 +512,7 @@ public static function cleanLog() * * @return string */ - public static function cleanData($value) + public static function cleanData(string $value): string { $value = preg_replace( '/[\x00-\x08\x10\x0B\x0C\x0E-\x19\x7F]' . @@ -577,9 +576,9 @@ public static function cleanData($value) * * @param string $phone Phone to clean * - * @return string + * @return string|null */ - public static function cleanPhone($phone) + public static function cleanPhone(string $phone): ?string { $replace = ['.', ' ', '-', '/']; if (!$phone) { @@ -599,7 +598,7 @@ public static function cleanPhone($phone) * * @return string */ - public static function replaceAccentedChars($str) + public static function replaceAccentedChars(string $str): string { /* One source among others: http://www.tachyonsoft.com/uc0000.htm @@ -671,7 +670,7 @@ public static function replaceAccentedChars($str) /* K */ '/[\x{0136}]/u', /* L */ - '/[\x{0139}\x{013B}\x{013D}\x{0139}\x{0141}]/u', + '/[\x{0139}\x{013B}\x{013D}\x{0141}]/u', /* N */ '/[\x{00D1}\x{0143}\x{0145}\x{0147}\x{014A}]/u', /* O */ @@ -752,7 +751,7 @@ public static function replaceAccentedChars($str) * * @return bool */ - public static function sendMailAlert($logOutput = false) + public static function sendMailAlert(bool $logOutput = false): bool { $success = true; // recovery of all errors not yet sent by email @@ -786,7 +785,7 @@ public static function sendMailAlert($logOutput = false) ]; // send an email if the template exists for the locale $emails = LengowConfiguration::getReportEmailAddress(); - $idLang = (int) Context::getContext()->cookie->id_lang; + $idLang = (int) LengowContext::getContext()->cookie->id_lang; $iso = Language::getIsoById($idLang); if (file_exists(_PS_MODULE_DIR_ . 'lengow/mails/' . $iso . '/report.txt') && file_exists(_PS_MODULE_DIR_ . 'lengow/mails/' . $iso . '/report.html') @@ -842,9 +841,11 @@ public static function sendMailAlert($logOutput = false) * * @return bool */ - public static function isModuleInstalled($moduleName) + public static function isModuleInstalled(string $moduleName): bool { - return Module::isInstalled($moduleName) && Module::isEnabled($moduleName); + $module = Module::getInstanceByName($moduleName); + + return $module !== false && (bool) $module->active; } /** @@ -852,24 +853,39 @@ public static function isModuleInstalled($moduleName) * * @return bool */ - public static function isMondialRelayV2Available() + public static function isMondialRelayV2Available(): bool { return self::isMondialRelayVersionAvailable('2.1.0', '3.0.0'); } - private static function isMondialRelayVersionAvailable($minVersion, $maxVersion) + /** + * @param string $minVersion + * @param string $maxVersion + * + * @return bool + */ + private static function isMondialRelayVersionAvailable(string $minVersion, string $maxVersion): bool { $moduleName = 'mondialrelay'; + $moduleClassName = 'MondialRelay'; $sep = DIRECTORY_SEPARATOR; $moduleDir = _PS_MODULE_DIR_ . $moduleName . $sep; if (!self::isModuleInstalled($moduleName)) { return false; } require_once $moduleDir . $moduleName . '.php'; - $mr = new MondialRelay(); + if (!class_exists($moduleClassName)) { + return false; + } + $mr = new $moduleClassName(); + $mrData = is_object($mr) ? (array) $mr : []; + $moduleVersion = isset($mrData['version']) && is_string($mrData['version']) ? $mrData['version'] : null; + if ($moduleVersion === null) { + return false; + } - return version_compare($mr->version, $minVersion, '>=') - && version_compare($mr->version, $maxVersion, '<'); + return version_compare($moduleVersion, $minVersion, '>=') + && version_compare($moduleVersion, $maxVersion, '<'); } /** @@ -877,7 +893,7 @@ private static function isMondialRelayVersionAvailable($minVersion, $maxVersion) * * @return bool */ - public static function isMondialRelayV3Available() + public static function isMondialRelayV3Available(): bool { return self::isMondialRelayVersionAvailable('3.0.0', '4.0.0'); } @@ -887,9 +903,10 @@ public static function isMondialRelayV3Available() * * @return bool */ - public static function isSoColissimoAvailable() + public static function isSoColissimoAvailable(): bool { - $moduleName = _PS_VERSION_ < '1.7' ? 'socolissimo' : 'colissimo_simplicite'; + $moduleName = 'colissimo_simplicite'; + $moduleClassName = 'Colissimo_simplicite'; $supportedVersion = '2.8.5'; $sep = DIRECTORY_SEPARATOR; $moduleDir = _PS_MODULE_DIR_ . $moduleName . $sep; @@ -897,8 +914,16 @@ public static function isSoColissimoAvailable() return false; } require_once $moduleDir . $moduleName . '.php'; - $soColissimo = _PS_VERSION_ < '1.7' ? new Socolissimo() : new Colissimo_simplicite(); - if (version_compare($soColissimo->version, $supportedVersion, '>=')) { + if (!class_exists($moduleClassName)) { + return false; + } + $soColissimo = new $moduleClassName(); + $soColissimoData = is_object($soColissimo) ? (array) $soColissimo : []; + $moduleVersion = isset($soColissimoData['version']) && is_string($soColissimoData['version']) ? $soColissimoData['version'] : null; + if ($moduleVersion === null) { + return false; + } + if (version_compare($moduleVersion, $supportedVersion, '>=')) { return true; } @@ -914,7 +939,7 @@ public static function isSoColissimoAvailable() * * @return int */ - public static function getPrestashopStateId($orderStateMarketplace, $marketplace, $shipmentByMp) + public static function getPrestashopStateId(string $orderStateMarketplace, LengowMarketplace $marketplace, bool $shipmentByMp): int { if ($shipmentByMp) { $orderState = 'shippedByMp'; @@ -934,9 +959,9 @@ public static function getPrestashopStateId($orderStateMarketplace, $marketplace * * @param int $idLang PrestaShop lang id * - * @return array + * @return array */ - public static function getOrderStates($idLang) + public static function getOrderStates(int $idLang): array { $states = OrderState::getOrderStates($idLang); $idStateLengow = self::getLengowErrorStateId(); @@ -956,7 +981,7 @@ public static function getOrderStates($idLang) * * @return LengowLog|false */ - public static function getLogInstance() + public static function getLogInstance(): LengowLog|false { if (self::$log === null) { try { @@ -970,43 +995,37 @@ public static function getLogInstance() } /** - * Get export webservice links + * Get export controller links * * @param int|null $idShop PrestaShop shop id * * @return string */ - public static function getExportUrl($idShop = null) + public static function getExportUrl(?int $idShop = null): string { - $sep = DIRECTORY_SEPARATOR; - - return self::getLengowBaseUrl($idShop) . self::FOLDER_WEBSERVICE . $sep . self::WEBSERVICE_EXPORT . '?' + return self::getLengowBaseUrl($idShop) . 'webservice/export.php?' . LengowExport::PARAM_TOKEN . '=' . self::getToken($idShop); } /** - * Get cron webservice links + * Get cron controller links * * @return string */ - public static function getCronUrl() + public static function getCronUrl(): string { - $sep = DIRECTORY_SEPARATOR; - - return self::getLengowBaseUrl() . self::FOLDER_WEBSERVICE . $sep . self::WEBSERVICE_CRON . '?' + return self::getLengowBaseUrl() . 'webservice/cron.php?' . LengowImport::PARAM_TOKEN . '=' . self::getToken(); } /** - * Get toolbox webservice links + * Get toolbox controller links * * @return string */ - public static function getToolboxUrl() + public static function getToolboxUrl(): string { - $sep = DIRECTORY_SEPARATOR; - - return self::getLengowBaseUrl() . self::FOLDER_WEBSERVICE . $sep . self::WEBSERVICE_TOOLBOX . '?' + return self::getLengowBaseUrl() . 'webservice/toolbox.php?' . LengowToolbox::PARAM_TOKEN . '=' . self::getToken(); } @@ -1017,11 +1036,11 @@ public static function getToolboxUrl() * * @return string */ - public static function getLengowBaseUrl($idShop = null) + public static function getLengowBaseUrl(?int $idShop = null): string { $isHttps = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] ? 's' : ''; try { - $idShop = $idShop === null ? Context::getContext()->shop->id : $idShop; + $idShop = $idShop === null ? LengowContext::getContext()->shop->id : $idShop; $shopUrl = self::getMainShopUrl($idShop); $base = 'http' . $isHttps . '://' . $shopUrl->domain . $shopUrl->physical_uri . $shopUrl->virtual_uri; } catch (Exception $e) { @@ -1040,7 +1059,7 @@ public static function getLengowBaseUrl($idShop = null) * * @throws Exception */ - public static function getMainShopUrl($idShop) + public static function getMainShopUrl(int $idShop): ShopUrl { $shopUrls = ShopUrl::getShopUrls($idShop); /** @var ShopUrl[] $shopUrls */ @@ -1060,7 +1079,7 @@ public static function getMainShopUrl($idShop) * * @return string */ - public static function getShopNameCleaned($shopName) + public static function getShopNameCleaned(string $shopName): string { return Tools::strtolower( preg_replace( @@ -1078,14 +1097,14 @@ public static function getShopNameCleaned($shopName) * * @return int|null */ - public static function getLengowErrorStateId($idLang = null) + public static function getLengowErrorStateId(?int $idLang = null): ?int { $idErrorState = LengowConfiguration::getGlobalValue(LengowConfiguration::LENGOW_ERROR_STATE_ID); if ($idErrorState) { return (int) $idErrorState; } if (!$idLang) { - $idLang = Context::getContext()->language->id; + $idLang = LengowContext::getContext()->language->id; } $states = OrderState::getOrderStates($idLang); foreach ($states as $state) { @@ -1104,7 +1123,7 @@ public static function getLengowErrorStateId($idLang = null) * * @return string */ - public function fromCamelCase($str) + public function fromCamelCase(string $str): string { $str[0] = Tools::strtolower($str[0]); @@ -1116,4 +1135,30 @@ static function ($c) { $str ); } + + /** + * Check if a file path is within an allowed base directory + * + * @param string $filePath file path to validate + * @param string $baseDir allowed base directory + * + * @return bool + */ + public static function isPathAllowed(string $filePath, string $baseDir): bool + { + $realBase = realpath($baseDir); + if ($realBase === false) { + return false; + } + // For files that don't exist yet, check the parent directory + $realPath = realpath($filePath); + if ($realPath === false) { + $realPath = realpath(dirname($filePath)); + if ($realPath === false) { + return false; + } + } + + return str_starts_with($realPath, $realBase); + } } diff --git a/classes/models/LengowMarketplace.php b/classes/models/LengowMarketplace.php index 797232a1..1929687f 100644 --- a/classes/models/LengowMarketplace.php +++ b/classes/models/LengowMarketplace.php @@ -43,73 +43,73 @@ class LengowMarketplace public const FILE_MARKETPLACE = 'marketplaces.json'; /** - * @var array all valid actions + * @var list all valid actions */ - public static $validActions = [ + public static array $validActions = [ LengowAction::TYPE_SHIP, LengowAction::TYPE_CANCEL, LengowAction::TYPE_REFUND, ]; /** - * @var array|false all marketplaces + * @var object|false all marketplaces */ - public static $marketplaces = false; + public static object|false $marketplaces = false; /** * @var mixed the current marketplace */ - public $marketplace; + public mixed $marketplace; /** * @var string the code of the marketplace */ - public $name; + public string $name; /** * @var string the old code of the marketplace for v2 compatibility */ - public $legacyCode; + public ?string $legacyCode = null; /** * @var string the name of the marketplace */ - public $labelName; + public string $labelName; /** * @var bool if the marketplace is loaded */ - public $isLoaded = false; + public bool $isLoaded = false; /** - * @var array Lengow states => marketplace states + * @var array Lengow states => marketplace states */ - public $statesLengow = []; + public array $statesLengow = []; /** - * @var array marketplace states => Lengow states + * @var array marketplace states => Lengow states */ - public $states = []; + public array $states = []; /** - * @var array all possible actions of the marketplace + * @var array all possible actions of the marketplace */ - public $actions = []; + public array $actions = []; /** - * @var array all possible values for actions of the marketplace + * @var array all possible values for actions of the marketplace */ - public $argValues = []; + public array $argValues = []; /** - * @var array all carriers of the marketplace + * @var array all carriers of the marketplace */ - public $carriers = []; + public array $carriers = []; /** - * @var array all shipping methods of the marketplace + * @var array all shipping methods of the marketplace */ - public $shippingMethods = []; + public array $shippingMethods = []; /** * Construct a new Marketplace instance with marketplace API @@ -118,7 +118,7 @@ class LengowMarketplace * * @throws LengowException marketplace not present */ - public function __construct($name) + public function __construct(string $name) { self::loadApiMarketplace(); $this->name = (string) Tools::strtolower($name); @@ -188,8 +188,10 @@ public function __construct($name) * * @param bool $force force cache update * @param bool $logOutput see log or not + * + * @return void */ - public static function loadApiMarketplace($force = false, $logOutput = false) + public static function loadApiMarketplace(bool $force = false, bool $logOutput = false): void { if (!self::$marketplaces || $force) { self::$marketplaces = LengowSync::getMarketplaces($force, $logOutput); @@ -201,7 +203,7 @@ public static function loadApiMarketplace($force = false, $logOutput = false) * * @return string */ - public static function getFilePath() + public static function getFilePath(): string { $sep = DIRECTORY_SEPARATOR; @@ -215,7 +217,7 @@ public static function getFilePath() * * @return string|false */ - public function getStateLengow($name) + public function getStateLengow(string $name): string|false { if (array_key_exists($name, $this->statesLengow)) { return $this->statesLengow[$name]; @@ -229,9 +231,9 @@ public function getStateLengow($name) * * @param string $name action's name * - * @return array|false + * @return array|false */ - public function getAction($name) + public function getAction(string $name): array|false { if (array_key_exists($name, $this->actions)) { return $this->actions[$name]; @@ -247,7 +249,7 @@ public function getAction($name) * * @return string|false */ - public function getDefaultValue($name) + public function getDefaultValue(string $name): string|false { if (array_key_exists($name, $this->argValues)) { $defaultValue = $this->argValues[$name]['default_value']; @@ -266,7 +268,7 @@ public function getDefaultValue($name) * * @return bool */ - public function containOrderLine($action) + public function containOrderLine(string $action): bool { if (isset($this->actions[$action])) { $actions = $this->actions[$action]; @@ -292,7 +294,7 @@ public function containOrderLine($action) * * @return bool */ - public function hasCarriers() + public function hasCarriers(): bool { return !empty($this->carriers); } @@ -302,7 +304,7 @@ public function hasCarriers() * * @return bool */ - public function hasShippingMethods() + public function hasShippingMethods(): bool { return !empty($this->shippingMethods); } @@ -313,10 +315,11 @@ public function hasShippingMethods() * @param string $action Lengow order actions type (ship or cancel) * @param LengowOrder $lengowOrder Lengow order instance * @param string|null $idOrderLine Lengow order line id + * @param mixed $partialAction * * @return bool */ - public function callAction($action, $lengowOrder, $idOrderLine = null, $partialAction = false) + public function callAction(string $action, LengowOrder $lengowOrder, ?string $idOrderLine = null, mixed $partialAction = false): bool { try { // check the action and order data @@ -372,7 +375,7 @@ public function callAction($action, $lengowOrder, $idOrderLine = null, $partialA } if (isset($errorMessage)) { if ($lengowOrder->lengowProcessState !== LengowOrder::PROCESS_STATE_FINISH) { - LengowOrderError::addOrderLog($lengowOrder->lengowId, $errorMessage, LengowOrderError::TYPE_ERROR_SEND); + LengowOrderError::addOrderLog((int) $lengowOrder->lengowId, $errorMessage, LengowOrderError::TYPE_ERROR_SEND); } $decodedMessage = LengowMain::decodeLogMessage($errorMessage, LengowTranslation::DEFAULT_ISO_CODE); LengowMain::log( @@ -396,9 +399,11 @@ public function callAction($action, $lengowOrder, $idOrderLine = null, $partialA * * @param string $action Lengow order actions type (ship or cancel) * + * @return void + * * @throws LengowException action not valid / marketplace action not present */ - protected function checkAction($action) + protected function checkAction(string $action): void { if (!in_array($action, self::$validActions, true)) { throw new LengowException(LengowMain::setLogMessage('lengow_log.exception.action_not_valid', ['action' => $action])); @@ -413,9 +418,11 @@ protected function checkAction($action) * * @param LengowOrder $lengowOrder Lengow order instance * + * @return void + * * @throws LengowException marketplace sku is required / marketplace name is required */ - protected function checkOrderData($lengowOrder) + protected function checkOrderData(LengowOrder $lengowOrder): void { if ($lengowOrder->lengowMarketplaceSku === '') { throw new LengowException(LengowMain::setLogMessage('lengow_log.exception.marketplace_sku_require')); @@ -430,9 +437,9 @@ protected function checkOrderData($lengowOrder) * * @param string $action Lengow order actions type (ship or cancel) * - * @return array + * @return array */ - protected function getMarketplaceArguments($action) + protected function getMarketplaceArguments(string $action): array { $actions = $this->getAction($action); if (isset($actions['args'], $actions['optional_args'])) { @@ -453,13 +460,13 @@ protected function getMarketplaceArguments($action) * * @param string $action Lengow order actions type (ship or cancel) * @param LengowOrder $lengowOrder Lengow order instance - * @param array $marketplaceArguments All marketplace arguments for a specific action + * @param array $marketplaceArguments All marketplace arguments for a specific action * - * @return array + * @return array * * @throws Exception|LengowException no delivery country in order */ - protected function getAllParams($action, $lengowOrder, $marketplaceArguments) + protected function getAllParams(string $action, LengowOrder $lengowOrder, array $marketplaceArguments): array { $params = []; $actions = $this->getAction($action); @@ -468,9 +475,9 @@ protected function getAllParams($action, $lengowOrder, $marketplaceArguments) // get tracking number for tracking number and tracking url $idOrderCarrier = $lengowOrder->getIdOrderCarrier(); $orderCarrier = new LengowOrderCarrier($idOrderCarrier); - $trackingNumber = $orderCarrier->tracking_number ?? ''; - $shippingMethod = $lengowOrder->getShippingMethodByPrestashopId($lengowOrder->lengowId); - $returnTrackingNumber = $orderCarrier->return_tracking_number ?? ''; + $trackingNumber = $orderCarrier->tracking_number; + $shippingMethod = $lengowOrder->getShippingMethodByPrestashopId((int) $lengowOrder->lengowId); + $returnTrackingNumber = $orderCarrier->return_tracking_number; if ($trackingNumber === '') { $trackingNumber = $lengowOrder->shipping_number ?? ''; } @@ -488,7 +495,7 @@ protected function getAllParams($action, $lengowOrder, $marketplaceArguments) if ((string) $lengowOrder->lengowCarrier !== '') { $carrierName = (string) $lengowOrder->lengowCarrier; } else { - if (!isset($deliveryAddress->id_country) || (int) $deliveryAddress->id_country === 0) { + if ((int) $deliveryAddress->id_country === 0) { if (isset($actions['optional_args']) && in_array($arg, $actions['optional_args'], true)) { break; } @@ -544,8 +551,13 @@ protected function getAllParams($action, $lengowOrder, $marketplaceArguments) case LengowAction::ARG_DELIVERY_DATE: $params[$arg] = date(LengowMain::DATE_ISO_8601); break; + case LengowAction::ARG_REFUND_REASON: case LengowAction::ARG_REASON: - $params[$arg] = $lengowOrder->getRefundReasonByPrestashopId($lengowOrder->lengowId) + $params[$arg] = $lengowOrder->getRefundReasonByPrestashopId((int) $lengowOrder->lengowId) + ?? $this->getDefaultValue((string) $arg); + break; + case LengowAction::ARG_REFUND_MODE: + $params[$arg] = $lengowOrder->getRefundModeByPrestashopId((int) $lengowOrder->lengowId) ?? $this->getDefaultValue((string) $arg); break; default: @@ -567,30 +579,26 @@ protected function getAllParams($action, $lengowOrder, $marketplaceArguments) * * @param string $action Lengow order actions type (ship or cancel) * @param LengowOrder $lengowOrder Lengow order instance - * @param array $marketplaceArguments All marketplace arguments for a specific action + * @param list $marketplaceArguments All marketplace arguments for a specific action + * @param mixed $orderLineId * - * @return array + * @return array * * @throws Exception|LengowException no delivery country in order */ - protected function getAllParamsForPartialRefund( - string $action, - LengowOrder $lengowOrder, - array $marketplaceArguments, - $orderLineId - ): array { + protected function getAllParamsForPartialRefund(string $action, LengowOrder $lengowOrder, array $marketplaceArguments, mixed $orderLineId): array + { $this->checkAction($action); if (!in_array($lengowOrder->lengowState, $this->getRefundStatuses(), true)) { throw new LengowException('refund action not available for this order_state: ' . $lengowOrder->lengowState); } $decodedExtra = json_decode($lengowOrder->lengowExtra, true, 512, JSON_THROW_ON_ERROR); - $shippingPriceTTC = $lengowOrder->getTotalShippingCostByOrderId($lengowOrder->id) - ?? 0; + $shippingPriceTTC = $lengowOrder->getTotalShippingCostByOrderId($lengowOrder->id); foreach ($marketplaceArguments as $arg) { switch ($arg) { case LengowAction::ARG_REFUND_REASON: case LengowAction::ARG_REASON: - $params[$arg] = $lengowOrder->getRefundReasonByPrestashopId($lengowOrder->lengowId) + $params[$arg] = $lengowOrder->getRefundReasonByPrestashopId((int) $lengowOrder->lengowId) ?? $this->getDefaultValue((string) $arg); break; case LengowAction::ARG_REFUND_PRICE: @@ -603,7 +611,7 @@ protected function getAllParamsForPartialRefund( $params[$arg] = $orderLineId; break; case LengowAction::ARG_REFUND_MODE: - $params[$arg] = $lengowOrder->getRefundModeByPrestashopId($lengowOrder->lengowId) + $params[$arg] = $lengowOrder->getRefundModeByPrestashopId((int) $lengowOrder->lengowId) ?? $this->getDefaultValue((string) $arg); break; case LengowAction::ARG_REFUND_SHIPPING_PRICE: @@ -624,13 +632,13 @@ protected function getAllParamsForPartialRefund( * Check required parameters and delete empty parameters * * @param string $action Lengow order actions type (ship or cancel) - * @param array $params all available values + * @param array $params all available values * - * @return array + * @return array * * @throws Exception argument is required */ - protected function checkAndCleanParams($action, $params) + protected function checkAndCleanParams(string $action, array $params): array { $actions = $this->getAction($action); if (isset($actions['args'])) { @@ -653,8 +661,10 @@ protected function checkAndCleanParams($action, $params) /** * Sync Lengow marketplaces + * + * @return void */ - public static function syncMarketplaces() + public static function syncMarketplaces(): void { self::loadApiMarketplace(); if (self::$marketplaces && !empty(self::$marketplaces)) { @@ -688,9 +698,9 @@ public static function syncMarketplaces() /** * Get marketplace counters list by country id * - * @return array + * @return array */ - public static function getMarketplaceCounters() + public static function getMarketplaceCounters(): array { $marketplaceCounters = []; try { @@ -716,9 +726,9 @@ public static function getMarketplaceCounters() * * @param int|bool $idCountry PrestaShop id country * - * @return array + * @return array */ - public static function getAllMarketplaces($idCountry = false) + public static function getAllMarketplaces($idCountry = false): array { if ($idCountry) { $sql = 'SELECT lm.id, lm.marketplace_name, lm.marketplace_label, lm.carrier_required @@ -744,9 +754,9 @@ public static function getAllMarketplaces($idCountry = false) * * @param int $idCountry PrestaShop country id * - * @return array + * @return array */ - public static function getAllMarketplaceDataByCountry($idCountry) + public static function getAllMarketplaceDataByCountry(int $idCountry): array { $marketplaceData = []; $marketplaces = self::getAllMarketplaces($idCountry); @@ -787,7 +797,7 @@ public static function getAllMarketplaceDataByCountry($idCountry) * * @return int|false */ - public static function getIdMarketplace($marketplaceName) + public static function getIdMarketplace(string $marketplaceName): int|false { try { $result = Db::getInstance()->ExecuteS( @@ -806,9 +816,9 @@ public static function getIdMarketplace($marketplaceName) * * @param string $marketplaceName Name of the marketplace * - * @return array|false + * @return array|false */ - public static function getValidShippingMethods(string $marketplaceName) + public static function getValidShippingMethods(string $marketplaceName): array|false { $idMarketplace = self::getIdMarketplace($marketplaceName); if (!$idMarketplace) { @@ -827,7 +837,7 @@ public static function getValidShippingMethods(string $marketplaceName) * * @return int|false */ - public static function insertMarketplace($marketplaceName, $marketplaceLabel, $carrierRequired) + public static function insertMarketplace(string $marketplaceName, string $marketplaceLabel, bool $carrierRequired): int|false { $db = Db::getInstance(); try { @@ -855,7 +865,7 @@ public static function insertMarketplace($marketplaceName, $marketplaceLabel, $c * * @return int|false */ - public static function updateMarketplace($idMarketplace, $marketplaceLabel, $carrierRequired) + public static function updateMarketplace(int $idMarketplace, string $marketplaceLabel, bool $carrierRequired): int|false { $db = Db::getInstance(); $success = $db->update( @@ -900,6 +910,8 @@ public function hasReturnTrackingNumber(): bool /** * Get all refund reasons choices + * + * @return array */ public function getRefundReasons(): array { @@ -914,6 +926,9 @@ public function getRefundReasons(): array if (empty($reasons)) { $reasons = in_array(LengowAction::ARG_REASON, $arguments) ? $this->argValues[LengowAction::ARG_REASON]['valid_values'] : []; } + if (empty($reasons)) { + return []; + } foreach ($reasons as $key => $reason) { $choices[$reason] = $key; } @@ -923,6 +938,8 @@ public function getRefundReasons(): array /** * Will return all refund modes for cdsicount + * + * @return array */ public function getRefundModes(): array { @@ -947,6 +964,8 @@ public function getRefundModes(): array /** * Get all refund arguments + * + * @return list */ public function getRefundArguments(): array { @@ -961,6 +980,8 @@ public function getRefundArguments(): array /** * Will return valid statuses for refund + * + * @return list */ public function getRefundStatuses(): array { diff --git a/classes/models/LengowMethod.php b/classes/models/LengowMethod.php index cb8a34a9..34134555 100755 --- a/classes/models/LengowMethod.php +++ b/classes/models/LengowMethod.php @@ -58,7 +58,7 @@ class LengowMethod * * @return int|false */ - public static function getIdMethodMarketplace($methodMarketplaceName) + public static function getIdMethodMarketplace(string $methodMarketplaceName): int|false { try { $results = Db::getInstance()->ExecuteS( @@ -85,9 +85,9 @@ public static function getIdMethodMarketplace($methodMarketplaceName) * * @param int $idMarketplace Lengow marketplace id * - * @return array + * @return array */ - public static function getAllMethodMarketplaceByIdMarketplace($idMarketplace) + public static function getAllMethodMarketplaceByIdMarketplace(int $idMarketplace): array { try { $results = Db::getInstance()->ExecuteS( @@ -114,8 +114,10 @@ public static function getAllMethodMarketplaceByIdMarketplace($idMarketplace) /** * Sync Lengow methods marketplace + * + * @return void */ - public static function syncMethodMarketplace() + public static function syncMethodMarketplace(): void { LengowMarketplace::loadApiMarketplace(); if (LengowMarketplace::$marketplaces && !empty(LengowMarketplace::$marketplaces)) { @@ -132,12 +134,11 @@ public static function syncMethodMarketplace() ); } else { $params = []; - if ($method->label !== null && Tools::strlen($method->label) > 0) { + if ($method->label !== null && mb_strlen((string) $method->label) > 0) { $params[self::FIELD_METHOD_MARKETPLACE_LABEL] = pSQL($method->label); } if (isset($method->lengow_code) - && $method->lengow_code !== null - && Tools::strlen($method->lengow_code) > 0 + && mb_strlen((string) $method->lengow_code) > 0 ) { $params[self::FIELD_METHOD_LENGOW_CODE] = pSQL($method->lengow_code); } @@ -163,13 +164,13 @@ public static function syncMethodMarketplace() * * @return int|false */ - public static function insertMethodMarketplace($methodMarketplaceName, $methodMarketplaceLabel, $methodLengowCode = null) + public static function insertMethodMarketplace(string $methodMarketplaceName, string $methodMarketplaceLabel, ?string $methodLengowCode = null): int|false { $params = [ self::FIELD_METHOD_MARKETPLACE_NAME => pSQL($methodMarketplaceName), self::FIELD_METHOD_MARKETPLACE_LABEL => pSQL($methodMarketplaceLabel), ]; - if ($methodLengowCode !== null && Tools::strlen($methodLengowCode) > 0) { + if ($methodLengowCode !== null && mb_strlen((string) $methodLengowCode) > 0) { $params[self::FIELD_METHOD_LENGOW_CODE] = pSQL($methodLengowCode); } $db = Db::getInstance(); @@ -186,11 +187,11 @@ public static function insertMethodMarketplace($methodMarketplaceName, $methodMa * Update a method marketplace * * @param int $idMethodMarketplace Lengow method marketplace id - * @param array $params all parameters to update a carrier method + * @param array $params all parameters to update a carrier method * * @return int|false */ - public static function updateMethodMarketplace($idMethodMarketplace, $params) + public static function updateMethodMarketplace(int $idMethodMarketplace, array $params): int|false { $db = Db::getInstance(); $success = $db->update(self::TABLE_METHOD_MARKETPLACE, $params, 'id = ' . (int) $idMethodMarketplace); @@ -206,7 +207,7 @@ public static function updateMethodMarketplace($idMethodMarketplace, $params) * * @return bool */ - public static function matchMethodMarketplaceWithMarketplace($idMarketplace, $idMethodMarketplace) + public static function matchMethodMarketplaceWithMarketplace(int $idMarketplace, int $idMethodMarketplace): bool { $db = Db::getInstance(); try { @@ -242,7 +243,7 @@ public static function matchMethodMarketplaceWithMarketplace($idMarketplace, $id * * @return bool */ - public static function deleteMarketplaceMethodMarketplace($idMarketplaceMethodMarketplace) + public static function deleteMarketplaceMethodMarketplace(int $idMarketplaceMethodMarketplace): bool { return Db::getInstance()->delete( self::TABLE_MARKETPLACE_METHOD_MARKETPLACE, @@ -252,8 +253,10 @@ public static function deleteMarketplaceMethodMarketplace($idMarketplaceMethodMa /** * Clean method marketplace matching for old methods + * + * @return void */ - public static function cleanMethodMarketplaceMatching() + public static function cleanMethodMarketplaceMatching(): void { LengowMarketplace::loadApiMarketplace(); if (LengowMarketplace::$marketplaces && !empty(LengowMarketplace::$marketplaces)) { @@ -300,7 +303,7 @@ public static function cleanMethodMarketplaceMatching() * * @return int|false */ - public static function getIdMarketplaceMethodCountry($idCountry, $idMarketplace, $idMethodMarketplace) + public static function getIdMarketplaceMethodCountry(int $idCountry, int $idMarketplace, int $idMethodMarketplace): int|false { try { $result = Db::getInstance()->ExecuteS( @@ -321,8 +324,10 @@ public static function getIdMarketplaceMethodCountry($idCountry, $idMarketplace, * * @param int $idMarketplace Lengow marketplace id * @param int $idMethodMarketplace Lengow method marketplace id + * + * @return void */ - public static function cleanMarketplaceMethodCountryByIdMarketplace($idMarketplace, $idMethodMarketplace) + public static function cleanMarketplaceMethodCountryByIdMarketplace(int $idMarketplace, int $idMethodMarketplace): void { try { $results = Db::getInstance()->ExecuteS( @@ -342,16 +347,16 @@ public static function cleanMarketplaceMethodCountryByIdMarketplace($idMarketpla } } - /** + /** * Get carrier id by country id, marketplace id and method marketplace label or name * * @param int $idCountry PrestaShop country id - * @param string $idMarketplace Lengow marketplace id + * @param int $idMarketplace Lengow marketplace id * @param string $methodMarketplaceName Lengow marketplace method name * * @return int|false */ - public static function getIdCarrierByMethodMarketplaceName($idCountry, $idMarketplace, $methodMarketplaceName) + public static function getIdCarrierByMethodMarketplaceName(int $idCountry, int $idMarketplace, string $methodMarketplaceName): int|false { if (!$methodMarketplaceName) { return false; @@ -390,9 +395,9 @@ public static function getIdCarrierByMethodMarketplaceName($idCountry, $idMarket * @param int $idCountry PrestaShop country id * @param int $idMarketplace Lengow marketplace id * - * @return array + * @return array */ - public static function getAllMarketplaceMethodCountryByIdMarketplace($idCountry, $idMarketplace) + public static function getAllMarketplaceMethodCountryByIdMarketplace(int $idCountry, int $idMarketplace): array { $methods = []; try { @@ -418,12 +423,12 @@ public static function getAllMarketplaceMethodCountryByIdMarketplace($idCountry, * * @param int $idCountry PrestaShop country id * @param int $idMarketplace Lengow marketplace id - * @param int $idCarrier PrestaShop carrier id + * @param int|null $idCarrier PrestaShop carrier id * @param int $idMethodMarketplace Lengow method marketplace id * * @return int|false */ - public static function insertMarketplaceMethodCountry($idCountry, $idMarketplace, $idCarrier, $idMethodMarketplace) + public static function insertMarketplaceMethodCountry(int $idCountry, int $idMarketplace, ?int $idCarrier, int $idMethodMarketplace): int|false { $params = [ self::FIELD_COUNTRY_ID => $idCountry, @@ -445,11 +450,11 @@ public static function insertMarketplaceMethodCountry($idCountry, $idMarketplace * Update a marketplace method country * * @param int $idMarketplaceMethodCountry Lengow marketplace method country id - * @param int $idCarrier PrestaShop carrier id + * @param int|null $idCarrier PrestaShop carrier id * * @return int|false */ - public static function updateMarketplaceMethodCountry($idMarketplaceMethodCountry, $idCarrier) + public static function updateMarketplaceMethodCountry(int $idMarketplaceMethodCountry, ?int $idCarrier): int|false { $db = Db::getInstance(); $success = $db->update( @@ -468,7 +473,7 @@ public static function updateMarketplaceMethodCountry($idMarketplaceMethodCountr * * @return bool */ - public static function deleteMarketplaceMethodCountry($idMarketplaceMethodCountry) + public static function deleteMarketplaceMethodCountry(int $idMarketplaceMethodCountry): bool { return Db::getInstance()->delete( self::TABLE_MARKETPLACE_METHOD_COUNTRY, diff --git a/classes/models/LengowNameParser.php b/classes/models/LengowNameParser.php index 46e53d63..9ff17404 100644 --- a/classes/models/LengowNameParser.php +++ b/classes/models/LengowNameParser.php @@ -27,82 +27,75 @@ } class LengowNameParser { - /** - * Array of possible name languages. - * - * @var array - */ - private $languages; - /** * Array of possible name titles. * - * @var array + * @var array */ - private $titles; + private array $titles; /** * Array of possible last name prefixes. * - * @var array + * @var array */ - private $prefices; + private array $prefices; /** * Array of possible name suffices. * - * @var array; + * @var array */ - private $suffices; + private array $suffices; /** * The TITLE ie. Dr., Mr. Mrs., etc... * * @var string */ - private $title; + private string $title; /** * The FIRST Name * * @var string */ - private $first; + private string $first; /** * The MIDDLE Name * * @var string */ - private $middle; + private string $middle; /** * The LAST Name * * @var string */ - private $last; + private string $last; /** * Name addendum ie. III, Sr., etc... * * @var string */ - private $suffix; + private string $suffix; /** * Full name string passed to class * * @var string */ - private $fullName; + private string $fullName; /** * Set to false by default, but set to true if parse() is executed on a name that is not parseable * * @var bool */ - private $notParseable; + private bool $notParseable; /** * File name for config parser @@ -126,11 +119,13 @@ public function __construct(string $initString = '') $this->suffix = ''; $filePath = self::getParserFilePath(); + if (!LengowMain::isPathAllowed($filePath, _PS_MODULE_LENGOW_DIR_)) { + return; + } $paramsJson = Tools::file_get_contents($filePath); $params = json_decode($paramsJson, true); // added Military Titles - $this->languages = $params['language']; $this->titles = $params['titles']; $this->prefices = $params['prefices']; @@ -214,9 +209,9 @@ public function setFullName(string $newFullName): void * Determine if the needle is in the haystack. * * @param mixed $needle the needle to look for - * @param array $haystack the haystack from which to look into + * @param array $haystack the haystack from which to look into */ - private function inArrayNorm($needle, array $haystack): bool + private function inArrayNorm(mixed $needle, array $haystack): bool { $needle = trim(strtolower(str_replace('.', '', $needle))); @@ -404,6 +399,7 @@ public function parse(): void $this->middle = $current; } } + $this->last = $pieces[0]; if (isset($pieces[2]) && $pieces[2]) { if ($this->last == '') { $this->suffix = trim($pieces[2]); @@ -416,7 +412,6 @@ public function parse(): void } } } - $this->last = $pieces[0]; break; } unset($pieces); diff --git a/classes/models/LengowOrder.php b/classes/models/LengowOrder.php index f900e0ce..d5b47e79 100644 --- a/classes/models/LengowOrder.php +++ b/classes/models/LengowOrder.php @@ -92,7 +92,7 @@ class LengowOrder extends Order public const FIELD_B2B_VALUE = 'B2B'; /** - * @const number of tries to sync order num + * @var number of tries to sync order num */ public const SYNCHRONIZE_TRIES = 5; @@ -104,142 +104,142 @@ class LengowOrder extends Order /** * @var string Lengow order record id */ - public $lengowId; + public string $lengowId = ''; /** * @var int PrestaShop shop ID */ - public $lengowIdShop; + public int $lengowIdShop = 0; /** - * @var int Lengow flux id + * @var int|null Lengow flux id */ - public $lengowIdFlux; + public ?int $lengowIdFlux = null; /** * @var int id of the delivery address */ - public $lengowDeliveryAddressId; + public int $lengowDeliveryAddressId = 0; /** * @var string ISO code for country */ - public $lengowDeliveryCountryIso; + public string $lengowDeliveryCountryIso = ''; /** * @var string Lengow order id */ - public $lengowMarketplaceSku; + public string $lengowMarketplaceSku = ''; /** * @var string marketplace's code */ - public $lengowMarketplaceName; + public string $lengowMarketplaceName = ''; /** * @var string marketplace's label */ - public $lengowMarketplaceLabel; + public string $lengowMarketplaceLabel = ''; /** * @var string current Lengow state */ - public $lengowState; + public string $lengowState = ''; /** * @var int Lengow process state (0 => error, 1 => imported, 2 => finished) */ - public $lengowProcessState; + public int $lengowProcessState = 0; /** * @var string marketplace order date */ - public $lengowOrderDate; + public string $lengowOrderDate = ''; /** * @var int number of items */ - public $lengowOrderItem; + public int $lengowOrderItem = 0; /** - * @var array order types (is_express, is_prime...) + * @var array order types (is_express, is_prime...) */ - public $lengowOrderTypes; + public array $lengowOrderTypes = []; /** * @var string order currency */ - public $lengowCurrency; + public string $lengowCurrency = ''; /** * @var float total paid on marketplace */ - public $lengowTotalPaid; + public float $lengowTotalPaid = 0.0; /** * @var string Customer vat number */ - public $lengowCustomerVatNumber; + public string $lengowCustomerVatNumber = ''; /** * @var float commission on marketplace */ - public $lengowCommission; + public float $lengowCommission = 0.0; /** * @var string the name of the customer */ - public $lengowCustomerName; + public string $lengowCustomerName = ''; /** * @var string email of the customer */ - public $lengowCustomerEmail; + public string $lengowCustomerEmail = ''; /** * @var string carrier from marketplace */ - public $lengowCarrier; + public string $lengowCarrier = ''; /** * @var string carrier Method from marketplace */ - public $lengowMethod; + public string $lengowMethod = ''; /** * @var string tracking */ - public $lengowTracking; + public string $lengowTracking = ''; /** * @var string id relay */ - public $lengowIdRelay; + public string $lengowIdRelay = ''; /** * @var bool order shipped by marketplace */ - public $lengowSentMarketplace; + public bool $lengowSentMarketplace = false; /** * @var bool order is reimported (ready to be reimported) */ - public $lengowIsReimported; + public bool $lengowIsReimported = false; /** * @var string message */ - public $lengowMessage; + public string $lengowMessage = ''; /** * @var string creation order date */ - public $lengowDateAdd; + public string $lengowDateAdd = ''; /** * @var string extra information (json node form import) */ - public $lengowExtra; + public string $lengowExtra = ''; /** * Construct a Lengow order based on PrestaShop order @@ -247,7 +247,7 @@ class LengowOrder extends Order * @param int|null $id Lengow order id * @param int|null $idLang PrestaShop id lang */ - public function __construct($id = null, $idLang = null) + public function __construct(?int $id = null, ?int $idLang = null) { parent::__construct($id, $idLang); $this->loadLengowFields(); @@ -258,7 +258,7 @@ public function __construct($id = null, $idLang = null) * * @return bool */ - protected function loadLengowFields() + protected function loadLengowFields(): bool { $query = 'SELECT lo.`id`, @@ -297,10 +297,10 @@ protected function loadLengowFields() $this->lengowIdShop = (int) $result[self::FIELD_SHOP_ID]; $this->lengowIdFlux = $result[self::FIELD_FLUX_ID]; $this->lengowDeliveryAddressId = (int) $result[self::FIELD_DELIVERY_ADDRESS_ID]; - $this->lengowDeliveryCountryIso = $result[self::FIELD_DELIVERY_COUNTRY_ISO]; + $this->lengowDeliveryCountryIso = $result[self::FIELD_DELIVERY_COUNTRY_ISO] ?? ''; $this->lengowMarketplaceSku = $result[self::FIELD_MARKETPLACE_SKU]; - $this->lengowMarketplaceName = $result[self::FIELD_MARKETPLACE_NAME]; - $this->lengowMarketplaceLabel = $result[self::FIELD_MARKETPLACE_LABEL]; + $this->lengowMarketplaceName = $result[self::FIELD_MARKETPLACE_NAME] ?? ''; + $this->lengowMarketplaceLabel = $result[self::FIELD_MARKETPLACE_LABEL] ?? ''; $this->lengowState = $result[self::FIELD_ORDER_LENGOW_STATE]; $this->lengowProcessState = (int) $result[self::FIELD_ORDER_PROCESS_STATE]; $this->lengowOrderDate = $result[self::FIELD_ORDER_DATE]; @@ -308,23 +308,21 @@ protected function loadLengowFields() $this->lengowOrderTypes = $result[self::FIELD_ORDER_TYPES] !== null ? json_decode($result[self::FIELD_ORDER_TYPES], true) : []; - $this->lengowCurrency = $result[self::FIELD_CURRENCY]; - $this->lengowTotalPaid = $result[self::FIELD_TOTAL_PAID]; - $this->lengowCustomerVatNumber = $result[self::FIELD_CUSTOMER_VAT_NUMBER] !== null - ? $result[self::FIELD_CUSTOMER_VAT_NUMBER] - : ''; - $this->lengowCommission = $result[self::FIELD_COMMISSION]; - $this->lengowCustomerName = $result[self::FIELD_CUSTOMER_NAME]; - $this->lengowCustomerEmail = $result[self::FIELD_CUSTOMER_EMAIL]; - $this->lengowCarrier = $result[self::FIELD_CARRIER]; - $this->lengowMethod = $result[self::FIELD_CARRIER_METHOD]; - $this->lengowTracking = $result[self::FIELD_CARRIER_TRACKING]; - $this->lengowIdRelay = $result[self::FIELD_CARRIER_RELAY_ID]; + $this->lengowCurrency = $result[self::FIELD_CURRENCY] ?? ''; + $this->lengowTotalPaid = (float) ($result[self::FIELD_TOTAL_PAID] ?? 0.0); + $this->lengowCustomerVatNumber = $result[self::FIELD_CUSTOMER_VAT_NUMBER] ?? ''; + $this->lengowCommission = (float) ($result[self::FIELD_COMMISSION] ?? 0.0); + $this->lengowCustomerName = $result[self::FIELD_CUSTOMER_NAME] ?? ''; + $this->lengowCustomerEmail = $result[self::FIELD_CUSTOMER_EMAIL] ?? ''; + $this->lengowCarrier = $result[self::FIELD_CARRIER] ?? ''; + $this->lengowMethod = $result[self::FIELD_CARRIER_METHOD] ?? ''; + $this->lengowTracking = $result[self::FIELD_CARRIER_TRACKING] ?? ''; + $this->lengowIdRelay = $result[self::FIELD_CARRIER_RELAY_ID] ?? ''; $this->lengowSentMarketplace = (bool) $result[self::FIELD_SENT_MARKETPLACE]; $this->lengowIsReimported = (bool) $result[self::FIELD_IS_REIMPORTED]; - $this->lengowMessage = $result[self::FIELD_MESSAGE]; + $this->lengowMessage = $result[self::FIELD_MESSAGE] ?? ''; $this->lengowDateAdd = $result[self::FIELD_CREATED_AT]; - $this->lengowExtra = $result[self::FIELD_EXTRA]; + $this->lengowExtra = $result[self::FIELD_EXTRA] ?? ''; return true; } @@ -337,11 +335,11 @@ protected function loadLengowFields() * * @param string $marketplaceSku Lengow order id * @param string $marketplace marketplace name - * @param string $marketplaceLegacy old marketplace name for v2 compatibility + * @param string|null $marketplaceLegacy old marketplace name for v2 compatibility * * @return int|false */ - public static function getOrderIdFromLengowOrders($marketplaceSku, $marketplace, $marketplaceLegacy) + public static function getOrderIdFromLengowOrders(string $marketplaceSku, string $marketplace, ?string $marketplaceLegacy): int|false { // v2 compatibility $in = ( @@ -375,7 +373,7 @@ public static function getOrderIdFromLengowOrders($marketplaceSku, $marketplace, * * @return int|false */ - public static function getIdFromLengowOrders($marketplaceSku, $marketplace) + public static function getIdFromLengowOrders(string $marketplaceSku, string $marketplace): int|false { $query = 'SELECT `id` FROM `' . _DB_PREFIX_ . 'lengow_orders` WHERE `' . self::FIELD_MARKETPLACE_SKU . '` = "' . pSQL($marketplaceSku) . '" @@ -396,7 +394,7 @@ public static function getIdFromLengowOrders($marketplaceSku, $marketplace) * * @return bool */ - public static function isFromLengow($idOrder) + public static function isFromLengow(int $idOrder): bool { $query = 'SELECT `marketplace_sku` FROM `' . _DB_PREFIX_ . 'lengow_orders` @@ -418,7 +416,7 @@ public static function isFromLengow($idOrder) * * @return int|false */ - public static function getIdFromLengowDeliveryAddress($idOrder, $deliveryAddressId) + public static function getIdFromLengowDeliveryAddress(int $idOrder, int $deliveryAddressId): int|false { $query = 'SELECT `id` FROM `' . _DB_PREFIX_ . 'lengow_orders` WHERE `id_order` = \'' . (int) $idOrder . '\' @@ -437,9 +435,9 @@ public static function getIdFromLengowDeliveryAddress($idOrder, $deliveryAddress * @param string $marketplaceSku Lengow order id * @param string $marketplace marketplace name * - * @return array + * @return array */ - public static function getAllOrderIdsFromLengowOrder($marketplaceSku, $marketplace) + public static function getAllOrderIdsFromLengowOrder(string $marketplaceSku, string $marketplace): array { $query = 'SELECT `id_order` FROM `' . _DB_PREFIX_ . 'lengow_orders` WHERE `marketplace_sku` = \'' . pSQL($marketplaceSku) . '\' @@ -458,9 +456,9 @@ public static function getAllOrderIdsFromLengowOrder($marketplaceSku, $marketpla * @param string $marketplaceSku Lengow order id * @param string $marketplace marketplace name * - * @return array + * @return array */ - public static function getAllLengowOrders($marketplaceSku, $marketplace) + public static function getAllLengowOrders(string $marketplaceSku, string $marketplace): array { $query = 'SELECT * FROM `' . _DB_PREFIX_ . 'lengow_orders` WHERE `marketplace_sku` = \'' . pSQL($marketplaceSku) . '\' @@ -476,11 +474,11 @@ public static function getAllLengowOrders($marketplaceSku, $marketplace) * Update order Lengow * * @param int $id Id of the record - * @param array $params Fields update + * @param array $params Fields update * * @return bool */ - public static function updateOrderLengow($id, $params) + public static function updateOrderLengow(int $id, array $params): bool { return Db::getInstance()->update(self::TABLE_ORDER, $params, '`id` = \'' . (int) $id . '\''); } @@ -495,7 +493,7 @@ public static function updateOrderLengow($id, $params) * * @throws Exception */ - public function updateState($orderStateLengow, $packageData) + public function updateState(string $orderStateLengow, mixed $packageData): string|false { $orderProcessState = self::getOrderProcessState($orderStateLengow); $trackingNumber = !empty($packageData->delivery->trackings) @@ -565,7 +563,7 @@ public function updateState($orderStateLengow, $packageData) * * @return int|false */ - public function cancelAndreImportOrder() + public function cancelAndreImportOrder(): int|false { if (!$this->isReimported()) { return false; @@ -589,8 +587,8 @@ public function cancelAndreImportOrder() } } // in the event of an error, all new order errors are finished and the order is reset - LengowOrderError::finishOrderLogs($this->lengowId); - self::updateOrderLengow($this->lengowId, [self::FIELD_IS_REIMPORTED => 0]); + LengowOrderError::finishOrderLogs((int) $this->lengowId); + self::updateOrderLengow((int) $this->lengowId, [self::FIELD_IS_REIMPORTED => 0]); return false; } @@ -600,7 +598,7 @@ public function cancelAndreImportOrder() * * @return bool */ - public function isReimported() + public function isReimported(): bool { $query = 'UPDATE ' . _DB_PREFIX_ . 'lengow_orders SET `is_reimported` = 1 @@ -611,22 +609,24 @@ public function isReimported() /** * Sets order state to Lengow technical error + * + * @return void */ - public function setStateToError() + public function setStateToError(): void { $idErrorLengowState = LengowMain::getLengowErrorStateId(); // update order to Lengow error state if not already updated if ($idErrorLengowState && (int) $this->getCurrentState() !== $idErrorLengowState) { - $this->setCurrentState($idErrorLengowState, Context::getContext()->employee->id); + $this->setCurrentState($idErrorLengowState, LengowContext::getContext()->employee->id); } } /** * Get all unset orders * - * @return array|false + * @return array|false */ - public static function getUnsentOrders() + public static function getUnsentOrders(): array|false { $date = date(LengowMain::DATE_FULL, strtotime('-5 days', time())); $sql = 'SELECT lo.`id`, oh.`id_order_state`, oh.`id_order` @@ -675,7 +675,7 @@ public static function getUnsentOrders() * * @return bool */ - public function synchronizeOrder($connector = null, $logOutput = false) + public function synchronizeOrder(?LengowConnector $connector = null, bool $logOutput = false): bool { list($accountId, $accessToken, $secretToken) = LengowConfiguration::getAccessIds(); // get connector @@ -748,7 +748,7 @@ public function synchronizeOrder($connector = null, $logOutput = false) * * @return bool */ - public function checkAndChangeMarketplaceName($connector = null, $logOutput = false) + public function checkAndChangeMarketplaceName(?LengowConnector $connector = null, bool $logOutput = false): bool { list($accountId, $accessToken, $secretToken) = LengowConfiguration::getAccessIds(); // get connector @@ -810,7 +810,7 @@ public function checkAndChangeMarketplaceName($connector = null, $logOutput = fa * * @return string|null */ - public function getCurrentStateName() + public function getCurrentStateName(): ?string { try { $idLang = Language::getIdByIso(LengowTranslation::ISO_CODE_EN) ?: Configuration::get('PS_LANG_DEFAULT'); @@ -827,7 +827,7 @@ public function getCurrentStateName() * * @return string|null */ - public function getCurrentCarrierName() + public function getCurrentCarrierName(): ?string { // get delivery address for carrier, shipping method and tracking url $deliveryAddress = new Address($this->id_address_delivery); @@ -846,7 +846,7 @@ public function getCurrentCarrierName() * * @return string|null */ - public function getCurrentTrackingNumber() + public function getCurrentTrackingNumber(): ?string { try { $orderCarrier = new LengowOrderCarrier($this->getIdOrderCarrier()); @@ -866,7 +866,7 @@ public function getCurrentTrackingNumber() * * @return string|null */ - public function getCurrentTrackingUrl() + public function getCurrentTrackingUrl(): ?string { // get tracking number $trackingNumber = $this->getCurrentTrackingNumber(); @@ -891,7 +891,7 @@ public function getCurrentTrackingUrl() * * @return bool */ - public function hasAnActionInProgress() + public function hasAnActionInProgress(): bool { return (bool) LengowAction::getActionsByOrderId($this->id, true, null, false); } @@ -901,9 +901,9 @@ public function hasAnActionInProgress() * * @param string $state state to be matched * - * @return int + * @return int|false */ - public static function getOrderProcessState($state) + public static function getOrderProcessState(string $state): int|false { switch ($state) { case self::STATE_ACCEPTED: @@ -925,9 +925,9 @@ public static function getOrderProcessState($state) * * @param int $idOrderLengow Lengow order id * - * @return bool + * @return array|false */ - public static function find($idOrderLengow) + public static function find(int $idOrderLengow): array|false { $sql = 'SELECT * FROM `' . _DB_PREFIX_ . 'lengow_orders` WHERE id = ' . (int) $idOrderLengow; @@ -941,7 +941,7 @@ public static function find($idOrderLengow) * * @return bool */ - public static function isOrderImport($idOrderLengow) + public static function isOrderImport(int $idOrderLengow): bool { $sql = 'SELECT id_order FROM `' . _DB_PREFIX_ . 'lengow_orders` WHERE id = ' . (int) $idOrderLengow; try { @@ -958,9 +958,9 @@ public static function isOrderImport($idOrderLengow) * * @param int $idOrderLengow Lengow order id * - * @return array|false + * @return array|false */ - public static function reImportOrder($idOrderLengow) + public static function reImportOrder(int $idOrderLengow): array|false { if (self::isOrderImport($idOrderLengow)) { Db::getInstance()->Execute( @@ -988,7 +988,7 @@ public static function reImportOrder($idOrderLengow) * * @return bool */ - public function canReSendOrder() + public function canReSendOrder(): bool { $orderActions = LengowAction::getActionsByOrderId((int) $this->id, true); if ($orderActions) { @@ -1013,7 +1013,7 @@ public function canReSendOrder() * * @return bool */ - public static function reSendOrder($idOrderLengow) + public static function reSendOrder(int $idOrderLengow): bool { if (self::isOrderImport($idOrderLengow)) { $lengowOrder = self::find($idOrderLengow); @@ -1040,7 +1040,7 @@ public static function reSendOrder($idOrderLengow) * * @return LengowMarketplace|null */ - public function getMarketPlace() + public function getMarketPlace(): ?LengowMarketplace { return LengowMain::getMarketplaceSingleton( $this->lengowMarketplaceName @@ -1051,10 +1051,11 @@ public function getMarketPlace() * Send Order action * * @param string $action Lengow Actions type (ship or cancel) + * @param mixed $partialAction * * @return bool */ - public function callAction($action, $partialAction = false) + public function callAction(string $action, mixed $partialAction = false): bool { $success = true; LengowMain::log( @@ -1079,7 +1080,7 @@ public function callAction($action, $partialAction = false) } if ($success) { // finish all order logs send - LengowOrderError::finishOrderLogs($this->lengowId, LengowOrderError::TYPE_ERROR_SEND); + LengowOrderError::finishOrderLogs((int) $this->lengowId, LengowOrderError::TYPE_ERROR_SEND); try { // compatibility V2 if ($this->lengowIdFlux !== null) { @@ -1120,7 +1121,7 @@ public function callAction($action, $partialAction = false) } if (isset($errorMessage)) { if ($this->lengowProcessState !== self::PROCESS_STATE_FINISH) { - LengowOrderError::addOrderLog($this->lengowId, $errorMessage, LengowOrderError::TYPE_ERROR_SEND); + LengowOrderError::addOrderLog((int) $this->lengowId, $errorMessage, LengowOrderError::TYPE_ERROR_SEND); } $decodedMessage = LengowMain::decodeLogMessage($errorMessage, LengowTranslation::DEFAULT_ISO_CODE); LengowMain::log( @@ -1160,9 +1161,9 @@ public function callAction($action, $partialAction = false) /** * Get order line by API * - * @return array|false + * @return array|false */ - public function getOrderLineByApi() + public function getOrderLineByApi(): array|false { $orderLines = []; $results = LengowConnector::queryApi( @@ -1199,7 +1200,7 @@ public function getOrderLineByApi() * * @return bool */ - public function isExpress() + public function isExpress(): bool { return isset($this->lengowOrderTypes[self::TYPE_EXPRESS]) || isset($this->lengowOrderTypes[self::TYPE_PRIME]); } @@ -1209,7 +1210,7 @@ public function isExpress() * * @return bool */ - public function isBusiness() + public function isBusiness(): bool { if (isset($this->lengowOrderTypes[self::TYPE_BUSINESS])) { return true; @@ -1246,7 +1247,7 @@ public function isBusiness() * * @return bool */ - public function isDeliveredByMarketplace() + public function isDeliveredByMarketplace(): bool { return isset($this->lengowOrderTypes[self::TYPE_DELIVERED_BY_MARKETPLACE]) || $this->lengowSentMarketplace; } @@ -1256,7 +1257,7 @@ public function isDeliveredByMarketplace() * * @return int */ - public static function countOrderImportedByLengow() + public static function countOrderImportedByLengow(): int { $sql = 'SELECT COUNT(*) as total FROM ' . _DB_PREFIX_ . 'lengow_orders WHERE id_order IS NOT NULL'; $row = Db::getInstance()->getRow($sql); @@ -1269,7 +1270,7 @@ public static function countOrderImportedByLengow() * * @return int */ - public static function countOrderWithError() + public static function countOrderWithError(): int { $sql = ' SELECT COUNT(DISTINCT lo.id) as total FROM ' . _DB_PREFIX_ . 'lengow_orders as lo @@ -1286,7 +1287,7 @@ public static function countOrderWithError() * * @return int */ - public static function countOrderToBeSent() + public static function countOrderToBeSent(): int { $sql = 'SELECT COUNT(*) as total FROM ' . _DB_PREFIX_ . 'lengow_orders WHERE order_process_state = 1'; $row = Db::getInstance()->getRow($sql); @@ -1301,7 +1302,7 @@ public static function countOrderToBeSent() * * @return string|null */ - public static function getRefundReasonByPrestashopId($idOrder): ?string + public static function getRefundReasonByPrestashopId(int $idOrder): ?string { $query = 'SELECT * FROM `' . _DB_PREFIX_ . 'lengow_orders` WHERE `id` = ' . (int) $idOrder; try { @@ -1320,7 +1321,7 @@ public static function getRefundReasonByPrestashopId($idOrder): ?string * * @return string|null */ - public static function getRefundModeByPrestashopId($idOrder): ?string + public static function getRefundModeByPrestashopId(int $idOrder): ?string { $query = 'SELECT * FROM `' . _DB_PREFIX_ . 'lengow_orders` WHERE `id` = ' . (int) $idOrder; try { @@ -1339,7 +1340,7 @@ public static function getRefundModeByPrestashopId($idOrder): ?string * * @return float|false Returns the total shipping cost amount or false on failure */ - public static function getTotalShippingCostByOrderId($orderId) + public static function getTotalShippingCostByOrderId(int $orderId): float|false { $query = 'SELECT SUM(os.shipping_cost_amount) AS total_shipping_cost FROM `' . _DB_PREFIX_ . 'order_slip` os @@ -1354,7 +1355,13 @@ public static function getTotalShippingCostByOrderId($orderId) } } - public function getRefundDataFromLengowOrder(int $orderId, $marketplaceName): array + /** + * @param int $orderId + * @param string $marketplaceName + * + * @return array + */ + public function getRefundDataFromLengowOrder(int $orderId, string $marketplaceName): array { $db = Db::getInstance(); $sql = 'SELECT refund_reason, refund_mode @@ -1380,9 +1387,11 @@ public function getRefundDataFromLengowOrder(int $orderId, $marketplaceName): ar /** * Return the Lengow orders from PrestaShop order id * - * @return int + * @param int $idOrder PrestaShop order id + * + * @return array|null */ - public static function getLengowOrderByPrestashopId($idOrder) + public static function getLengowOrderByPrestashopId(int $idOrder): ?array { $query = 'SELECT * FROM `' . _DB_PREFIX_ . 'lengow_orders` WHERE `id_order` = ' . (int) $idOrder; try { @@ -1401,7 +1410,7 @@ public static function getLengowOrderByPrestashopId($idOrder) * * @return string|null */ - public static function getShippingMethodByPrestashopId($idOrder) + public static function getShippingMethodByPrestashopId(int $idOrder): ?string { $query = 'SELECT * FROM `' . _DB_PREFIX_ . 'lengow_orders` WHERE `id` = ' . (int) $idOrder; try { diff --git a/classes/models/LengowOrderCarrier.php b/classes/models/LengowOrderCarrier.php index daa9c2e0..479b67f5 100644 --- a/classes/models/LengowOrderCarrier.php +++ b/classes/models/LengowOrderCarrier.php @@ -27,18 +27,18 @@ class LengowOrderCarrier extends OrderCarrier { /** @var string */ - public $return_tracking_number; + public string $return_tracking_number = ''; /** @var string */ - public $return_carrier; + public string $return_carrier = ''; /** - * @param type $id - * @param type $id_lang - * @param type $id_shop - * @param type $translator + * @param int|null $id + * @param int|null $id_lang + * @param int|null $id_shop + * @param mixed $translator */ - public function __construct($id = null, $id_lang = null, $id_shop = null, $translator = null) + public function __construct(?int $id = null, ?int $id_lang = null, ?int $id_shop = null, mixed $translator = null) { parent::__construct($id, $id_lang, $id_shop, $translator); diff --git a/classes/models/LengowOrderDetail.php b/classes/models/LengowOrderDetail.php index 9563e448..79e7031b 100755 --- a/classes/models/LengowOrderDetail.php +++ b/classes/models/LengowOrderDetail.php @@ -34,7 +34,7 @@ class LengowOrderDetail extends OrderDetail * * @return int */ - public static function findByOrderIdProductId($idOrder, $idProduct) + public static function findByOrderIdProductId(int $idOrder, $idProduct): int { $whereArr = [ '`id_order`=' . (int) $idOrder, @@ -59,43 +59,39 @@ public static function findByOrderIdProductId($idOrder, $idProduct) /** * @param string $returnTrackingNumber * @param int $orderId + * + * @return void */ - public static function updateOrderReturnTrackingNumber($returnTrackingNumber, $orderId) + public static function updateOrderReturnTrackingNumber(string $returnTrackingNumber, int $orderId): void { - try { - $returnTrackingNumber = pSQL($returnTrackingNumber); - $order = new Order($orderId); - $orderCarrier = new LengowOrderCarrier((int) $order->getIdOrderCarrier()); - $orderCarrier->return_tracking_number = $returnTrackingNumber; - $orderCarrier->update(); - } catch (Exception $e) { - LengowOrderError::addOrderLog( - $orderId, - '[PrestaShop error]: ' . $e->getMessage(), - LengowOrderError::TYPE_ERROR_SEND - ); + $idOrderCarrier = self::getIdOrderCarrier($orderId); + if (!$idOrderCarrier) { + return; } + Db::getInstance()->update( + 'order_carrier', + ['return_tracking_number' => pSQL($returnTrackingNumber)], + 'id_order_carrier = ' . $idOrderCarrier + ); } /** - * @param string $returnTrackingNumber + * @param string $returnCarrier * @param int $orderId + * + * @return void */ - public static function updateOrderReturnCarrier($returnCarrier, $orderId) + public static function updateOrderReturnCarrier(string $returnCarrier, int $orderId): void { - try { - $returnCarrier = pSQL($returnCarrier); - $order = new Order($orderId); - $orderCarrier = new LengowOrderCarrier((int) $order->getIdOrderCarrier()); - $orderCarrier->return_carrier = $returnCarrier; - $orderCarrier->update(); - } catch (Exception $e) { - LengowOrderError::addOrderLog( - $orderId, - '[PrestaShop error]: ' . $e->getMessage(), - LengowOrderError::TYPE_ERROR_SEND - ); + $idOrderCarrier = self::getIdOrderCarrier($orderId); + if (!$idOrderCarrier) { + return; } + Db::getInstance()->update( + 'order_carrier', + ['return_carrier' => pSQL($returnCarrier)], + 'id_order_carrier = ' . $idOrderCarrier + ); } /** @@ -103,22 +99,17 @@ public static function updateOrderReturnCarrier($returnCarrier, $orderId) * * @return string */ - public static function getOrderReturnTrackingNumber($orderId) + public static function getOrderReturnTrackingNumber(int $orderId): string { - try { - $order = new Order($orderId); - $orderCarrier = new LengowOrderCarrier((int) $order->getIdOrderCarrier()); - - return (string) $orderCarrier->return_tracking_number; - } catch (Exception $e) { - LengowOrderError::addOrderLog( - $orderId, - '[PrestaShop error]: ' . $e->getMessage(), - LengowOrderError::TYPE_ERROR_SEND - ); + $idOrderCarrier = self::getIdOrderCarrier($orderId); + if (!$idOrderCarrier) { + return ''; } + $result = Db::getInstance()->getValue( + 'SELECT return_tracking_number FROM ' . _DB_PREFIX_ . 'order_carrier WHERE id_order_carrier = ' . $idOrderCarrier + ); - return ''; + return $result !== false ? (string) $result : ''; } /** @@ -126,22 +117,31 @@ public static function getOrderReturnTrackingNumber($orderId) * * @return string */ - public static function getOrderReturnCarrier($orderId) + public static function getOrderReturnCarrier(int $orderId): string { - try { - $order = new Order($orderId); - $orderCarrier = new LengowOrderCarrier((int) $order->getIdOrderCarrier()); - - return (string) $orderCarrier->return_carrier; - } catch (Exception $e) { - LengowOrderError::addOrderLog( - $orderId, - '[PrestaShop error]: ' . $e->getMessage(), - LengowOrderError::TYPE_ERROR_SEND - ); + $idOrderCarrier = self::getIdOrderCarrier($orderId); + if (!$idOrderCarrier) { + return ''; } + $result = Db::getInstance()->getValue( + 'SELECT return_carrier FROM ' . _DB_PREFIX_ . 'order_carrier WHERE id_order_carrier = ' . $idOrderCarrier + ); - return ''; + return $result !== false ? (string) $result : ''; + } + + /** + * @param int $orderId + * + * @return int + */ + private static function getIdOrderCarrier(int $orderId): int + { + $result = Db::getInstance()->getValue( + 'SELECT id_order_carrier FROM ' . _DB_PREFIX_ . 'order_carrier WHERE id_order = ' . $orderId . ' ORDER BY id_order_carrier DESC' + ); + + return $result !== false ? (int) $result : 0; } /** @@ -149,12 +149,12 @@ public static function getOrderReturnCarrier($orderId) * * @return string */ - public static function getOrderReturnCarrierName($orderId) + public static function getOrderReturnCarrierName(int $orderId): string { try { $order = new Order($orderId); $orderCarrier = new LengowOrderCarrier((int) $order->getIdOrderCarrier()); - $carrier = new LengowCarrier($orderCarrier->return_carrier); + $carrier = new LengowCarrier((int) $orderCarrier->return_carrier); return (string) $carrier->name; } catch (Exception $e) { diff --git a/classes/models/LengowOrderError.php b/classes/models/LengowOrderError.php index 89c647be..03310200 100644 --- a/classes/models/LengowOrderError.php +++ b/classes/models/LengowOrderError.php @@ -51,7 +51,7 @@ class LengowOrderError * * @return bool */ - public static function lengowOrderIsInError($idLengowOrder) + public static function lengowOrderIsInError(int $idLengowOrder): bool { $query = 'SELECT lli.id FROM ' . _DB_PREFIX_ . 'lengow_logs_import lli LEFT JOIN ' . _DB_PREFIX_ . 'lengow_orders lo ON lli.id_order_lengow = lo.id @@ -72,9 +72,9 @@ public static function lengowOrderIsInError($idLengowOrder) * @param string $marketplaceName Lengow marketplace name * @param int $type order log type (import or send) * - * @return array|false + * @return array|false */ - public static function getLastImportLogNotFinished($marketplaceSku, $marketplaceName, $type = self::TYPE_ERROR_IMPORT) + public static function getLastImportLogNotFinished(string $marketplaceSku, string $marketplaceName, int $type = self::TYPE_ERROR_IMPORT): array|false { // check if log already exists for the given order id $query = 'SELECT lli.`message`, lli.`date` FROM `' . _DB_PREFIX_ . 'lengow_logs_import` lli @@ -90,13 +90,13 @@ public static function getLastImportLogNotFinished($marketplaceSku, $marketplace /** * Check if log already exists for the given order * - * @param string $idOrderLengow Lengow order id + * @param int $idOrderLengow Lengow order id * @param int|null $type order log type (import or send) * @param bool|null $finished log finished (true or false) * - * @return array|false + * @return array|false */ - public static function getOrderLogs($idOrderLengow, $type = null, $finished = null) + public static function getOrderLogs(int $idOrderLengow, ?int $type = null, ?bool $finished = null): array|false { $andType = $type !== null ? ' AND `type` = \'' . $type . '\'' : ''; $andFinished = ''; @@ -119,12 +119,12 @@ public static function getOrderLogs($idOrderLengow, $type = null, $finished = nu * * @param int $idOrderLengow Lengow order id * @param string $message error message - * @param string $type order log type (import or send) + * @param int $type order log type (import or send) * @param int $finished error is finished * * @return bool */ - public static function addOrderLog($idOrderLengow, $message = '', $type = self::TYPE_ERROR_IMPORT, $finished = 0) + public static function addOrderLog(int $idOrderLengow, string $message = '', int $type = self::TYPE_ERROR_IMPORT, int $finished = 0): bool { try { return Db::getInstance()->insert( @@ -146,11 +146,11 @@ public static function addOrderLog($idOrderLengow, $message = '', $type = self:: * Removes all order logs * * @param int $idOrderLengow Lengow order id - * @param string $type order log type (import or send) + * @param int $type order log type (import or send) * * @return bool */ - public static function finishOrderLogs($idOrderLengow, $type = self::TYPE_ERROR_IMPORT) + public static function finishOrderLogs(int $idOrderLengow, int $type = self::TYPE_ERROR_IMPORT): bool { $query = 'SELECT `id` FROM `' . _DB_PREFIX_ . 'lengow_logs_import` WHERE `id_order_lengow` = \'' . (int) $idOrderLengow . '\' @@ -178,9 +178,9 @@ public static function finishOrderLogs($idOrderLengow, $type = self::TYPE_ERROR_ /** * Get all order errors not yet sent by email * - * @return array + * @return array */ - public static function getAllOrderLogsNotSent() + public static function getAllOrderLogsNotSent(): array { try { $sqlLogs = 'SELECT lo.`marketplace_sku`, lli.`message`, lli.`id` @@ -204,7 +204,7 @@ public static function getAllOrderLogsNotSent() * * @return bool */ - public static function logSent($idOrderLog) + public static function logSent(int $idOrderLog): bool { try { return Db::getInstance()->update( diff --git a/classes/models/LengowOrderLine.php b/classes/models/LengowOrderLine.php index 19152901..8d0d4580 100644 --- a/classes/models/LengowOrderLine.php +++ b/classes/models/LengowOrderLine.php @@ -42,9 +42,9 @@ class LengowOrderLine * * @param int $idOrder PrestaShop order id * - * @return array + * @return array */ - public static function findOrderLineIds($idOrder) + public static function findOrderLineIds(int $idOrder): array { $sql = 'SELECT id_order_line FROM `' . _DB_PREFIX_ . 'lengow_order_line` WHERE id_order = ' . (int) $idOrder; @@ -60,7 +60,7 @@ public static function findOrderLineIds($idOrder) * * @param int $idOrderDetail PrestaShop order detail id * - * @return array + * @return array */ public static function findOrderLineByOrderDetailId(int $idOrderDetail): array { @@ -78,7 +78,7 @@ public static function findOrderLineByOrderDetailId(int $idOrderDetail): array * * @param string $idOrderLine Lengow order line id * - * @return array + * @return array */ public static function findOrderLineByOrderLineIdAndOrderId(string $idOrderLine, int $idOrder): array { @@ -106,7 +106,7 @@ public static function findOrderLineByOrderLineIdAndOrderId(string $idOrderLine, * * @return bool */ - public static function setRefunded(int $idOrderDetail, $idOrderLine, int $cancelQuantity) + public static function setRefunded(int $idOrderDetail, string $idOrderLine, int $cancelQuantity): bool { $sql = 'UPDATE `' . _DB_PREFIX_ . self::TABLE_ORDER_LINE . '` SET refunded = 1, quantity_refunded = ' . (int) $cancelQuantity . ' @@ -128,7 +128,7 @@ public static function setRefunded(int $idOrderDetail, $idOrderLine, int $cancel * * @return int|null */ - public static function getQuantityRefunded($idOrderLine) + public static function getQuantityRefunded(string $idOrderLine): ?int { $sql = 'SELECT quantity_refunded FROM `' . _DB_PREFIX_ . self::TABLE_ORDER_LINE . '` WHERE id_order_line = "' . pSQL($idOrderLine) . '"'; diff --git a/classes/models/LengowPaymentModule.php b/classes/models/LengowPaymentModule.php index 1a359a30..970e56fb 100755 --- a/classes/models/LengowPaymentModule.php +++ b/classes/models/LengowPaymentModule.php @@ -39,35 +39,28 @@ class LengowPaymentModule extends PaymentModule * @param int $idOrderState PrestaShop order state id * @param string $paymentMethod name of the payment method * @param string $message order message - * @param array $lengowProducts list of Lengow products + * @param array $lengowProducts list of Lengow products * @param float $lengowShippingCosts order shipping costs * @param float $processingFees order processing fees - * @param string $lengowTrackingNumber Lengow carrier tracking number + * @param string|null $lengowTrackingNumber Lengow carrier tracking number * @param int $idOrderLengow id of the record Lengow order table * @param string $orderStateLengow Lengow order state * @param string $marketplaceSku id lengow of current order * @param bool $logOutput display log messages * - * @return array + * @return array * * @throws Exception|LengowException cannot load order status / payment module not active / cart cannot be loaded * delivery country not active / product is not listed / unable to save order * unable to save order payment / order creation failed */ - public function makeOrder($idCart, $idOrderState, $paymentMethod, $message, $lengowProducts, $lengowShippingCosts, $processingFees, $lengowTrackingNumber, $idOrderLengow, $orderStateLengow, $marketplaceSku, $logOutput) + public function makeOrder(int $idCart, int $idOrderState, string $paymentMethod, string $message, array $lengowProducts, float $lengowShippingCosts, float $processingFees, ?string $lengowTrackingNumber, int $idOrderLengow, string $orderStateLengow, string $marketplaceSku, bool $logOutput): array { - if (!isset($this->context)) { - $this->context = Context::getContext(); - } $this->context->cart = new Cart($idCart); $this->context->customer = new Customer($this->context->cart->id_customer); // the tax cart is loaded before the customer so re-cache the tax calculation method - if (method_exists($this->context->cart, 'setTaxCalculationMethod')) { - $this->context->cart->setTaxCalculationMethod(); - } - if (method_exists(new ShopUrl(), 'resetMainDomainCache')) { - ShopUrl::resetMainDomainCache(); - } + $this->context->cart->setTaxCalculationMethod(); + ShopUrl::resetMainDomainCache(); $idCurrency = (int) $this->context->cart->id_currency; $this->context->currency = new Currency($idCurrency, null, $this->context->shop->id); @@ -100,7 +93,7 @@ public function makeOrder($idCart, $idOrderState, $paymentMethod, $message, $len // force carrier to be the one chosen in Lengow config $carrierOptions = explode(',', $key); foreach ($carrierOptions as $c) { - if ($c === $this->context->cart->id_carrier) { + if ((int) $c === (int) $this->context->cart->id_carrier) { $cartDeliveryOption[$idAddress] = $key; $carrierAssigned = true; break; @@ -128,7 +121,6 @@ public function makeOrder($idCart, $idOrderState, $paymentMethod, $message, $len $this->currentOrderReference = $reference; - $orderCreationFailed = false; if ($cartDeliveryOption) { foreach ($cartDeliveryOption as $idAddress => $keyCarriers) { foreach ($deliveryOptionList[$idAddress][$keyCarriers]['carrier_list'] as $idCarrier => $data) { @@ -138,13 +130,11 @@ public function makeOrder($idCart, $idOrderState, $paymentMethod, $message, $len $idCarrier = $this->context->cart->id_carrier; } // rewrite the id_warehouse - if (method_exists($this->context->cart, 'getPackageIdWarehouse')) { - $idWarehouse = (int) $this->context->cart->getPackageIdWarehouse( - $packageList[$idAddress][$idPackage], - (int) $idCarrier - ); - $packageList[$idAddress][$idPackage]['id_warehouse'] = $idWarehouse; - } + $idWarehouse = (int) $this->context->cart->getPackageIdWarehouse( + $packageList[$idAddress][$idPackage], + (int) $idCarrier + ); + $packageList[$idAddress][$idPackage]['id_warehouse'] = $idWarehouse; $packageList[$idAddress][$idPackage]['id_carrier'] = $idCarrier; } } @@ -185,11 +175,11 @@ public function makeOrder($idCart, $idOrderState, $paymentMethod, $message, $len $order->secure_key = pSQL($this->context->customer->secure_key); $order->payment = $paymentMethod; - if (isset($this->name)) { + if ($this->name !== '') { $order->module = $this->name; } $order->recyclable = $this->context->cart->recyclable; - $order->gift = (int) $this->context->cart->gift; + $order->gift = (bool) $this->context->cart->gift; $order->gift_message = $this->context->cart->gift_message; $order->mobile_theme = false; $order->conversion_rate = $this->context->currency->conversion_rate; @@ -247,7 +237,7 @@ public function makeOrder($idCart, $idOrderState, $paymentMethod, $message, $len $order->total_shipping_tax_incl = (float) Tools::ps_round($lengowShippingCosts, $precision); $order->total_shipping = $order->total_shipping_tax_incl; if ($lengowTrackingNumber !== null) { - $order->shipping_number = (string) $lengowTrackingNumber; + $order->setWsShippingNumber((string) $lengowTrackingNumber); } // add processing fees to wrapping fees $taxManager = TaxManagerFactory::getManager( @@ -270,7 +260,7 @@ public function makeOrder($idCart, $idOrderState, $paymentMethod, $message, $len $precision ); $order->total_paid = $order->total_paid_tax_incl; - $order->round_mode = Configuration::get('PS_PRICE_ROUND_MODE'); + $order->round_mode = (int) Configuration::get('PS_PRICE_ROUND_MODE'); $order->invoice_date = '0000-00-00 00:00:00'; $order->delivery_date = '0000-00-00 00:00:00'; @@ -333,7 +323,7 @@ public function makeOrder($idCart, $idOrderState, $paymentMethod, $message, $len $orderDetailList[] = $orderDetail; // adding an entry in order_carrier table - if ($carrier !== null) { + if (Validate::isLoadedObject($carrier)) { $orderCarrier = new LengowOrderCarrier(); $orderCarrier->id_order = (int) $order->id; $orderCarrier->id_carrier = (int) $idCarrier; @@ -352,21 +342,21 @@ public function makeOrder($idCart, $idOrderState, $paymentMethod, $message, $len // register payment only if the order status validate the order if ($orderStatus->logable && isset($order)) { $idTransaction = null; - if (!$order->addOrderPayment($order->total_paid_tax_incl, null, $idTransaction)) { + if (!$order->addOrderPayment((string) $order->total_paid_tax_incl, null, $idTransaction)) { throw new LengowException(LengowMain::setLogMessage('lengow_log.exception.unable_to_save_order_payment')); } } foreach ($orderDetailList as $key => $orderDetail) { $order = $orderList[$key]; - if (!$orderCreationFailed && isset($order->id)) { + if (isset($order->id)) { if (!empty($message)) { $msg = new Message(); $message = strip_tags($message, '
'); if (Validate::isCleanHtml($message)) { $msg->message = $message; $msg->id_order = (int) $order->id; - $msg->private = 1; + $msg->private = true; $msg->add(); } } @@ -393,7 +383,7 @@ public function makeOrder($idCart, $idOrderState, $paymentMethod, $message, $len $customerMessage->id_customer_thread = $customerThread->id; $customerMessage->id_employee = 0; $customerMessage->message = $updateMessage->message; - $customerMessage->private = 0; + $customerMessage->private = false; $customerMessage->add(); } @@ -407,18 +397,15 @@ public function makeOrder($idCart, $idOrderState, $paymentMethod, $message, $len $newHistory = new OrderHistory(); $newHistory->id_order = (int) $order->id; $newHistory->changeIdOrderState((int) $idOrderState, $order, true); - $newHistory->addWithemail(true, null); + $newHistory->addWithemail(true, []); // switch to back order if needed if (Configuration::get('PS_STOCK_MANAGEMENT') && $orderDetail->getStockState()) { $history = new OrderHistory(); $history->id_order = (int) $order->id; - if (version_compare(_PS_VERSION_, '1.6.0.11', '<')) { - $history->changeIdOrderState(Configuration::get('PS_OS_OUTOFSTOCK'), $order, true); - } $history->changeIdOrderState( - Configuration::get($order->valid ? 'PS_OS_OUTOFSTOCK_PAID' : 'PS_OS_OUTOFSTOCK_UNPAID'), + (int) Configuration::get($order->valid ? 'PS_OS_OUTOFSTOCK_PAID' : 'PS_OS_OUTOFSTOCK_UNPAID'), $order, true ); @@ -429,25 +416,13 @@ public function makeOrder($idCart, $idOrderState, $paymentMethod, $message, $len // order is reloaded because the status just changed $order = new Order($order->id); - - // updates stock in shops - if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) { - $productList = $order->getProducts(); - foreach ($productList as $product) { - // if the available quantities depends on the physical stock - if (StockAvailable::dependsOnStock($product['product_id'])) { - // synchronizes - StockAvailable::synchronize($product['product_id'], $order->id_shop); - } - } - } } else { throw new LengowException(LengowMain::setLogMessage('lengow_log.exception.order_creation_failed')); } } // update Order Details Tax in case cart rules have free shipping - if (isset($order) && $order instanceof Order) { + if (isset($order)) { foreach ($order->getOrderDetailList() as $detail) { $orderDetail = new OrderDetail($detail['id_order_detail']); $orderDetail->updateTaxAmount($order); @@ -455,7 +430,7 @@ public function makeOrder($idCart, $idOrderState, $paymentMethod, $message, $len } // use the last order as currentOrder - if (isset($order) && $order instanceof Order) { + if (isset($order)) { $this->currentOrder = (int) $order->id; } @@ -466,8 +441,10 @@ public function makeOrder($idCart, $idOrderState, $paymentMethod, $message, $len * Set context for payment module * * @param Context $context PrestaShop context instance + * + * @return void */ - public function setContext(Context $context) + public function setContext(Context $context): void { $this->context = $context; } diff --git a/classes/models/LengowProduct.php b/classes/models/LengowProduct.php index cbb32649..00e872f5 100755 --- a/classes/models/LengowProduct.php +++ b/classes/models/LengowProduct.php @@ -37,9 +37,9 @@ class LengowProduct extends Product public const FIELD_SHOP_ID = 'id_shop'; /** - * @var array API nodes containing relevant data + * @var list API nodes containing relevant data */ - public static $productApiNodes = [ + public static array $productApiNodes = [ 'marketplace_product_id', 'marketplace_status', 'merchant_product_id', @@ -51,71 +51,71 @@ class LengowProduct extends Product /** * @var Context PrestaShop context instance */ - protected $context; + protected Context $context; /** - * @var array product images + * @var array product images */ - protected $images; + protected array $images = []; /** * @var string image size */ - protected $imageSize; + protected string $imageSize = ''; /** - * @var Category PrestaShop category instance + * @var Category|null PrestaShop category instance */ - protected $categoryDefault; + protected ?Category $categoryDefault = null; /** * @var string name of the default category */ - protected $categoryDefaultName; + protected string $categoryDefaultName = ''; /** * @var bool is product in sale */ - protected $isSale; + protected bool $isSale = false; /** - * @var array|null combination of product's attributes + * @var array|null combination of product's attributes */ - protected $combinations; + protected ?array $combinations = null; /** - * @var array product's features + * @var array product's features */ - protected $features; + protected array $features = []; /** - * @var Carrier PrestaShop carrier instance + * @var Carrier|null PrestaShop carrier instance */ - protected $carrier; + protected ?Carrier $carrier = null; /** * @var string all product variations */ - protected $variation; + protected string $variation = ''; /** * Load a new product * * @param int|null $idProduct PrestaShop product id * @param int|null $idLang PrestaShop lang id - * @param array $params all export parameters + * @param array $params all export parameters * * @throws Exception|LengowException */ - public function __construct($idProduct = null, $idLang = null, $params = []) + public function __construct(?int $idProduct = null, ?int $idLang = null, array $params = []) { parent::__construct($idProduct, false, $idLang); $this->isSale = false; $this->combinations = null; $this->carrier = isset($params['carrier']) ? $params['carrier'] : null; $this->imageSize = isset($params['image_size']) ? $params['image_size'] : self::getMaxImageType(); - $this->context = Context::getContext(); - $this->context->language = isset($params['language']) ? $params['language'] : Context::getContext()->language; + $this->context = LengowContext::getContext(); + $this->context->language = isset($params['language']) ? $params['language'] : $this->context->language; // the applicable tax may be BOTH the product one and the state one (moreover this variable is some deadcode) $this->tax_name = 'deprecated'; $this->manufacturer_name = Manufacturer::getNameById((int) $this->id_manufacturer); @@ -150,12 +150,16 @@ public function __construct($idProduct = null, $idLang = null, $params = []) $this->loadStockData(); if ($this->id_category_default && $this->id_category_default > 1) { $this->categoryDefault = new Category((int) $this->id_category_default, $idLang); - $this->categoryDefaultName = $this->categoryDefault->name; + $this->categoryDefaultName = is_array($this->categoryDefault->name) + ? (string) reset($this->categoryDefault->name) + : (string) $this->categoryDefault->name; } else { $categories = self::getProductCategories($this->id); if (!empty($categories)) { $this->categoryDefault = new Category($categories[0], $idLang); - $this->categoryDefaultName = $this->categoryDefault->name; + $this->categoryDefaultName = is_array($this->categoryDefault->name) + ? (string) reset($this->categoryDefault->name) + : (string) $this->categoryDefault->name; } } $this->images = $this->getImages($idLang); @@ -177,11 +181,11 @@ public function __construct($idProduct = null, $idLang = null, $params = []) * @param string $name data name * @param int|null $idProductAttribute PrestaShop product attribute id * - * @return string + * @return mixed * * @throws Exception */ - public function getData($name, $idProductAttribute = null) + public function getData(string $name, ?int $idProductAttribute = null): mixed { switch ($name) { case 'id': @@ -242,7 +246,7 @@ public function getData($name, $idProductAttribute = null) case 'shipping_delay': return $this->carrier->delay[$this->context->language->id]; case 'currency': - return Context::getContext()->currency->iso_code; + return $this->context->currency->iso_code; case (bool) preg_match('`image_([0-9]+)`', $name): return $this->getImageLink($name, $idProductAttribute); case 'type': @@ -272,6 +276,10 @@ public function getData($name, $idProductAttribute = null) case 'width': case 'height': case 'depth': + if (!in_array($name, ['width', 'height', 'depth'], true)) { + return ''; + } + return LengowMain::formatNumber($this->{$name}); case 'weight_unit': return Configuration::get('PS_WEIGHT_UNIT'); @@ -288,7 +296,7 @@ public function getData($name, $idProductAttribute = null) ) { return LengowMain::cleanData($this->combinations[$idProductAttribute]['attributes'][$name][1]); } - if (isset($this->{$name})) { + if (property_exists($this, $name) && isset($this->{$name})) { return LengowMain::cleanData($this->{$name}); } @@ -298,8 +306,10 @@ public function getData($name, $idProductAttribute = null) /** * Make the feature of current product + * + * @return void */ - public function makeFeatures() + public function makeFeatures(): void { $features = $this->getFrontFeatures($this->context->language->id); if ($features) { @@ -311,17 +321,19 @@ public function makeFeatures() /** * Make the attributes of current product + * + * @return void */ - public function makeAttributes() + public function makeAttributes(): void { $combArray = []; $combinations = $this->getAttributesGroups($this->context->language->id); - if (is_array($combinations)) { + if (!empty($combinations)) { $cImages = $this->getImageUrlCombination(); foreach ($combinations as $c) { $attributeId = $c['id_product_attribute']; $priceToConvert = Tools::convertPrice($c['price'], $this->context->currency); - $price = Tools::displayPrice($priceToConvert, $this->context->currency); + $price = Tools::getContextLocale($this->context)->formatPrice($priceToConvert, $this->context->currency->iso_code); if (array_key_exists($attributeId, $combArray)) { $combArray[$attributeId]['attributes'][$c['group_name']] = [ $c['group_name'], @@ -367,7 +379,7 @@ public function makeAttributes() $this->variation = rtrim($name, ', '); } $combArray[$idProductAttribute]['available_date'] = ( - $productAttribute['available_date'] != 0 + $productAttribute['available_date'] !== '0000-00-00' ? date(LengowMain::DATE_DAY, strtotime($productAttribute['available_date'])) : '0000-00-00' ); @@ -379,9 +391,9 @@ public function makeAttributes() /** * Get combinations of current product * - * @return array + * @return array */ - public function getCombinations() + public function getCombinations(): array { return $this->combinations; } @@ -392,9 +404,9 @@ public function getCombinations() * @param int $idLang PrestaShop lang id * @param int $id_product_attribute * - * @return array + * @return array */ - public function getAttributesGroups($idLang, $id_product_attribute = null) + public function getAttributesGroups($idLang, $id_product_attribute = null): array { if (!Combination::isFeatureActive()) { return []; @@ -421,7 +433,7 @@ public function getAttributesGroups($idLang, $id_product_attribute = null) ps.`product_supplier_reference` AS `supplier_reference`, pa.`ean13`, pa.`upc`, - ' . (version_compare(_PS_VERSION_, '1.7.0', '>=') ? 'pa.`isbn`,' : '') . ' + pa.`isbn`, pa.`wholesale_price`, pa.`ecotax` FROM `' . _DB_PREFIX_ . 'product_attribute` pa @@ -456,9 +468,10 @@ public function getAttributesGroups($idLang, $id_product_attribute = null) * * @return string */ - protected function getSupplierReference($idProductAttribute) + protected function getSupplierReference(?int $idProductAttribute): string { - if ($idProductAttribute && $this->combinations[$idProductAttribute]['supplier_reference']) { + // If an attribute id is provided and combinations for it exist, prefer its supplier reference + if ($idProductAttribute && isset($this->combinations[$idProductAttribute]) && !empty($this->combinations[$idProductAttribute]['supplier_reference'])) { $supplierReference = $this->combinations[$idProductAttribute]['supplier_reference']; } elseif ($this->supplier_reference !== '') { $supplierReference = $this->supplier_reference; @@ -479,7 +492,7 @@ protected function getSupplierReference($idProductAttribute) * * @return string */ - protected function getBreadcrumb() + protected function getBreadcrumb(): string { if ($this->categoryDefault) { $breadcrumb = ''; @@ -503,37 +516,24 @@ protected function getBreadcrumb() * * @return string */ - protected function getProductUrl($idProductAttribute = null, $rewrite = false) + protected function getProductUrl(?int $idProductAttribute = null, bool $rewrite = false): string { try { - if (version_compare(_PS_VERSION_, '1.6.1.1', '<')) { - $productUrl = $this->context->link->getProductLink( - $this, - $rewrite ? $this->link_rewrite : null, - null, - null, - null, - null, - $idProductAttribute, - _PS_VERSION_ === '1.6.1.0' && !$rewrite - ); - } else { - if (version_compare(_PS_VERSION_, '1.7.1', '>=') && $idProductAttribute === null) { - $idProductAttribute = $this->getDefaultAttribute($this->id); - } - $productUrl = $this->context->link->getProductLink( - $this, - null, - null, - null, - null, - null, - $idProductAttribute, - !(version_compare(_PS_VERSION_, '1.7.1', '<') && $rewrite), - false, - true - ); + if ($idProductAttribute === null) { + $idProductAttribute = $this->getDefaultAttribute($this->id); } + $productUrl = $this->context->link->getProductLink( + $this, + null, + null, + null, + null, + null, + $idProductAttribute, + true, + false, + true + ); } catch (Exception $e) { $productUrl = ''; } @@ -548,7 +548,7 @@ protected function getProductUrl($idProductAttribute = null, $rewrite = false) * * @return float */ - protected function getEcotaxLengow($idProductAttribute = null) + protected function getEcotaxLengow(?int $idProductAttribute = null): float { $ecotax = 0; if ($idProductAttribute && $this->combinations[$idProductAttribute]['ecotax']) { @@ -566,11 +566,11 @@ protected function getEcotaxLengow($idProductAttribute = null) * * @param int|null $idProductAttribute PrestaShop product attribute id * - * @return float + * @return string * * @throws Exception */ - protected function getShippingCost($idProductAttribute = null) + protected function getShippingCost(?int $idProductAttribute = null): string { if ($idProductAttribute) { $price = $this->getData('price_incl_tax', $idProductAttribute); @@ -632,10 +632,10 @@ protected function getShippingCost($idProductAttribute = null) * * @return string */ - protected function getImageLink($name, $idProductAttribute = null) + protected function getImageLink(string $name, ?int $idProductAttribute = null): string { $index = explode('_', $name); - $idImage = (isset($index[1])) ? $index[1] - 1 : null; + $idImage = (isset($index[1])) ? (int) $index[1] - 1 : null; if (is_null($idImage)) { return ''; } @@ -652,7 +652,7 @@ protected function getImageLink($name, $idProductAttribute = null) return isset($this->images[$idImage]) ? $this->context->link->getImageLink( $this->link_rewrite, - $this->id . '-' . $this->images[$idImage]['id_image'], + $this->images[$idImage]['id_image'], $this->imageSize ) : ''; } @@ -664,7 +664,7 @@ protected function getImageLink($name, $idProductAttribute = null) * * @return string */ - protected function getProductTypeLengow($idProductAttribute = null) + protected function getProductTypeLengow(?int $idProductAttribute = null): string { if ($idProductAttribute) { $type = 'child'; @@ -682,7 +682,7 @@ protected function getProductTypeLengow($idProductAttribute = null) * * @return string */ - protected function getTagList() + protected function getTagList(): string { return $this->getTags($this->context->language->id); } @@ -692,9 +692,9 @@ protected function getTagList() * * @param int|null $idProductAttribute PrestaShop product attribute id * - * @return string + * @return float */ - protected function getWeight($idProductAttribute = null) + protected function getWeight(?int $idProductAttribute = null): float { if ($idProductAttribute && $this->combinations[$idProductAttribute]['weight']) { $weight = (float) $this->weight + (float) $this->combinations[$idProductAttribute]['weight']; @@ -713,14 +713,18 @@ protected function getWeight($idProductAttribute = null) * * @return string */ - protected function getProductData($name, $idProductAttribute = null) + protected function getProductData(string $name, ?int $idProductAttribute = null): string { + $allowedProductFields = ['reference', 'ean13', 'upc', 'isbn', 'wholesale_price', 'minimal_quantity']; $value = false; if ($idProductAttribute && $this->combinations[$idProductAttribute][$name]) { $value = $this->combinations[$idProductAttribute][$name]; } // if the value of the combination is not given, we take that of the parent - if (!$value || $value === 0 || $value === '0' || $value === '') { + if (empty($value)) { + if (!in_array($name, $allowedProductFields, true)) { + return ''; + } $value = isset($this->{$name}) ? $this->{$name} : ''; } @@ -736,7 +740,7 @@ protected function getProductData($name, $idProductAttribute = null) * * @return bool */ - public static function publish($productId, $value, $shopId) + public static function publish(int $productId, int $value, int $shopId): bool { if (!$value) { $sql = 'DELETE FROM ' . _DB_PREFIX_ . 'lengow_product @@ -768,17 +772,20 @@ public static function publish($productId, $value, $shopId) * Compares found id with API ids and checks if they match * * @param LengowProduct $product Lengow product instance - * @param array $apiDatas product ids from the API + * @param array $apiDatas product ids from the API * * @return bool if valid or not */ - protected static function isValidId($product, $apiDatas) + protected static function isValidId(LengowProduct $product, array $apiDatas): bool { $attributes = ['reference', 'ean13', 'upc', 'id']; $combinations = $product->getCombinations(); if (!empty($combinations)) { foreach ($combinations as $combination) { foreach ($attributes as $attributeName) { + if (!in_array($attributeName, ['reference', 'ean13', 'upc', 'id'], true)) { + continue; + } foreach ($apiDatas as $idApi) { if (!empty($idApi)) { if ($attributeName === 'id') { @@ -799,6 +806,9 @@ protected static function isValidId($product, $apiDatas) } } else { foreach ($attributes as $attributeName) { + if (!in_array($attributeName, ['reference', 'ean13', 'upc', 'id'], true)) { + continue; + } foreach ($apiDatas as $idApi) { if (!empty($idApi)) { if ($attributeName === 'id') { @@ -827,12 +837,15 @@ protected static function isValidId($product, $apiDatas) * * @param mixed $api product datas * - * @return array + * @return array */ - public static function extractProductDataFromAPI($api) + public static function extractProductDataFromAPI(mixed $api): array { $temp = []; foreach (self::$productApiNodes as $node) { + if (!in_array($node, self::$productApiNodes, true)) { + continue; + } $temp[$node] = $api->{$node}; } $qty = (float) $temp['quantity']; @@ -851,13 +864,13 @@ public static function extractProductDataFromAPI($api) * @param string $attributeName attribute name * @param string $attributeValue attribute value * @param int $idShop PrestaShop shop id - * @param array $apiDatas product ids from the API + * @param array $apiDatas product ids from the API * - * @return array|false + * @return array|false * * @throws LengowException */ - public static function matchProduct($attributeName, $attributeValue, $idShop, $apiDatas = []) + public static function matchProduct(string $attributeName, string $attributeValue, int $idShop, array $apiDatas = []): array|false { if (empty($attributeValue) || empty($attributeName)) { return false; @@ -877,7 +890,7 @@ public static function matchProduct($attributeName, $attributeValue, $idShop, $a // compatibility with old plugins $sku = str_replace(['\_', 'X'], '_', $attributeValue); $sku = explode('_', $sku); - if (isset($sku[0]) && preg_match('/^[0-9]*$/', $sku[0]) && count($sku) < 3) { + if (preg_match('/^[0-9]*$/', $sku[0]) && count($sku) < 3) { $idsProduct['id_product'] = (int) $sku[0]; if (isset($sku[1])) { if (preg_match('/^[0-9]*$/', $sku[1]) && count($sku) === 2) { @@ -910,13 +923,13 @@ public static function matchProduct($attributeName, $attributeValue, $idShop, $a * Check if product id found is correct * * @param int $idProduct PrestaShop product id - * @param array $apiDatas product ids from the API + * @param array $apiDatas product ids from the API * * @return bool * * @throws LengowException */ - protected static function checkProductId($idProduct, $apiDatas) + protected static function checkProductId(int $idProduct, array $apiDatas): bool { if (empty($idProduct)) { return false; @@ -934,7 +947,7 @@ protected static function checkProductId($idProduct, $apiDatas) * * @return bool */ - protected static function checkProductAttributeId($product, $idProductAttribute) + protected static function checkProductAttributeId(LengowProduct $product, int $idProductAttribute): bool { return !($idProductAttribute === 0 || !array_key_exists($idProductAttribute, $product->getCombinations())); } @@ -946,28 +959,36 @@ protected static function checkProductAttributeId($product, $idProductAttribute) * @param string $value attribute value * @param int $idShop PrestaShop shop id * - * @return int|false + * @return array|false */ - protected static function findProduct($key, $value, $idShop) + protected static function findProduct(string $key, string $value, int $idShop): array|false { - if (empty($key) || empty($value) || ($key === 'isbn' && version_compare(_PS_VERSION_, '1.7.0', '<'))) { + if (empty($key) || empty($value)) { + return false; + } + $allowedColumns = ['id_product', 'reference', 'ean13', 'isbn', 'upc', 'mpn', 'supplier_reference']; + if (!in_array($key, $allowedColumns, true)) { return false; } $query = new DbQuery(); $query->select('p.id_product'); $query->from('product', 'p'); $query->innerJoin('product_shop', 'ps', 'p.id_product = ps.id_product'); - $query->where('p.' . pSQL(Db::getInstance()->_escape($key)) . ' = \'' . pSQL(Db::getInstance()->_escape($value)) . '\''); - $query->where('ps.`id_shop` = \'' . (int) Db::getInstance()->_escape($idShop) . '\''); + $query->where('p.`' . bqSQL($key) . '` = \'' . pSQL($value) . '\''); + $query->where('ps.`id_shop` = ' . (int) $idShop); $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($query); // if no result, search in attribute if ($result == '') { + $allowedAttrColumns = ['id_product_attribute', 'reference', 'ean13', 'isbn', 'upc', 'mpn', 'supplier_reference']; + if (!in_array($key, $allowedAttrColumns, true)) { + return false; + } $query = new DbQuery(); $query->select('pa.id_product, pa.id_product_attribute'); $query->from('product_attribute', 'pa'); $query->innerJoin('product_shop', 'ps', 'pa.id_product = ps.id_product'); - $query->where('pa.' . pSQL(Db::getInstance()->_escape($key)) . ' = \'' . pSQL(Db::getInstance()->_escape($value)) . '\''); - $query->where('ps.`id_shop` = \'' . (int) Db::getInstance()->_escape($idShop) . '\''); + $query->where('pa.`' . bqSQL($key) . '` = \'' . pSQL($value) . '\''); + $query->where('ps.`id_shop` = ' . (int) $idShop); $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($query); } @@ -979,13 +1000,13 @@ protected static function findProduct($key, $value, $idShop) * * @param string $attributeValue attribute value * @param int $idShop PrestaShop shop id - * @param array $apiDatas product ids from the API + * @param array $apiDatas product ids from the API * - * @return array|false + * @return array|false * * @throws LengowException */ - public static function advancedSearch($attributeValue, $idShop, $apiDatas) + public static function advancedSearch(string $attributeValue, int $idShop, array $apiDatas): array|false { // product class attribute to search $attributes = ['reference', 'ean', 'upc', 'isbn', 'ids']; @@ -1010,13 +1031,13 @@ public static function advancedSearch($attributeValue, $idShop, $apiDatas) /** * Calculate product without taxes using TaxManager * - * @param array $product product + * @param array $product product * @param int $idAddress PrestaShop address id used to get tax rate * @param Context $context PrestaShop context instance * * @return float */ - public static function calculatePriceWithoutTax($product, $idAddress, $context) + public static function calculatePriceWithoutTax(array $product, int $idAddress, Context $context): float { $taxAddress = new LengowAddress((int) $idAddress); $taxManager = TaxManagerFactory::getManager( @@ -1031,9 +1052,9 @@ public static function calculatePriceWithoutTax($product, $idAddress, $context) /** * get image url of product variations * - * @return array|false + * @return array|false */ - public function getImageUrlCombination() + public function getImageUrlCombination(): array|false { $cImages = []; $psImages = $this->getCombinationImages($this->id_lang); @@ -1044,7 +1065,7 @@ public function getImageUrlCombination() if (!isset($cImages[$productAttributeId]) || count($cImages[$productAttributeId]) < $maxImage) { $cImages[$productAttributeId][] = $this->context->link->getImageLink( $this->link_rewrite, - $this->id . '-' . $image['id_image'], + $image['id_image'], $this->imageSize ); } @@ -1064,7 +1085,7 @@ public function getImageUrlCombination() * * @throws LengowException cant find image size */ - public static function getMaxImageType() + public static function getMaxImageType(): string { $sql = 'SELECT name FROM ' . _DB_PREFIX_ . 'image_type WHERE products = 1 ORDER BY width DESC'; try { diff --git a/classes/models/LengowShop.php b/classes/models/LengowShop.php index 57d3bfc3..023f7971 100755 --- a/classes/models/LengowShop.php +++ b/classes/models/LengowShop.php @@ -33,7 +33,7 @@ class LengowShop extends Shop * * @return LengowShop|false */ - public static function findByToken($token) + public static function findByToken(string $token): LengowShop|false { try { $sql = 'SELECT id_shop FROM ' . _DB_PREFIX_ . 'shop WHERE active = 1'; @@ -55,9 +55,9 @@ public static function findByToken($token) * * @param bool $forceContext force context to get all shops * - * @return array + * @return array */ - public static function findAll($forceContext = false) + public static function findAll(bool $forceContext = false): array { if (!$forceContext && $currentShop = Shop::getContextShopID()) { $results = [['id_shop' => $currentShop]]; @@ -79,9 +79,9 @@ public static function findAll($forceContext = false) * @param bool $activeInLengow get only shop active in Lengow * @param int $idShop PrestaShop shop id * - * @return array + * @return array */ - public static function getActiveShops($activeInLengow = false, $idShop = null) + public static function getActiveShops(bool $activeInLengow = false, ?int $idShop = null): array { $result = []; $shops = self::findAll(true); diff --git a/classes/models/LengowSync.php b/classes/models/LengowSync.php index 3aad94da..a409f12c 100755 --- a/classes/models/LengowSync.php +++ b/classes/models/LengowSync.php @@ -60,9 +60,9 @@ class LengowSync public const API_ISO_CODE_IT = 'it'; /** - * @var array cache time for catalog, carrier, account status, options and marketplace synchronisation + * @var array cache time for catalog, carrier, account status, options and marketplace synchronisation */ - protected static $cacheTimes = [ + protected static array $cacheTimes = [ self::SYNC_CATALOG => 21600, self::SYNC_CARRIER => 86400, self::SYNC_CMS_OPTION => 86400, @@ -72,9 +72,9 @@ class LengowSync ]; /** - * @var array valid sync actions + * @var list valid sync actions */ - public static $syncActions = [ + public static array $syncActions = [ self::SYNC_ORDER, self::SYNC_CARRIER, self::SYNC_CMS_OPTION, @@ -86,9 +86,9 @@ class LengowSync ]; /** - * @var array iso code correspondence for plugin links + * @var array iso code correspondence for plugin links */ - public static $genericIsoCodes = [ + public static array $genericIsoCodes = [ self::API_ISO_CODE_EN => LengowTranslation::ISO_CODE_EN, self::API_ISO_CODE_FR => LengowTranslation::ISO_CODE_FR, self::API_ISO_CODE_ES => LengowTranslation::ISO_CODE_ES, @@ -96,9 +96,9 @@ class LengowSync ]; /** - * @var array default plugin links when the API is not available + * @var array default plugin links when the API is not available */ - public static $defaultPluginLinks = [ + public static array $defaultPluginLinks = [ self::LINK_TYPE_HELP_CENTER => self::LINK_HELP_CENTER, self::LINK_TYPE_CHANGELOG => self::LINK_CHANGELOG, self::LINK_TYPE_UPDATE_GUIDE => self::LINK_UPDATE_GUIDE, @@ -108,9 +108,9 @@ class LengowSync /** * Get Sync Data (Inscription / Update) * - * @return array + * @return array */ - public static function getSyncData() + public static function getSyncData(): array { $data = [ 'domain_name' => $_SERVER['SERVER_NAME'], @@ -150,7 +150,7 @@ public static function getSyncData() * * @return bool */ - public static function syncCatalog($force = false, $logOutput = false) + public static function syncCatalog(bool $force = false, bool $logOutput = false): bool { $success = false; $settingUpdated = false; @@ -159,7 +159,7 @@ public static function syncCatalog($force = false, $logOutput = false) } if (!$force) { $updatedAt = LengowConfiguration::getGlobalValue(LengowConfiguration::LAST_UPDATE_CATALOG); - if ($updatedAt !== null && (time() - (int) $updatedAt) < self::$cacheTimes[self::SYNC_CATALOG]) { + if ($updatedAt !== '' && (time() - (int) $updatedAt) < self::$cacheTimes[self::SYNC_CATALOG]) { return $success; } } @@ -203,14 +203,14 @@ public static function syncCatalog($force = false, $logOutput = false) * * @return bool */ - public static function syncCarrier($force = false, $logOutput = false) + public static function syncCarrier(bool $force = false, bool $logOutput = false): bool { if (LengowConfiguration::isNewMerchant()) { return false; } if (!$force) { $updatedAt = LengowConfiguration::getGlobalValue(LengowConfiguration::LAST_UPDATE_MARKETPLACE_LIST); - if ($updatedAt !== null && (time() - (int) $updatedAt) < self::$cacheTimes[self::SYNC_CARRIER]) { + if ($updatedAt !== '' && (time() - (int) $updatedAt) < self::$cacheTimes[self::SYNC_CARRIER]) { return false; } } @@ -229,9 +229,9 @@ public static function syncCarrier($force = false, $logOutput = false) /** * Get options for all shops * - * @return array + * @return array */ - public static function getOptionData() + public static function getOptionData(): array { $data = [ 'token' => LengowMain::getToken(), @@ -264,14 +264,14 @@ public static function getOptionData() * * @return bool */ - public static function setCmsOption($force = false, $logOutput = false) + public static function setCmsOption(bool $force = false, bool $logOutput = false): bool { if (LengowConfiguration::isNewMerchant() || LengowConfiguration::debugModeIsActive()) { return false; } if (!$force) { $updatedAt = LengowConfiguration::getGlobalValue(LengowConfiguration::LAST_UPDATE_OPTION_CMS); - if ($updatedAt !== null && (time() - (int) $updatedAt) < self::$cacheTimes[self::SYNC_CMS_OPTION]) { + if ($updatedAt !== '' && (time() - (int) $updatedAt) < self::$cacheTimes[self::SYNC_CMS_OPTION]) { return false; } } @@ -288,13 +288,13 @@ public static function setCmsOption($force = false, $logOutput = false) * @param bool $force force cache update * @param bool $logOutput see log or not * - * @return array|false + * @return array|false */ - public static function getStatusAccount($force = false, $logOutput = false) + public static function getStatusAccount(bool $force = false, bool $logOutput = false): array|false { if (!$force) { $updatedAt = LengowConfiguration::getGlobalValue(LengowConfiguration::LAST_UPDATE_ACCOUNT_STATUS_DATA); - if ($updatedAt !== null && (time() - (int) $updatedAt) < self::$cacheTimes[self::SYNC_STATUS_ACCOUNT]) { + if ($updatedAt !== '' && (time() - (int) $updatedAt) < self::$cacheTimes[self::SYNC_STATUS_ACCOUNT]) { return json_decode( LengowConfiguration::getGlobalValue(LengowConfiguration::ACCOUNT_STATUS_DATA), true @@ -308,12 +308,16 @@ public static function getStatusAccount($force = false, $logOutput = false) '', $logOutput ); - if (isset($result->isFreeTrial)) { + $resultData = is_object($result) ? (array) $result : []; + if (array_key_exists('isFreeTrial', $resultData)) { + $leftDaysBeforeExpired = isset($resultData['leftDaysBeforeExpired']) ? (int) $resultData['leftDaysBeforeExpired'] : 0; + $isExpired = isset($resultData['isExpired']) ? (bool) $resultData['isExpired'] : false; + $accountVersion = isset($resultData['accountVersion']) ? (string) $resultData['accountVersion'] : ''; $status = [ - 'type' => $result->isFreeTrial ? 'free_trial' : '', - 'day' => (int) $result->leftDaysBeforeExpired < 0 ? 0 : (int) $result->leftDaysBeforeExpired, - 'expired' => (bool) $result->isExpired, - 'legacy' => $result->accountVersion === 'v2', + 'type' => (bool) $resultData['isFreeTrial'] ? 'free_trial' : '', + 'day' => $leftDaysBeforeExpired < 0 ? 0 : $leftDaysBeforeExpired, + 'expired' => $isExpired, + 'legacy' => $accountVersion === 'v2', ]; LengowConfiguration::updateGlobalValue( LengowConfiguration::ACCOUNT_STATUS_DATA, @@ -339,14 +343,17 @@ public static function getStatusAccount($force = false, $logOutput = false) * @param bool $force force cache update * @param bool $logOutput see log or not * - * @return array|false + * @return mixed */ - public static function getMarketplaces($force = false, $logOutput = false) + public static function getMarketplaces(bool $force = false, bool $logOutput = false): mixed { $filePath = LengowMarketplace::getFilePath(); + if (!LengowMain::isPathAllowed($filePath, _PS_MODULE_LENGOW_DIR_)) { + return false; + } if (!$force) { $updatedAt = LengowConfiguration::getGlobalValue(LengowConfiguration::LAST_UPDATE_MARKETPLACE); - if ($updatedAt !== null + if ($updatedAt !== '' && (time() - (int) $updatedAt) < self::$cacheTimes[self::SYNC_MARKETPLACE] && file_exists($filePath) ) { @@ -410,13 +417,13 @@ public static function getMarketplaces($force = false, $logOutput = false) * @param bool $force force cache update * @param bool $logOutput see log or not * - * @return array|false + * @return array|false */ - public static function getPluginData($force = false, $logOutput = false) + public static function getPluginData(bool $force = false, bool $logOutput = false): array|false { if (!$force) { $updatedAt = LengowConfiguration::getGlobalValue(LengowConfiguration::LAST_UPDATE_PLUGIN_DATA); - if ($updatedAt !== null && (time() - (int) $updatedAt) < self::$cacheTimes[self::SYNC_PLUGIN_DATA]) { + if ($updatedAt !== '' && (time() - (int) $updatedAt) < self::$cacheTimes[self::SYNC_PLUGIN_DATA]) { return json_decode(LengowConfiguration::getGlobalValue(LengowConfiguration::PLUGIN_DATA), true); } } @@ -485,9 +492,9 @@ public static function getPluginData($force = false, $logOutput = false) * @param string|null $isoCode * @param bool|null $default * - * @return array + * @return array */ - public static function getPluginLinks($isoCode = null, $default = false) + public static function getPluginLinks(?string $isoCode = null, ?bool $default = false): array { $pluginData = self::getPluginData(); if (!$pluginData || $default) { diff --git a/classes/models/LengowToolbox.php b/classes/models/LengowToolbox.php index 2673c5cc..d418ed69 100644 --- a/classes/models/LengowToolbox.php +++ b/classes/models/LengowToolbox.php @@ -192,9 +192,9 @@ class LengowToolbox public const FILE_TEST = 'test.txt'; /** - * @var array valid toolbox actions + * @var list valid toolbox actions */ - public static $toolboxActions = [ + public static array $toolboxActions = [ self::ACTION_DATA, self::ACTION_LOG, self::ACTION_ORDER, @@ -205,9 +205,9 @@ class LengowToolbox * * @param string $type Toolbox data type * - * @return array + * @return array */ - public static function getData($type = self::DATA_TYPE_CMS) + public static function getData(string $type = self::DATA_TYPE_CMS): array { switch ($type) { case self::DATA_TYPE_ALL: @@ -240,8 +240,10 @@ public static function getData($type = self::DATA_TYPE_CMS) * Download log file individually or globally * * @param string|null $date name of file to download + * + * @return void */ - public static function downloadLog($date = null) + public static function downloadLog(?string $date = null): void { LengowLog::download($date); } @@ -249,11 +251,11 @@ public static function downloadLog($date = null) /** * Start order synchronization based on specific parameters * - * @param array $params synchronization parameters + * @param array $params synchronization parameters * - * @return array + * @return array */ - public static function syncOrders($params = []) + public static function syncOrders(array $params = []): array { // get all params for order synchronization $params = self::filterParamsForSync($params); @@ -275,9 +277,9 @@ public static function syncOrders($params = []) * @param string|null $marketplaceName marketplace code * @param string $type Toolbox order data type * - * @return array + * @return array */ - public static function getOrderData($marketplaceSku = null, $marketplaceName = null, $type = self::DATA_TYPE_ORDER) + public static function getOrderData(?string $marketplaceSku = null, ?string $marketplaceName = null, string $type = self::DATA_TYPE_ORDER): array { $lengowOrders = $marketplaceSku && $marketplaceName ? LengowOrder::getAllLengowOrders($marketplaceSku, $marketplaceName) @@ -319,7 +321,7 @@ public static function getOrderData($marketplaceSku = null, $marketplaceName = n * * @return bool */ - public static function isCurlActivated() + public static function isCurlActivated(): bool { return function_exists(self::PHP_EXTENSION_CURL); } @@ -327,9 +329,9 @@ public static function isCurlActivated() /** * Get all data * - * @return array + * @return array */ - private static function getAllData() + private static function getAllData(): array { return [ self::CHECKLIST => self::getChecklistData(), @@ -345,9 +347,9 @@ private static function getAllData() /** * Get cms data * - * @return array + * @return array */ - private static function getCmsData() + private static function getCmsData(): array { return [ self::CHECKLIST => self::getChecklistData(), @@ -360,9 +362,9 @@ private static function getCmsData() /** * Get array of requirements * - * @return array + * @return array */ - private static function getChecklistData() + private static function getChecklistData(): array { $checksumData = self::getChecksumData(); @@ -377,9 +379,9 @@ private static function getChecklistData() /** * Get array of plugin data * - * @return array + * @return array */ - private static function getPluginData() + private static function getPluginData(): array { return [ self::PLUGIN_CMS_VERSION => _PS_VERSION_, @@ -399,9 +401,9 @@ private static function getPluginData() /** * Get array of synchronization data * - * @return array + * @return array */ - private static function getSynchronizationData() + private static function getSynchronizationData(): array { $lastImport = LengowMain::getLastImport(); @@ -420,9 +422,9 @@ private static function getSynchronizationData() /** * Get array of export data * - * @return array + * @return array */ - private static function getShopData() + private static function getShopData(): array { $exportData = []; $shops = LengowShop::getActiveShops(); @@ -454,9 +456,9 @@ private static function getShopData() /** * Get array of export data * - * @return array + * @return array */ - private static function getOptionData() + private static function getOptionData(): array { $optionData = [ self::CMS_OPTIONS => LengowConfiguration::getAllValues(), @@ -473,9 +475,9 @@ private static function getOptionData() /** * Get files checksum * - * @return array + * @return array */ - private static function getChecksumData() + private static function getChecksumData(): array { $fileCounter = 0; $fileModified = []; @@ -484,11 +486,23 @@ private static function getChecksumData() $fileName = LengowMain::getLengowFolder() . $sep . LengowMain::FOLDER_CONFIG . $sep . self::FILE_CHECKMD5; if (file_exists($fileName)) { $md5Available = true; + if (!LengowMain::isPathAllowed($fileName, _PS_MODULE_LENGOW_DIR_)) { + return [ + self::CHECKSUM_AVAILABLE => false, + self::CHECKSUM_SUCCESS => false, + self::CHECKSUM_NUMBER_FILES_CHECKED => 0, + self::CHECKSUM_FILE_MODIFIED => [], + self::CHECKSUM_FILE_DELETED => [], + ]; + } if (($file = fopen($fileName, 'rb')) !== false) { - while (($data = fgetcsv($file, 1000, '|')) !== false) { + while (($data = fgetcsv($file, 1000, '|', '"', '')) !== false) { ++$fileCounter; $shortPath = $data[0]; $filePath = LengowMain::getLengowFolder() . $data[0]; + if (!LengowMain::isPathAllowed($filePath, _PS_MODULE_LENGOW_DIR_)) { + continue; + } if (file_exists($filePath)) { $fileMd = md5_file($filePath); if ($fileMd !== $data[1]) { @@ -524,9 +538,11 @@ private static function getChecksumData() * * @string $shortPathParam the file short path * - * @return array + * @param mixed $shortPathParam + * + * @return array */ - private static function getModifiedFilesData($shortPathParam) + private static function getModifiedFilesData(mixed $shortPathParam): array { $fileCounter = 0; $fileModified = []; @@ -536,11 +552,23 @@ private static function getModifiedFilesData($shortPathParam) if (file_exists($fileName)) { $md5Available = true; + if (!LengowMain::isPathAllowed($fileName, _PS_MODULE_LENGOW_DIR_)) { + return [ + self::CHECKSUM_AVAILABLE => false, + self::CHECKSUM_SUCCESS => false, + self::CHECKSUM_NUMBER_FILES_CHECKED => 0, + self::CHECKSUM_FILE_MODIFIED => [], + self::CHECKSUM_FILE_DELETED => [], + ]; + } if (($file = fopen($fileName, 'rb')) !== false) { - while (($data = fgetcsv($file, 1000, '|')) !== false) { + while (($data = fgetcsv($file, 1000, '|', '"', '')) !== false) { ++$fileCounter; $shortPath = $data[0]; $filePath = LengowMain::getLengowFolder() . $data[0]; + if (!LengowMain::isPathAllowed($filePath, _PS_MODULE_LENGOW_DIR_)) { + continue; + } if (file_exists($filePath)) { $fileMd = md5_file($filePath); if ($fileMd !== $data[1]) { @@ -572,9 +600,9 @@ private static function getModifiedFilesData($shortPathParam) /** * Get all log files available * - * @return array + * @return array */ - private static function getLogData() + private static function getLogData(): array { $logs = LengowLog::getPaths(); if (!empty($logs)) { @@ -593,7 +621,7 @@ private static function getLogData() * * @return bool */ - private static function isSimpleXMLActivated() + private static function isSimpleXMLActivated(): bool { return function_exists(self::PHP_EXTENSION_SIMPLEXML); } @@ -603,7 +631,7 @@ private static function isSimpleXMLActivated() * * @return bool */ - private static function isJsonActivated() + private static function isJsonActivated(): bool { return function_exists(self::PHP_EXTENSION_JSON); } @@ -613,10 +641,13 @@ private static function isJsonActivated() * * @return bool */ - private static function testWritePermission() + private static function testWritePermission(): bool { $sep = DIRECTORY_SEPARATOR; $filePath = LengowMain::getLengowFolder() . $sep . LengowMain::FOLDER_CONFIG . $sep . self::FILE_TEST; + if (!LengowMain::isPathAllowed($filePath, _PS_MODULE_LENGOW_DIR_)) { + return false; + } try { $file = fopen($filePath, 'wb+'); if (!$file) { @@ -633,11 +664,11 @@ private static function testWritePermission() /** * Filter parameters for order synchronization * - * @param array $params synchronization params + * @param array $params synchronization params * - * @return array + * @return array */ - private static function filterParamsForSync($params = []) + private static function filterParamsForSync(array $params = []): array { $paramsFiltered = [LengowImport::PARAM_TYPE => LengowImport::TYPE_TOOLBOX]; if (isset( @@ -669,12 +700,12 @@ private static function filterParamsForSync($params = []) * Get array of all the data of the order * * @param string $type Toolbox order data type - * @param array $data All Lengow order data + * @param array $data All Lengow order data * @param LengowOrder|null $lengowOrder Lengow order instance * - * @return array + * @return array */ - private static function getOrderDataByType($type, $data, $lengowOrder = null) + private static function getOrderDataByType(string $type, array $data, ?LengowOrder $lengowOrder = null): array { $orderReferences = [ self::ID => (int) $data[LengowOrder::FIELD_ID], @@ -709,12 +740,12 @@ private static function getOrderDataByType($type, $data, $lengowOrder = null) /** * Get array of all the data of the order * - * @param array $data All Lengow order data + * @param array $data All Lengow order data * @param LengowOrder|null $lengowOrder Lengow order instance * - * @return array + * @return array */ - private static function getAllOrderData($data, $lengowOrder = null) + private static function getAllOrderData(array $data, ?LengowOrder $lengowOrder = null): array { $orderTypes = json_decode($data[LengowOrder::FIELD_ORDER_TYPES], true); @@ -786,9 +817,9 @@ private static function getAllOrderData($data, $lengowOrder = null) * * @param int $idOrderLengow Lengow order id * - * @return array + * @return array */ - private static function getOrderErrorsData($idOrderLengow) + private static function getOrderErrorsData(int $idOrderLengow): array { $orderErrors = []; $errors = LengowOrderError::getOrderLogs($idOrderLengow); @@ -820,9 +851,9 @@ private static function getOrderErrorsData($idOrderLengow) * * @param int $idOrder PrestaShop order id * - * @return array + * @return array */ - private static function getOrderActionData($idOrder) + private static function getOrderActionData(int $idOrder): array { $orderActions = []; $actions = LengowAction::getActionsByOrderId($idOrder); @@ -849,9 +880,9 @@ private static function getOrderActionData($idOrder) * * @param LengowOrder $lengowOrder Lengow order instance * - * @return array + * @return array */ - private static function getOrderStatusesData($lengowOrder) + private static function getOrderStatusesData(LengowOrder $lengowOrder): array { $orderStatuses = []; $idLang = Language::getIdByIso(LengowTranslation::ISO_CODE_EN); @@ -871,12 +902,12 @@ private static function getOrderStatusesData($lengowOrder) /** * Get all the data of the order at the time of import * - * @param array $data All Lengow order data + * @param array $data All Lengow order data * @param LengowOrder|null $lengowOrder Lengow order instance * - * @return array + * @return array */ - private static function getOrderExtraData($data, $lengowOrder = null) + private static function getOrderExtraData(array $data, ?LengowOrder $lengowOrder = null): array { $orderData = json_decode($data[LengowOrder::FIELD_EXTRA], true); $orderData[self::EXTRA_UPDATED_AT] = $lengowOrder @@ -893,7 +924,7 @@ private static function getOrderExtraData($data, $lengowOrder = null) * * @return string */ - private static function getOrderProcessLabel($orderProcess) + private static function getOrderProcessLabel(int $orderProcess): string { switch ($orderProcess) { case LengowOrder::PROCESS_STATE_NEW: @@ -913,7 +944,7 @@ private static function getOrderProcessLabel($orderProcess) * * @return string|null */ - private static function getOrderStatusCorrespondence($idOrderState) + private static function getOrderStatusCorrespondence(int $idOrderState): ?string { $idStatusWaitingShipment = LengowMain::getOrderState(LengowOrder::STATE_WAITING_SHIPMENT); $idStatusShipped = LengowMain::getOrderState(LengowOrder::STATE_SHIPPED); @@ -936,9 +967,9 @@ private static function getOrderStatusCorrespondence($idOrderState) * @param int $httpCode request http code * @param string $error error message * - * @return array + * @return array */ - private static function generateErrorReturn($httpCode, $error) + private static function generateErrorReturn(int $httpCode, string $error): array { return [ self::ERRORS => [ diff --git a/classes/models/LengowToolboxElement.php b/classes/models/LengowToolboxElement.php index 3373a00e..5b73f063 100644 --- a/classes/models/LengowToolboxElement.php +++ b/classes/models/LengowToolboxElement.php @@ -39,7 +39,7 @@ class LengowToolboxElement /** * @var LengowTranslation Lengow translation instance */ - protected $locale; + protected LengowTranslation $locale; /** * Constructor @@ -54,7 +54,7 @@ public function __construct() * * @return string */ - public function getCheckList() + public function getCheckList(): string { $checklistData = LengowToolbox::getData(LengowToolbox::DATA_TYPE_CHECKLIST); $mailCheck = $this->getMailConfiguration(); @@ -104,7 +104,7 @@ public function getCheckList() * * @return string */ - public function getGlobalInformation() + public function getGlobalInformation(): string { $pluginData = LengowToolbox::getData(LengowToolbox::DATA_TYPE_PLUGIN); $checklist = [ @@ -154,7 +154,7 @@ public function getGlobalInformation() * * @return string */ - public function getImportInformation() + public function getImportInformation(): string { $synchronizationData = LengowToolbox::getData(LengowToolbox::DATA_TYPE_SYNCHRONIZATION); $lastSynchronization = $synchronizationData[LengowToolbox::SYNCHRONIZATION_LAST_SYNCHRONIZATION]; @@ -222,7 +222,7 @@ public function getImportInformation() * * @return string */ - public function getExportInformation() + public function getExportInformation(): string { $content = ''; $exportData = LengowToolbox::getData(LengowToolbox::DATA_TYPE_SHOP); @@ -299,7 +299,7 @@ public function getExportInformation() * * @return string */ - public function getFileInformation() + public function getFileInformation(): string { $content = ''; $exportData = LengowToolbox::getData(LengowToolbox::DATA_TYPE_SHOP); @@ -325,7 +325,7 @@ public function getFileInformation() $checklist[] = [self::DATA_SIMPLE => $this->locale->t('toolbox.screen.file_list')]; foreach ($files as $file) { $fileTimestamp = filectime($folderPath . $file); - $fileLink = '' . $file . ''; + $fileLink = '' . htmlspecialchars($file, ENT_QUOTES, 'UTF-8') . ''; $checklist[] = [ self::DATA_TITLE => $fileLink, self::DATA_MESSAGE => LengowMain::getDateInCorrectFormat($fileTimestamp, true), @@ -347,7 +347,7 @@ public function getFileInformation() * * @return string */ - public function checkFileMd5() + public function checkFileMd5(): string { $checklist = []; $checksumData = LengowToolbox::getData(LengowToolbox::DATA_TYPE_CHECKSUM); @@ -413,9 +413,9 @@ public function checkFileMd5() /** * Get mail configuration information * - * @return array + * @return array */ - private function getMailConfiguration() + private function getMailConfiguration(): array { $mailMethod = (int) Configuration::get('PS_MAIL_METHOD'); if ($mailMethod === 2) { @@ -442,7 +442,7 @@ private function getMailConfiguration() * * @return bool */ - private function isShopActivated() + private function isShopActivated(): bool { if (Configuration::get('PS_CATALOG_MODE')) { return false; @@ -454,11 +454,11 @@ private function isShopActivated() /** * Get HTML Table content of checklist * - * @param array $checklist all information for toolbox + * @param array $checklist all information for toolbox * - * @return string + * @return string|null */ - private function getContent($checklist = []) + private function getContent(array $checklist = []): ?string { if (empty($checklist)) { return null; diff --git a/classes/models/LengowTranslation.php b/classes/models/LengowTranslation.php index c9d01dbd..8c5dbab1 100755 --- a/classes/models/LengowTranslation.php +++ b/classes/models/LengowTranslation.php @@ -38,38 +38,42 @@ class LengowTranslation public const DEFAULT_ISO_CODE = self::ISO_CODE_EN; /** - * @var array|null all translations + * @var array|null all translations */ - protected static $translation; + protected static ?array $translation = null; /** * @var string|null iso code */ - protected $isoCode; + protected ?string $isoCode = null; /** * @var string|null force iso code for log and toolbox */ - public static $forceIsoCode; + public static ?string $forceIsoCode = null; /** * Construct + * + * @param Context|null $context PrestaShop context (injected where available, + * falls back to LengowContext for legacy callers) */ - public function __construct() + public function __construct(?Context $context = null) { - $this->isoCode = Context::getContext()->language->iso_code; + $ctx = $context ?? LengowContext::getContext(); + $this->isoCode = $ctx->language->iso_code; } /** * Translate message * * @param string $message localization key - * @param array $args arguments to replace word in string + * @param array $args arguments to replace word in string * @param string|null $isoCode translation iso code * * @return string */ - public function t($message, $args = [], $isoCode = null) + public function t(string $message, array $args = [], ?string $isoCode = null): string { if (self::$forceIsoCode !== null) { $isoCode = self::$forceIsoCode; @@ -97,11 +101,11 @@ public function t($message, $args = [], $isoCode = null) * Translate string * * @param string $text localization key - * @param array $args arguments to replace word in string + * @param array $args arguments to replace word in string * * @return string */ - protected function translateFinal($text, $args) + protected function translateFinal(string $text, array $args): string { if ($args) { $params = []; @@ -125,7 +129,7 @@ protected function translateFinal($text, $args) * * @return bool */ - public function loadFile($isoCode, $filename = null) + public function loadFile(string $isoCode, ?string $filename = null): bool { $validCodes = [ self::ISO_CODE_EN, @@ -142,9 +146,12 @@ public function loadFile($isoCode, $filename = null) . $sep . LengowMain::FOLDER_TRANSLATION . $sep . $isoCode . '.csv'; } $translation = []; + if (!LengowMain::isPathAllowed($filename, _PS_MODULE_LENGOW_DIR_)) { + return false; + } if (file_exists($filename)) { if (($handle = fopen($filename, 'rb')) !== false) { - while (($data = fgetcsv($handle, 1000, '|')) !== false) { + while (($data = fgetcsv($handle, 1000, '|', '"', '\\')) !== false) { if (isset($data[1])) { $translation[$data[0]] = $data[1]; } diff --git a/composer.json b/composer.json index ad2a4979..9937f1e3 100644 --- a/composer.json +++ b/composer.json @@ -2,9 +2,13 @@ "name": "prestashop/lengow", "description": "Lengow", "version": "3.9.4", + "require": { + "php": ">=8.1" + }, "autoload": { "psr-4": { - "Lengow\\": "src/" + "Lengow\\": "src/", + "PrestaShop\\Module\\Lengow\\Controller\\Admin\\": "src/Controller/Admin/" }, "classmap": [ "lengow.php", diff --git a/composer.lock b/composer.lock index 24ef0089..eb1a28a1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,15 +4,17 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6643397d4ae64e38ae5518f118d46b6d", + "content-hash": "7c34a031ca70c4216dadaf1ad788f169", "packages": [], "packages-dev": [], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.2.0" + "platform": { + "php": ">=8.1" + }, + "platform-dev": {}, + "plugin-api-version": "2.9.0" } diff --git a/backup/index.php b/config/admin/index.php old mode 100755 new mode 100644 similarity index 100% rename from backup/index.php rename to config/admin/index.php diff --git a/config/admin/services.yml b/config/admin/services.yml new file mode 100644 index 00000000..e1f1e58e --- /dev/null +++ b/config/admin/services.yml @@ -0,0 +1,46 @@ +services: + _defaults: + public: false + autowire: true + autoconfigure: true + bind: + 'PrestaShop\PrestaShop\Adapter\LegacyContext $legacyContext': '@prestashop.adapter.legacy.context' + + PrestaShop\Module\Lengow\Controller\Admin\LengowHomeAdminController: + class: PrestaShop\Module\Lengow\Controller\Admin\LengowHomeAdminController + public: true + tags: ['controller.service_arguments'] + PrestaShop\Module\Lengow\Controller\Admin\LengowDashboardAdminController: + class: PrestaShop\Module\Lengow\Controller\Admin\LengowDashboardAdminController + public: true + tags: ['controller.service_arguments'] + PrestaShop\Module\Lengow\Controller\Admin\LengowFeedAdminController: + class: PrestaShop\Module\Lengow\Controller\Admin\LengowFeedAdminController + public: true + tags: ['controller.service_arguments'] + PrestaShop\Module\Lengow\Controller\Admin\LengowOrderAdminController: + class: PrestaShop\Module\Lengow\Controller\Admin\LengowOrderAdminController + public: true + tags: ['controller.service_arguments'] + PrestaShop\Module\Lengow\Controller\Admin\LengowOrderSettingAdminController: + class: PrestaShop\Module\Lengow\Controller\Admin\LengowOrderSettingAdminController + public: true + tags: ['controller.service_arguments'] + PrestaShop\Module\Lengow\Controller\Admin\LengowMainSettingAdminController: + class: PrestaShop\Module\Lengow\Controller\Admin\LengowMainSettingAdminController + public: true + tags: ['controller.service_arguments'] + PrestaShop\Module\Lengow\Controller\Admin\LengowHelpAdminController: + class: PrestaShop\Module\Lengow\Controller\Admin\LengowHelpAdminController + public: true + tags: ['controller.service_arguments'] + PrestaShop\Module\Lengow\Controller\Admin\LengowLegalsAdminController: + class: PrestaShop\Module\Lengow\Controller\Admin\LengowLegalsAdminController + public: true + tags: ['controller.service_arguments'] + PrestaShop\Module\Lengow\Controller\Admin\LengowToolboxAdminController: + class: PrestaShop\Module\Lengow\Controller\Admin\LengowToolboxAdminController + public: true + tags: ['controller.service_arguments'] + PrestaShop\Module\Lengow\Service\OrderRefundDataUpdater: + class: PrestaShop\Module\Lengow\Service\OrderRefundDataUpdater diff --git a/config/checkmd5.csv b/config/checkmd5.csv index 4b8d9f4c..6f0e333b 100644 --- a/config/checkmd5.csv +++ b/config/checkmd5.csv @@ -1,8 +1,8 @@ -/es.php|4e751925dec6dadaca2552eda4f4cd2f -/fr.php|0688c5e6237bf1c4ebf4d8f7a622a794 +/es.php|830a00d69fb5e92957de1aa684c87128 +/fr.php|e33982ba5b5cff100bd3f7ea7e8c104b /index.php|be8b25f88c14bddd7711e4585ebae316 -/it.php|14e76520f64429f3436543e904e13015 -/lengow.php|b5ef240b137aaa79e62db2110687742a +/it.php|f7bf9029ec3739108a185666561c2d86 +/lengow.php|9cb9064a1b9bc18cde5df26212969938 /loader.php|b3d94d65d0a074088758bc1e50736a01 /config/index.php|be8b25f88c14bddd7711e4585ebae316 /translations/en.csv|81b2e2ef964f1081ff0f455b22a99d42 @@ -10,500 +10,484 @@ /translations/fr.csv|a58e1647eaa7fdc493c171860eca27e2 /translations/index.php|be8b25f88c14bddd7711e4585ebae316 /translations/it.csv|8f3106c2c9c88c6b7f40ccb24aec629b -/classes/models/LengowImportOrder.php|be3f1d22fff61d3459b3138d1e7959ff -/classes/models/LengowCarrier.php|f9621c73a0d75730c81dfecde6908147 -/classes/models/LengowOrderDetail.php|c0ea8445020fc1c49b3d9e7099650d7a -/classes/models/LengowBackup.php|4967f2db11169e3ae51cf04357009769 -/classes/models/LengowNameParser.php|24faacd2e9367fc4652784090b20d0d5 -/classes/models/LengowList.php|31030820ccfc2ed94bfc5249c72d94f6 -/classes/models/LengowInstall.php|8a789fbf71c394665b39c4079799bcb9 -/classes/models/LengowOrder.php|ba0cf5fcb943c2e4d86663b668ff3c65 -/classes/models/LengowCountry.php|3f0559f5ec914a4cec1ca7848204553b -/classes/models/LengowConfigurationForm.php|f934e20300498dcd3be0094fb179c6bb -/classes/models/LengowCart.php|d7cba9073960f17a864fcc37dd780877 -/classes/models/LengowToolboxElement.php|20dbd4958f8914acd3d9654b9cde026a -/classes/models/LengowPaymentModule.php|b2bf40358df612a8b5d883685b69dfc3 -/classes/models/LengowOrderLine.php|b06e79bf48beffebb7ecfbcbff3560b1 -/classes/models/LengowOrderError.php|ee49194afa24deff08a2c2ea85729747 -/classes/models/LengowMarketplace.php|f8c1e1611e7f1c63dd358aa7991cfabb -/classes/models/LengowHook.php|7df3b1ea5e6dc0839fd7dfe4d8441b3d -/classes/models/LengowSync.php|68491bce2b3bab10b343065e00032dec -/classes/models/LengowCatalog.php|48fb568b8823482ef6b1e7bc48122300 -/classes/models/LengowAction.php|b8b64bc201c570996965ca3de66ba35a -/classes/models/LengowExport.php|d5fcb88fa350c8dd0a3870b8cedb4821 -/classes/models/LengowLink.php|d658ea39cfbae6deefe2069fd92ad4fa -/classes/models/LengowFile.php|5a58b3cf03a99bfeb305abe048799206 -/classes/models/LengowOrderCarrier.php|593f0e1ff6bc9611739de14b8f3d192a -/classes/models/LengowMethod.php|38595a8040e1f13ff4f3a17b94e9100a -/classes/models/LengowConnector.php|97805c39f27ff054889fd7352976fdef -/classes/models/LengowTranslation.php|a3cf23bc8af338976a392f9d0bb146ca -/classes/models/LengowMain.php|afdec4a9df1a0f44c86741d7f3231010 -/classes/models/LengowCustomer.php|54167dfa1c72210b8b69c74e4f9c5a0d -/classes/models/LengowShop.php|9f2898b82329096caedba902a30a0a6a -/classes/models/LengowLog.php|5ca3e0b79356d72945bb5fe721f4f246 -/classes/models/LengowImport.php|ac86ee09513ddd370a35647f7f014ebb -/classes/models/LengowGender.php|ea44d0c65c0bef2f1925bd78cf1d91ed -/classes/models/LengowConfiguration.php|e5ede4b56406d07be67f5742224e4644 -/classes/models/LengowToolbox.php|16c719778050e0492cbed92d2adf75e1 -/classes/models/LengowException.php|8beecbf00b5c1c047ee19af552903439 -/classes/models/index.php|a90243841e2e64a4ee2965d4dfa12491 -/classes/models/LengowProduct.php|bb6755974e5976c4f67af477a0e8747e -/classes/models/LengowAddress.php|ec593b179a1db4b625aa34539f841419 -/classes/models/LengowFeed.php|0b1cac677bebaff745d54e60d20ef84e -/classes/controllers/LengowMainSettingController.php|302aaed85a09d49dd92da005146f4165 -/classes/controllers/LengowToolboxController.php|48c875b7c202a21c9b5ee07e9ddbd4ae -/classes/controllers/LengowOrderSettingController.php|f8bc2c6cbf256babfcc99dd49d6bafa4 +/classes/controllers/LengowOrderController.php|1e4c0b35f3334e69406d9e16c7c70b29 +/classes/controllers/LengowDashboardController.php|ebe6a9d71e4a9be250061d96ec23b9ca /classes/controllers/LengowLegalsController.php|14effece7503b9524c83f628d255d146 -/classes/controllers/LengowController.php|4d3025edb706f3b10210a06e807fd2dc -/classes/controllers/LengowFeedController.php|b9a4e1bfe6836ad7a648de8a2a79bf77 +/classes/controllers/LengowController.php|e4d8bbb3a4d2212e138f8d67dbd1dcd7 +/classes/controllers/LengowToolboxController.php|292b629d678c2743e0050782e73ace07 /classes/controllers/LengowHelpController.php|e0b813a636dcf6a6910e8a2c7199931c -/classes/controllers/LengowDashboardController.php|60b83659efdecee33637ec4c0999aae3 +/classes/controllers/LengowMainSettingController.php|bbd1135a358b667bd922acd101104a05 +/classes/controllers/LengowOrderSettingController.php|4cd5566fa9340122be65d84ae50d2e63 +/classes/controllers/LengowHomeController.php|60caf882f1b38928c27164b913ad4159 /classes/controllers/index.php|a90243841e2e64a4ee2965d4dfa12491 -/classes/controllers/LengowHomeController.php|124a1bb77383394555206b022b67a1ad -/classes/controllers/LengowOrderController.php|44d74f87d0fe95d5845df690d36f9d14 +/classes/controllers/LengowFeedController.php|41b4db4ac3a070ee3cc599044b51f75d +/classes/models/LengowCustomer.php|78579376c21dce9dcea169e642d9802c +/classes/models/LengowHook.php|7e17d9ebfa664d8689fec493745a3900 +/classes/models/LengowOrderDetail.php|a51019c529e83b2f0eda9e8d713dbd3d +/classes/models/LengowImport.php|9a106938d503900de7807abf00ac9c6f +/classes/models/LengowInstall.php|be765799d993e72a2656cb2f84f81579 +/classes/models/LengowConfiguration.php|25df6dedabd775a60420e8c263751278 +/classes/models/LengowMain.php|058ddf81649f4a53b93bddefaa6f4129 +/classes/models/LengowAction.php|0e51cdaa86b88539c40c7c5273fb8c0d +/classes/models/LengowOrder.php|e7d80bb7b25ca35d2d5958ad71aaf26d +/classes/models/LengowList.php|071e3d48dfe8f4517374bc57718059b5 +/classes/models/LengowOrderCarrier.php|130bddda8e7a344fc2153cb1d55b58f3 +/classes/models/LengowOrderError.php|7ab270578749382990d67e7dcc3c3d50 +/classes/models/LengowImportOrder.php|1aedede7194e7c832405f86eb7451902 +/classes/models/LengowMarketplace.php|a2175dbe84b063c5097745e13dacb025 +/classes/models/LengowMethod.php|fad805cab01bc5ad136066b65e265f3d +/classes/models/LengowToolbox.php|0a7e1d3cd33ccaa8948c8c48b1893617 +/classes/models/LengowProduct.php|9a53599f08f1b931ed462e1887722deb +/classes/models/LengowContext.php|af29b1a24c96ee0dbc6f49ff8ad2f812 +/classes/models/LengowGender.php|13bcb15e024a66ceb8635ac848a50cc9 +/classes/models/LengowPaymentModule.php|5df1a660dd421bcb3dfa7681f5314ec6 +/classes/models/LengowNameParser.php|511cc42f9879b1c4d46a0416280f7382 +/classes/models/LengowFeed.php|58a3d6efa4c7114e6925abce293c6eab +/classes/models/LengowOrderLine.php|34d8c9facb15fe65eae3492cfb0065f8 +/classes/models/LengowSync.php|0a1a7b2e3922fd50e5768d7846e17175 +/classes/models/LengowExport.php|a5e89e32339b8b6d0c84beeff2f5fedb +/classes/models/LengowLink.php|bdbc53d7f8c0d25ded5203e321c2933c +/classes/models/LengowConnector.php|0746d2e0d7b4de082f5447567392444d +/classes/models/LengowTranslation.php|8664ba0942d6ebaee4e66384df308a1f +/classes/models/LengowFile.php|b49c051be110d6dd977826d9c5076fea +/classes/models/LengowAddress.php|59d6f28bc5dfc1ba4582a416564785e5 +/classes/models/LengowToolboxElement.php|592fde24e684de58b4a81936f23866b9 +/classes/models/LengowConfigurationForm.php|d8ecc896f125b531cb12e4ed09d0658f +/classes/models/LengowLog.php|36d1d903fedfa5c571134c0af4b63fee +/classes/models/LengowCatalog.php|07c15f25bb0905335f9a64a49d318be5 +/classes/models/LengowException.php|8beecbf00b5c1c047ee19af552903439 +/classes/models/LengowCarrier.php|550bea36d8b683bc250934a8532529dc +/classes/models/index.php|a90243841e2e64a4ee2965d4dfa12491 +/classes/models/LengowBackup.php|5e5baf9145d919f8c0fd43990b883315 +/classes/models/LengowCart.php|9e369126c3fd70bf168f962fc6aa50f6 +/classes/models/LengowCountry.php|d842caedcd144ae3a02144958804176c +/classes/models/LengowShop.php|988978cd8bbf3d7c47f41a91069811d9 /classes/index.php|a90243841e2e64a4ee2965d4dfa12491 -/controllers/admin/AdminLengowHomeController.php|01a450088f055ac12f56201534732f19 -/controllers/admin/AdminLengowLegalsController.php|c61e9ab8da13e272606369772448b0c7 -/controllers/admin/AdminLengowMainSettingController.php|cb8b24a5405860c955a6e56faba62d08 -/controllers/admin/AdminLengowOrderSettingController.php|1b8c3ea8b3797fd1d4b7fe2afeb375a9 -/controllers/admin/AdminLengowHelpController.php|d17ee58a9f6d2ebd84d55e76e4fd6055 -/controllers/admin/AdminLengowFeedController.php|4e7db60977fb58dc257a8be90245b637 -/controllers/admin/AdminLengowOrderController.php|3f287ca4f413ed8256694d45f873980f -/controllers/admin/AdminLengowDashboardController.php|e996a37046ab4b400a942c20c0310a7d -/controllers/admin/index.php|be8b25f88c14bddd7711e4585ebae316 -/controllers/admin/AdminLengowToolboxController.php|f40e82431eb689c849552a37cdf3da5a +/controllers/front/toolbox.php|a2cd0079e8f9dd10299f23d168ac8415 +/controllers/front/cron.php|68e3491c3707d292ad012e36cc64f657 +/controllers/front/export.php|e01edb71f72fbda565f761185630d4e6 +/controllers/front/index.php|32ed9f6c9b16b5f98fb812d3feb7e086 /controllers/index.php|be8b25f88c14bddd7711e4585ebae316 -/mails/en/report.html|aa21eced7789f09a68ca474b04cc431e -/mails/en/index.php|be8b25f88c14bddd7711e4585ebae316 -/mails/en/report.txt|de4160ab037db7fa1806b1dabe546a60 -/mails/nl/report.html|aa21eced7789f09a68ca474b04cc431e -/mails/nl/index.php|be8b25f88c14bddd7711e4585ebae316 /mails/nl/report.txt|de4160ab037db7fa1806b1dabe546a60 -/mails/fr/report.html|aa21eced7789f09a68ca474b04cc431e -/mails/fr/index.php|be8b25f88c14bddd7711e4585ebae316 -/mails/fr/report.txt|de4160ab037db7fa1806b1dabe546a60 -/mails/it/report.html|aa21eced7789f09a68ca474b04cc431e -/mails/it/index.php|be8b25f88c14bddd7711e4585ebae316 +/mails/nl/index.php|be8b25f88c14bddd7711e4585ebae316 +/mails/nl/report.html|aa21eced7789f09a68ca474b04cc431e /mails/it/report.txt|de4160ab037db7fa1806b1dabe546a60 -/mails/gb/report.html|aa21eced7789f09a68ca474b04cc431e -/mails/gb/index.php|be8b25f88c14bddd7711e4585ebae316 -/mails/gb/report.txt|de4160ab037db7fa1806b1dabe546a60 -/mails/sv/report.html|aa21eced7789f09a68ca474b04cc431e -/mails/sv/index.php|be8b25f88c14bddd7711e4585ebae316 -/mails/sv/report.txt|de4160ab037db7fa1806b1dabe546a60 -/mails/es/report.html|aa21eced7789f09a68ca474b04cc431e -/mails/es/index.php|be8b25f88c14bddd7711e4585ebae316 +/mails/it/index.php|be8b25f88c14bddd7711e4585ebae316 +/mails/it/report.html|aa21eced7789f09a68ca474b04cc431e /mails/es/report.txt|de4160ab037db7fa1806b1dabe546a60 -/mails/de/report.html|aa21eced7789f09a68ca474b04cc431e -/mails/de/index.php|be8b25f88c14bddd7711e4585ebae316 -/mails/de/report.txt|de4160ab037db7fa1806b1dabe546a60 -/mails/pt/report.html|aa21eced7789f09a68ca474b04cc431e -/mails/pt/index.php|be8b25f88c14bddd7711e4585ebae316 +/mails/es/index.php|be8b25f88c14bddd7711e4585ebae316 +/mails/es/report.html|aa21eced7789f09a68ca474b04cc431e +/mails/en/report.txt|de4160ab037db7fa1806b1dabe546a60 +/mails/en/index.php|be8b25f88c14bddd7711e4585ebae316 +/mails/en/report.html|aa21eced7789f09a68ca474b04cc431e +/mails/sv/report.txt|de4160ab037db7fa1806b1dabe546a60 +/mails/sv/index.php|be8b25f88c14bddd7711e4585ebae316 +/mails/sv/report.html|aa21eced7789f09a68ca474b04cc431e /mails/pt/report.txt|de4160ab037db7fa1806b1dabe546a60 +/mails/pt/index.php|be8b25f88c14bddd7711e4585ebae316 +/mails/pt/report.html|aa21eced7789f09a68ca474b04cc431e +/mails/gb/report.txt|de4160ab037db7fa1806b1dabe546a60 +/mails/gb/index.php|be8b25f88c14bddd7711e4585ebae316 +/mails/gb/report.html|aa21eced7789f09a68ca474b04cc431e +/mails/de/report.txt|de4160ab037db7fa1806b1dabe546a60 +/mails/de/index.php|be8b25f88c14bddd7711e4585ebae316 +/mails/de/report.html|aa21eced7789f09a68ca474b04cc431e /mails/index.php|be8b25f88c14bddd7711e4585ebae316 -/upgrade/update_3.7.1.php|ce9aab786524b099812b619237f950df -/upgrade/update_3.0.0.php|f1f09d1725b39114b4fa4e51583668c3 +/mails/fr/report.txt|de4160ab037db7fa1806b1dabe546a60 +/mails/fr/index.php|be8b25f88c14bddd7711e4585ebae316 +/mails/fr/report.html|aa21eced7789f09a68ca474b04cc431e /upgrade/update_3.0.1.php|715cedb6c2f1d9651e84ea2a6b54939d +/upgrade/update_3.0.2.php|ee99924a6b556bd82ee52f7966f45bac +/upgrade/update_3.7.1.php|ce9aab786524b099812b619237f950df +/upgrade/update_3.7.0.php|ce9aab786524b099812b619237f950df /upgrade/update_3.2.3.php|7c168fc6b974f17dea3f4879acee71d6 /upgrade/update_3.2.2.php|192eb7b032dead89666ffe41b1ba8646 -/upgrade/update_3.7.0.php|ce9aab786524b099812b619237f950df /upgrade/index.php|a90243841e2e64a4ee2965d4dfa12491 -/upgrade/update_3.0.2.php|ee99924a6b556bd82ee52f7966f45bac -/views/img/laser-gun.png|5b09dfd39f2c17e6e818e79fdf8c03c0 -/views/img/carret-down.png|f54e84c999caf3849f56fcf6537141bc -/views/img/plug-grey.png|4231ef1a002a23decaa0e3e292a417fc +/upgrade/update_3.0.0.php|f1f09d1725b39114b4fa4e51583668c3 +/views/img/connection-module.png|edb3364c8b46d07cbaa7192944f01475 +/views/img/carret-up.png|3e14398dbf0566a04e32160d61fb0dd8 +/views/img/connected-lengow.png|0a6a7a3e04ed7f6281f7c24a25cae074 +/views/img/modal-close.png|32cadb3a7cfff33ff4d79b53b817f8e2 /views/img/search.png|7f9b41e3ae4871543c2962369b9de277 -/views/img/tick.png|93392d528788c75f2c61f48632e3a93e -/views/img/connected-prestashop.png|190c1dd936024ad8bb95d42491e7fe1e -/views/img/bag.png|d812d529e1b5404cf7b92d4f36ab7abd -/views/img/flag/GI.png|ecfd4b85afd85b8bf8c531f8e6255cae -/views/img/flag/GM.png|d5273ab5a2bb48c0678db55894849363 -/views/img/flag/GS.png|fcfa6d9375d344cdad3cba278059f9dc -/views/img/flag/TF.png|cc1fc719aa70170cf59aa97989f32fca -/views/img/flag/MG.png|1d31e4ce165056179bbe39248a7170cc -/views/img/flag/MU.png|026a9a35bf226c5466e85912d37c80ec -/views/img/flag/CN.png|9e22cff886b227b7c66a7299cee60c4a -/views/img/flag/EG.png|22e30f3af14155502c2f4a4819bcf799 -/views/img/flag/UZ.png|9cd7f3e20f89d37e4a2854f30622d27a -/views/img/flag/CZ.png|c29892cb415d8489c5e4024a867fe8b6 -/views/img/flag/GA.png|334f0731d029c587625f0b7b98e6e17d -/views/img/flag/PT.png|2e7c7be8522b84c10ac8c584c3932fab -/views/img/flag/DO.png|7ca29ece3c9d65228080ba12e0be8940 -/views/img/flag/BQ.png|f9da0a905e9fec2ff6a12d52b0bae61c -/views/img/flag/IR.png|304c0bf838a4fbc343b85f2a0c252d1b -/views/img/flag/ER.png|098530d2dfadf464e46eeb7b67f88391 -/views/img/flag/HR.png|24cb403f2615ba725761dfbbcb843cfa -/views/img/flag/HM.png|ab3991ad7489bf384fb5446222bb48c6 -/views/img/flag/BF.png|80b84a563590f903257bfe44f1332870 -/views/img/flag/DJ.png|5ddb0d34fd83107a3d83e18880fa0305 +/views/img/plane.png|7d27896af3e0f3cf6e353cccef8f8267 +/views/img/home-products.png|99ff45448ea094f8c70b58a0cd4d9303 +/views/img/flag/MS.png|ecfd4b85afd85b8bf8c531f8e6255cae +/views/img/flag/TG.png|e2cf3a5f662ba166b85bf7a224d9ded9 +/views/img/flag/KW.png|04474a00fd44b8c39fcce5cb6f2b94f7 +/views/img/flag/PH.png|38df9e3c0944ffe4d5b015be95793be5 +/views/img/flag/MD.png|2b7d7b14d52f8fe8d800c000f2ddd0a9 +/views/img/flag/LB.png|a40045be63d6f413ff91c9b5867aa880 +/views/img/flag/SE.png|b8e45aecfb0ad66627b731f7d5fee095 +/views/img/flag/AS.png|6e81163a35de2f77ef3feb9ff4c36819 +/views/img/flag/DK.png|4c8c04806671345cacfabbd0781aaa64 /views/img/flag/PS.png|f9f7ff5e3c9d12173aca821154719f7e +/views/img/flag/NL.png|f9da0a905e9fec2ff6a12d52b0bae61c +/views/img/flag/CN.png|9e22cff886b227b7c66a7299cee60c4a /views/img/flag/LC.png|92badafa246492aed1cffb0bb913a21b -/views/img/flag/MN.png|6b459e34b09e6eb540ca41ff45f5d978 -/views/img/flag/SZ.png|cba65b0b5c6d94904dcba4f3150c5ca8 -/views/img/flag/GY.png|ab7cebdcd0f057c92edb1d92d4c45ed1 -/views/img/flag/TA.png|ecfd4b85afd85b8bf8c531f8e6255cae -/views/img/flag/ME.png|b9d7ebeaa14eaf5c2132098e57ac3b3a -/views/img/flag/LR.png|88412f2e2d5322bdd1d10f011fda38e3 -/views/img/flag/AG.png|3e96767508f891bee4e18b0879197059 -/views/img/flag/AU.png|ab3991ad7489bf384fb5446222bb48c6 +/views/img/flag/KP.png|6b12eacf3bd315e433ba0b1eacf9d802 +/views/img/flag/BR.png|8f5c8e3aec893ab67e226a15db7cf0c0 +/views/img/flag/SH.png|ecfd4b85afd85b8bf8c531f8e6255cae +/views/img/flag/MU.png|026a9a35bf226c5466e85912d37c80ec +/views/img/flag/CR.png|fb27f4596f9ac16b951e0f017dbeaa2b +/views/img/flag/SL.png|262fe618a191d0d8a60bc364746d3c04 +/views/img/flag/UY.png|bb2ddc17d73acbc625c0ec8ab5ff51c4 +/views/img/flag/GB.png|ecfd4b85afd85b8bf8c531f8e6255cae +/views/img/flag/PT.png|2e7c7be8522b84c10ac8c584c3932fab +/views/img/flag/AQ.png|7b496e199605b532dba8319044097d7e +/views/img/flag/CX.png|3f3aba1069496a40934637cf4b4f766c +/views/img/flag/IE.png|6882a56174318552db95a58dc4bc295c +/views/img/flag/SR.png|0a74189d8580fae462170f51fdfd5b9b +/views/img/flag/MH.png|14bc97a69158b9c8b513b4b4adc6b861 +/views/img/flag/CF.png|5f181e4dc309c220174c64376759a89a +/views/img/flag/TZ.png|aeab49fe6ea2334ee06286245759f40a +/views/img/flag/PG.png|e13e005b63bc30978dc3e4232623e8d1 /views/img/flag/RO.png|0701088a3c572a894daa458455c957f1 -/views/img/flag/BD.png|ea5f4a802e6b2969197551c64750b9a6 -/views/img/flag/KE.png|ba0a3ef22e0a59d8db268ae25d4fcb77 -/views/img/flag/BO.png|4e5e360f3cfec693bddd39707f79254a -/views/img/flag/AF.png|49d77e12111afc3d4194ade2664d286f -/views/img/flag/LU.png|b30b097b3f764af26f3fc551e10b62fa -/views/img/flag/NZ.png|c9eb80f47846f678803710fd86e4fb91 -/views/img/flag/BB.png|a0a004f000c7ea6ab8d150959ac8d3fe -/views/img/flag/SS.png|83ab553ec6ed1454b5523b9bb5f9e4f9 -/views/img/flag/EC.png|061930954ddd6fb786cd4060f0876fce -/views/img/flag/PF.png|cc1fc719aa70170cf59aa97989f32fca /views/img/flag/GG.png|d104842e7f86efd100c0ee29a0fa40ca -/views/img/flag/GP.png|cc1fc719aa70170cf59aa97989f32fca -/views/img/flag/MH.png|14bc97a69158b9c8b513b4b4adc6b861 -/views/img/flag/KI.png|da6b34f01691dfaaad7424078d741a6a -/views/img/flag/BS.png|9bd57b913f78269f420d06006adc4881 -/views/img/flag/MO.png|9e22cff886b227b7c66a7299cee60c4a -/views/img/flag/MV.png|ba000bb35f554921cf272250f30c2e10 -/views/img/flag/CA.png|959ca28fd07235ef971d3ea388c16397 -/views/img/flag/MF.png|cc1fc719aa70170cf59aa97989f32fca -/views/img/flag/SD.png|fa421effd81aa5f626083d0b2474853b +/views/img/flag/KG.png|aa27c4a8269656e2b7e22ee2782869fd +/views/img/flag/GW.png|9103e6399b262a7ad40a5d06e0ea8ecd +/views/img/flag/TD.png|c09a11652d7215dbbb86b9f2e08e1eaa +/views/img/flag/PF.png|cc1fc719aa70170cf59aa97989f32fca +/views/img/flag/TC.png|1988184525b5d9410d8bbc07fca834c0 +/views/img/flag/EG.png|22e30f3af14155502c2f4a4819bcf799 +/views/img/flag/TL.png|e782b6cfd00d15f709104755f400a578 +/views/img/flag/ML.png|a902428bbc6d2e20381b5f4a58ffc750 +/views/img/flag/MP.png|6c26816f5aaeae7d369b60fce14da9db +/views/img/flag/IO.png|1c5a9a59d014fad88383a6d864458bc8 +/views/img/flag/GN.png|37244e09a030931a398207bbed599818 +/views/img/flag/JM.png|3d54284d8d3cb58632a152175cb42866 +/views/img/flag/AO.png|835be1589972b119e2a3aea772e21a18 +/views/img/flag/NO.png|e3fa15f998178a590461f1fc6a0d2de8 +/views/img/flag/HM.png|ab3991ad7489bf384fb5446222bb48c6 +/views/img/flag/TH.png|04ae701cf5d13862c0badd8f931844b6 +/views/img/flag/HN.png|e969c09f78ba886511b46ac692d9f204 /views/img/flag/SX.png|f9da0a905e9fec2ff6a12d52b0bae61c -/views/img/flag/SO.png|053a1a934a1e0e0e3c4b455c3a0bf1db -/views/img/flag/JR.png|532ea8b20fa31e751d81f819d1e6774d -/views/img/flag/CK.png|3859da524e0ff3fedf39784da126a647 -/views/img/flag/KY.png|ecfd4b85afd85b8bf8c531f8e6255cae +/views/img/flag/VG.png|cd80422040f3569cdee8fe37c9ac233b +/views/img/flag/ET.png|a8ccdaec951da596214f55351e1ce618 +/views/img/flag/GA.png|334f0731d029c587625f0b7b98e6e17d +/views/img/flag/ME.png|b9d7ebeaa14eaf5c2132098e57ac3b3a +/views/img/flag/TT.png|3dd6607f691fdc7244b08e30f9cb5266 +/views/img/flag/NP.png|3885515ee4827a6d374e0bbcc3ddaaef /views/img/flag/DM.png|863a58ff3765e2285d6b2f519620640e +/views/img/flag/TF.png|cc1fc719aa70170cf59aa97989f32fca +/views/img/flag/JR.png|532ea8b20fa31e751d81f819d1e6774d +/views/img/flag/BB.png|a0a004f000c7ea6ab8d150959ac8d3fe +/views/img/flag/PW.png|b5ae6117e7e8c6c506f4ec2bed045e33 +/views/img/flag/AG.png|3e96767508f891bee4e18b0879197059 +/views/img/flag/VN.png|8c03bf96d845425cda900ed4cf965193 /views/img/flag/JE.png|3d4f6a61cc22ad5a77b4cbe36c26c9d7 -/views/img/flag/LK.png|4af94d1108d1dbd3daee42e5d7027e73 +/views/img/flag/HT.png|3dd1a60ae95e7348b00fa8c1bffd0258 +/views/img/flag/TJ.png|725785afd7652b97fc79b9f9a2219759 +/views/img/flag/AU.png|ab3991ad7489bf384fb5446222bb48c6 +/views/img/flag/KZ.png|1944b754503564c281ce18e5902229e9 +/views/img/flag/MX.png|4585eaa23399ff97b0edddebc9548733 /views/img/flag/VU.png|cade21feef734a691c19396d4cacd4d4 -/views/img/flag/JM.png|3d54284d8d3cb58632a152175cb42866 -/views/img/flag/UG.png|2e03029719fda3470ee6263150a7466b -/views/img/flag/SB.png|bf3795be21421952a58ca2039aaaf5b5 +/views/img/flag/GI.png|ecfd4b85afd85b8bf8c531f8e6255cae +/views/img/flag/GR.png|1490aa27b7e0f14ac0757139cf3804fa +/views/img/flag/AT.png|d94ad12cbb42e07163dad620027b3a80 +/views/img/flag/KR.png|26ddd3e45a9a097d781fd1c9cfddc468 +/views/img/flag/NI.png|7f337fe073caff1ecb41acae6a9d1e3d +/views/img/flag/JP.png|e6f8733f45d9c7ac9dcf834aba625cbb +/views/img/flag/BS.png|9bd57b913f78269f420d06006adc4881 +/views/img/flag/UM.png|6c26816f5aaeae7d369b60fce14da9db +/views/img/flag/PL.png|08b70dfd937f53fc448e084334df133d +/views/img/flag/AW.png|ec19a347739ea0e70970e2a604614837 /views/img/flag/BL.png|cc1fc719aa70170cf59aa97989f32fca -/views/img/flag/BA.png|0ca33f9b22f6317781e167a74843a19e -/views/img/flag/NR.png|0d5e83ccb1ccd3a8f02fc61acaa6e47b -/views/img/flag/SY.png|5f25bd15bf8a63c5f55b36a63ad029b5 -/views/img/flag/GQ.png|a3535b533b2af91719ba770f308ceb67 -/views/img/flag/KG.png|aa27c4a8269656e2b7e22ee2782869fd -/views/img/flag/IL.png|ca066a0cb246da38676b6a4930b29971 -/views/img/flag/AR.png|2c0793e851675c4178e6c623bedada68 -/views/img/flag/CG.png|fd66daf57f1a96e802ba44b07ce712c8 -/views/img/flag/KW.png|04474a00fd44b8c39fcce5cb6f2b94f7 -/views/img/flag/NF.png|380b2fedcc87649ed83992a0e8fcfcc8 -/views/img/flag/KN.png|73c41ac33b42de3aa30fca903333f7fb -/views/img/flag/MC.png|85754149e4307e821f27c80389263d6e -/views/img/flag/AQ.png|7b496e199605b532dba8319044097d7e -/views/img/flag/TR.png|ae9e141ce534888b8b298f3a63d36e38 -/views/img/flag/FO.png|0268b567af566647f953d8c3524c9ca7 -/views/img/flag/NE.png|fc09575c0fabcb08e083e2b25f8e4343 -/views/img/flag/TT.png|3dd6607f691fdc7244b08e30f9cb5266 -/views/img/flag/CH.png|d3f7ffa92fc89d18ecf93a210dcbd046 -/views/img/flag/IM.png|9a71aa37ec75db5858d66cf3a9a943f4 -/views/img/flag/ZA.png|55dc8a9767f651d0c1f81dc47580f5d8 -/views/img/flag/MX.png|4585eaa23399ff97b0edddebc9548733 -/views/img/flag/GH.png|748acbf0e69a5b10243d3ef200d9ea7f -/views/img/flag/VE.png|60739b59a02254e88e103f154f434087 -/views/img/flag/IE.png|6882a56174318552db95a58dc4bc295c -/views/img/flag/SV.png|7f337fe073caff1ecb41acae6a9d1e3d -/views/img/flag/SN.png|1a524290e23411b9f33e2e4426cb2d40 -/views/img/flag/PW.png|b5ae6117e7e8c6c506f4ec2bed045e33 -/views/img/flag/PH.png|38df9e3c0944ffe4d5b015be95793be5 -/views/img/flag/PY.png|47ba6b57d21f58b4e206251230b19ac8 +/views/img/flag/SB.png|bf3795be21421952a58ca2039aaaf5b5 /views/img/flag/NG.png|bd9daa305a8a954cffaff6649a464b5d -/views/img/flag/HT.png|3dd1a60ae95e7348b00fa8c1bffd0258 -/views/img/flag/MT.png|a31f908619bd13739d39dfca7d3900a4 -/views/img/flag/KP.png|6b12eacf3bd315e433ba0b1eacf9d802 -/views/img/flag/BH.png|4c735715f2b57bf14008bc277ba43c51 -/views/img/flag/NO.png|e3fa15f998178a590461f1fc6a0d2de8 -/views/img/flag/RW.png|3c21dcfbee72c5a9229317ba9e3b9cdb -/views/img/flag/IT.png|42d6ced0776d3c3ea8295b704202ff44 -/views/img/flag/RS.png|6e44d2f1b54aeb9f6a470796c05307b8 -/views/img/flag/PM.png|cc1fc719aa70170cf59aa97989f32fca -/views/img/flag/AL.png|5d34661c52bbda24fb4a49adf5ef82a0 -/views/img/flag/PL.png|08b70dfd937f53fc448e084334df133d -/views/img/flag/CC.png|7fecb4864f239d8d672d4dd0c780797c -/views/img/flag/MR.png|88251c8ae9701c1c130b51c206462216 -/views/img/flag/AD.png|ca92647387865e00fd0128eea3c0b3f0 -/views/img/flag/SJ.png|e3fa15f998178a590461f1fc6a0d2de8 +/views/img/flag/GM.png|d5273ab5a2bb48c0678db55894849363 /views/img/flag/PN.png|dc374e50b3c4d72a5663d422d276776a -/views/img/flag/RU.png|784a2a8638e99ff3e7d229be90b4f420 -/views/img/flag/PK.png|bb24b773e81e7daebc3ba3e263e67c20 +/views/img/flag/PY.png|47ba6b57d21f58b4e206251230b19ac8 +/views/img/flag/NZ.png|c9eb80f47846f678803710fd86e4fb91 +/views/img/flag/GT.png|d4b7180e1da0f1f2baede267bec4d045 +/views/img/flag/VE.png|60739b59a02254e88e103f154f434087 +/views/img/flag/GE.png|6ece075c9a93ba4cabbd65f015fa91b3 +/views/img/flag/MK.png|a58f238f52c62e8eb54fa6d056c37d38 +/views/img/flag/ZA.png|55dc8a9767f651d0c1f81dc47580f5d8 +/views/img/flag/SI.png|87f0819a7674137b062db99f7b888af7 +/views/img/flag/PR.png|587404b281120855ff304375851e3793 +/views/img/flag/CO.png|e9239e0e2019b75b50908273696037a5 +/views/img/flag/AD.png|ca92647387865e00fd0128eea3c0b3f0 +/views/img/flag/MO.png|9e22cff886b227b7c66a7299cee60c4a +/views/img/flag/EH.png|64c0643f5f65257b22dd3bb070d3acf5 +/views/img/flag/MT.png|a31f908619bd13739d39dfca7d3900a4 +/views/img/flag/FR.png|cc1fc719aa70170cf59aa97989f32fca +/views/img/flag/MN.png|6b459e34b09e6eb540ca41ff45f5d978 +/views/img/flag/LS.png|424c47d3ce5111e4f646abcfafc652be /views/img/flag/SA.png|fa0d37fefbcb03be08a96ff39c35e9fb +/views/img/flag/DZ.png|96aecc1300df553a35b3758e3ecfba3e +/views/img/flag/NF.png|380b2fedcc87649ed83992a0e8fcfcc8 +/views/img/flag/CA.png|959ca28fd07235ef971d3ea388c16397 +/views/img/flag/MF.png|cc1fc719aa70170cf59aa97989f32fca +/views/img/flag/GD.png|2f520ce09043643b7252eb0ce75a3d0c +/views/img/flag/IR.png|304c0bf838a4fbc343b85f2a0c252d1b +/views/img/flag/EE.png|9d2fe6fa37282535b72b5b4428e02a1d +/views/img/flag/SC.png|59f0b2fdc9c66ca24e723225fea73c3f +/views/img/flag/HK.png|9e22cff886b227b7c66a7299cee60c4a +/views/img/flag/PK.png|bb24b773e81e7daebc3ba3e263e67c20 /views/img/flag/BT.png|3d1dd6d51b8706976d8e52985f572dd1 -/views/img/flag/MZ.png|04cfeaaf203ceb1ffc56d95914956d3d -/views/img/flag/AX.png|6bfdcba08d5eac28c8b2f444d403fbd7 -/views/img/flag/SG.png|f0f0bb2bf6639e472ef6ff90f9eaf0c7 /views/img/flag/ZM.png|90feb476b1cf845ec389074f32585c34 -/views/img/flag/MW.png|eaadfcd54efd99816aa1e98cde55b48a -/views/img/flag/AZ.png|eed74a4b4d1d9320554380ecd298c603 -/views/img/flag/MD.png|2b7d7b14d52f8fe8d800c000f2ddd0a9 -/views/img/flag/HK.png|9e22cff886b227b7c66a7299cee60c4a -/views/img/flag/KH.png|0ffb252a38a5001bd776633c7d294063 +/views/img/flag/PM.png|cc1fc719aa70170cf59aa97989f32fca +/views/img/flag/JO.png|30a9129bf6502226ba7fd9da08e4b35c +/views/img/flag/GF.png|cc1fc719aa70170cf59aa97989f32fca +/views/img/flag/FK.png|38cba6706a7246740309b9ca0fbc0b73 +/views/img/flag/DO.png|7ca29ece3c9d65228080ba12e0be8940 +/views/img/flag/BE.png|a538d77b0d0e599095ca6db2ada1c2f3 +/views/img/flag/LK.png|4af94d1108d1dbd3daee42e5d7027e73 +/views/img/flag/ER.png|098530d2dfadf464e46eeb7b67f88391 +/views/img/flag/HR.png|24cb403f2615ba725761dfbbcb843cfa /views/img/flag/TN.png|fb43183a6891caf1600763cb51cde4a5 +/views/img/flag/BA.png|0ca33f9b22f6317781e167a74843a19e /views/img/flag/DE.png|d8cd6c8e3fa88c3a5d71aade7691711d -/views/img/flag/MY.png|1e8b313da9168f9b03b235d2952e142b -/views/img/flag/GB.png|ecfd4b85afd85b8bf8c531f8e6255cae -/views/img/flag/FM.png|6ade62bece03f1d514fdbccdda641de1 -/views/img/flag/HU.png|aa1de41f497f81700e4bbf862e3454ee -/views/img/flag/SR.png|0a74189d8580fae462170f51fdfd5b9b -/views/img/flag/ET.png|a8ccdaec951da596214f55351e1ce618 -/views/img/flag/AW.png|ec19a347739ea0e70970e2a604614837 -/views/img/flag/EE.png|9d2fe6fa37282535b72b5b4428e02a1d -/views/img/flag/MP.png|6c26816f5aaeae7d369b60fce14da9db -/views/img/flag/SC.png|59f0b2fdc9c66ca24e723225fea73c3f -/views/img/flag/IO.png|1c5a9a59d014fad88383a6d864458bc8 -/views/img/flag/LV.png|48efa49e2a85e9c077be41542ad17a1a +/views/img/flag/ST.png|c879c939fdce2c819a2f80f1680580d2 +/views/img/flag/GQ.png|a3535b533b2af91719ba770f308ceb67 +/views/img/flag/CD.png|1a91773608e0dc37943f2e3b64e2fd74 +/views/img/flag/CH.png|d3f7ffa92fc89d18ecf93a210dcbd046 +/views/img/flag/CL.png|6e05e10bbad0945a6a0ac4f72de351bd +/views/img/flag/EC.png|061930954ddd6fb786cd4060f0876fce +/views/img/flag/WF.png|cc1fc719aa70170cf59aa97989f32fca +/views/img/flag/AZ.png|eed74a4b4d1d9320554380ecd298c603 +/views/img/flag/AR.png|2c0793e851675c4178e6c623bedada68 +/views/img/flag/ZW.png|7d535d7ed7bb8fad8684610d869c4058 /views/img/flag/XK.png|6d8d386104193e251f4c3077e5bf5d3b /views/img/flag/BG.png|aad68b8269f4c43558b53089c6e42d71 -/views/img/flag/IC.png|6db63d7e4bee7add3ead8eb95c9668e8 -/views/img/flag/BN.png|54fbed23e5e0467e10530f00e5a53d8a -/views/img/flag/BV.png|2f9326738982ae4876fc7f0f0960c77e -/views/img/flag/PA.png|9407681f91e287935c4a7f987da34c63 -/views/img/flag/FK.png|38cba6706a7246740309b9ca0fbc0b73 -/views/img/flag/TJ.png|725785afd7652b97fc79b9f9a2219759 +/views/img/flag/SM.png|ad4c6e282255da7434889bd83a069286 +/views/img/flag/CM.png|7944de5a7885828172fe267c5f0bd666 +/views/img/flag/GL.png|4c8c04806671345cacfabbd0781aaa64 +/views/img/flag/SK.png|6bfe648618589d94ccad3c6e27aec692 +/views/img/flag/YE.png|393dee2beda492bbdae758640b615561 +/views/img/flag/LR.png|88412f2e2d5322bdd1d10f011fda38e3 +/views/img/flag/BZ.png|9481ccc9362b14353caa982b525793a8 +/views/img/flag/CY.png|eb2365a3603d60aff08f3c50cc87f249 +/views/img/flag/GY.png|ab7cebdcd0f057c92edb1d92d4c45ed1 +/views/img/flag/KI.png|da6b34f01691dfaaad7424078d741a6a +/views/img/flag/TR.png|ae9e141ce534888b8b298f3a63d36e38 +/views/img/flag/NR.png|0d5e83ccb1ccd3a8f02fc61acaa6e47b +/views/img/flag/KY.png|ecfd4b85afd85b8bf8c531f8e6255cae +/views/img/flag/LI.png|ba8539c6542d4d7e443a10f91bea414c /views/img/flag/BJ.png|e0db6fe266bf66ddebe037bc574a930d -/views/img/flag/SI.png|87f0819a7674137b062db99f7b888af7 -/views/img/flag/SL.png|262fe618a191d0d8a60bc364746d3c04 -/views/img/flag/TH.png|04ae701cf5d13862c0badd8f931844b6 -/views/img/flag/YT.png|cc1fc719aa70170cf59aa97989f32fca -/views/img/flag/US.png|96becb321dbd9e9fab92cf6b3c9b5163 -/views/img/flag/LY.png|cc1fe9b7e51a1ffa91c5f79d26043a25 -/views/img/flag/VN.png|8c03bf96d845425cda900ed4cf965193 -/views/img/flag/BE.png|a538d77b0d0e599095ca6db2ada1c2f3 -/views/img/flag/FI.png|6bfdcba08d5eac28c8b2f444d403fbd7 -/views/img/flag/GU.png|49c3a9df1fe4d853a0a5fc76e3270b20 -/views/img/flag/PG.png|e13e005b63bc30978dc3e4232623e8d1 -/views/img/flag/NP.png|3885515ee4827a6d374e0bbcc3ddaaef -/views/img/flag/UM.png|6c26816f5aaeae7d369b60fce14da9db -/views/img/flag/EH.png|64c0643f5f65257b22dd3bb070d3acf5 -/views/img/flag/TZ.png|aeab49fe6ea2334ee06286245759f40a -/views/img/flag/MA.png|b9214415961f794af1034dab0cace3b3 -/views/img/flag/TW.png|6ae84dc3a37d433ee650f0089a8e8f4f -/views/img/flag/KZ.png|1944b754503564c281ce18e5902229e9 -/views/img/flag/MS.png|ecfd4b85afd85b8bf8c531f8e6255cae +/views/img/flag/CC.png|7fecb4864f239d8d672d4dd0c780797c +/views/img/flag/OTHERS.png|ca92647387865e00fd0128eea3c0b3f0 +/views/img/flag/MC.png|85754149e4307e821f27c80389263d6e +/views/img/flag/MG.png|1d31e4ce165056179bbe39248a7170cc +/views/img/flag/FM.png|6ade62bece03f1d514fdbccdda641de1 +/views/img/flag/MY.png|1e8b313da9168f9b03b235d2952e142b +/views/img/flag/AI.png|59b67277582e2170cfe037c35ba4ed7a +/views/img/flag/FO.png|0268b567af566647f953d8c3524c9ca7 +/views/img/flag/UZ.png|9cd7f3e20f89d37e4a2854f30622d27a +/views/img/flag/BO.png|4e5e360f3cfec693bddd39707f79254a +/views/img/flag/CI.png|06b9dd31f9661b9a162857eef2f33cc2 /views/img/flag/MM.png|96647eab72c5fe93e4be84e1c5f3d7a7 -/views/img/flag/AO.png|835be1589972b119e2a3aea772e21a18 -/views/img/flag/LS.png|424c47d3ce5111e4f646abcfafc652be -/views/img/flag/LA.png|73e8e91f8cec75bc2cb582effb937212 -/views/img/flag/LT.png|6a8428cf97967d9726f9a78277fec777 -/views/img/flag/VC.png|04d50353949376995d0ca8827fd35241 +/views/img/flag/CU.png|4ba302408d9eddb58f79ef741668bf3b +/views/img/flag/CV.png|0e39eebc150f3825588ebd015b958372 +/views/img/flag/AL.png|5d34661c52bbda24fb4a49adf5ef82a0 /views/img/flag/UA.png|01969d09f7817a4ed6b9f152123fd5fa -/views/img/flag/BM.png|9dd3a4a2f7082b5ec1d62888cc091c49 -/views/img/flag/CO.png|e9239e0e2019b75b50908273696037a5 -/views/img/flag/TC.png|1988184525b5d9410d8bbc07fca834c0 -/views/img/flag/NA.png|17f102547f2ad6154227108af755dad2 -/views/img/flag/VG.png|cd80422040f3569cdee8fe37c9ac233b -/views/img/flag/TG.png|e2cf3a5f662ba166b85bf7a224d9ded9 -/views/img/flag/OM.png|03760a212630cc7c0e5471df8281355e -/views/img/flag/YE.png|393dee2beda492bbdae758640b615561 -/views/img/flag/TV.png|87b460b75260e3da93f06e56840a95b9 -/views/img/flag/SE.png|b8e45aecfb0ad66627b731f7d5fee095 -/views/img/flag/AS.png|6e81163a35de2f77ef3feb9ff4c36819 -/views/img/flag/ZW.png|7d535d7ed7bb8fad8684610d869c4058 -/views/img/flag/MK.png|a58f238f52c62e8eb54fa6d056c37d38 -/views/img/flag/QA.png|f38b2d29e8a446e5764d5258c8afd6eb -/views/img/flag/AN.png|a8c499377e0868f60a435229aa146fb1 +/views/img/flag/RU.png|784a2a8638e99ff3e7d229be90b4f420 +/views/img/flag/MA.png|b9214415961f794af1034dab0cace3b3 +/views/img/flag/BN.png|54fbed23e5e0467e10530f00e5a53d8a +/views/img/flag/IN.png|c1b8cf0460974ae1739a2f0ee72a0a36 /views/img/flag/TO.png|59a189738b32f9e766c913ed9296de03 -/views/img/flag/NI.png|7f337fe073caff1ecb41acae6a9d1e3d -/views/img/flag/GN.png|37244e09a030931a398207bbed599818 -/views/img/flag/CY.png|eb2365a3603d60aff08f3c50cc87f249 -/views/img/flag/NL.png|f9da0a905e9fec2ff6a12d52b0bae61c -/views/img/flag/OTHERS.png|ca92647387865e00fd0128eea3c0b3f0 -/views/img/flag/BR.png|8f5c8e3aec893ab67e226a15db7cf0c0 +/views/img/flag/IM.png|9a71aa37ec75db5858d66cf3a9a943f4 +/views/img/flag/MV.png|ba000bb35f554921cf272250f30c2e10 +/views/img/flag/LV.png|48efa49e2a85e9c077be41542ad17a1a +/views/img/flag/CG.png|fd66daf57f1a96e802ba44b07ce712c8 +/views/img/flag/IT.png|42d6ced0776d3c3ea8295b704202ff44 +/views/img/flag/GS.png|fcfa6d9375d344cdad3cba278059f9dc +/views/img/flag/YT.png|cc1fc719aa70170cf59aa97989f32fca +/views/img/flag/RW.png|3c21dcfbee72c5a9229317ba9e3b9cdb +/views/img/flag/US.png|96becb321dbd9e9fab92cf6b3c9b5163 +/views/img/flag/KM.png|130b19dbbed58a2896335af73c1a7ff2 +/views/img/flag/NA.png|17f102547f2ad6154227108af755dad2 +/views/img/flag/LA.png|73e8e91f8cec75bc2cb582effb937212 +/views/img/flag/TW.png|6ae84dc3a37d433ee650f0089a8e8f4f +/views/img/flag/NU.png|d89e7c94b030bb809a10231c0ee38e8e +/views/img/flag/LT.png|6a8428cf97967d9726f9a78277fec777 +/views/img/flag/PE.png|2213daa82fbd4344c53ed14272064ed3 +/views/img/flag/LU.png|b30b097b3f764af26f3fc551e10b62fa +/views/img/flag/KN.png|73c41ac33b42de3aa30fca903333f7fb +/views/img/flag/NE.png|fc09575c0fabcb08e083e2b25f8e4343 +/views/img/flag/SY.png|5f25bd15bf8a63c5f55b36a63ad029b5 +/views/img/flag/SO.png|053a1a934a1e0e0e3c4b455c3a0bf1db +/views/img/flag/BY.png|30eb3989b884d4aed254eef073a21e9f +/views/img/flag/BH.png|4c735715f2b57bf14008bc277ba43c51 +/views/img/flag/IC.png|6db63d7e4bee7add3ead8eb95c9668e8 +/views/img/flag/SS.png|83ab553ec6ed1454b5523b9bb5f9e4f9 +/views/img/flag/TA.png|ecfd4b85afd85b8bf8c531f8e6255cae +/views/img/flag/SG.png|f0f0bb2bf6639e472ef6ff90f9eaf0c7 /views/img/flag/AE.png|ea9875d8e8afafed9f07e63e7fae0b3d -/views/img/flag/SM.png|ad4c6e282255da7434889bd83a069286 -/views/img/flag/GF.png|cc1fc719aa70170cf59aa97989f32fca -/views/img/flag/GT.png|d4b7180e1da0f1f2baede267bec4d045 +/views/img/flag/FI.png|6bfdcba08d5eac28c8b2f444d403fbd7 +/views/img/flag/FJ.png|dabe04af951004527f0b1094cfd218d1 +/views/img/flag/VC.png|04d50353949376995d0ca8827fd35241 +/views/img/flag/GU.png|49c3a9df1fe4d853a0a5fc76e3270b20 +/views/img/flag/SJ.png|e3fa15f998178a590461f1fc6a0d2de8 /views/img/flag/ZZ.png|737e91fb2b9da9e69ab2495a49cce79d -/views/img/flag/CL.png|6e05e10bbad0945a6a0ac4f72de351bd +/views/img/flag/NC.png|cc1fc719aa70170cf59aa97989f32fca +/views/img/flag/BV.png|2f9326738982ae4876fc7f0f0960c77e +/views/img/flag/CK.png|3859da524e0ff3fedf39784da126a647 +/views/img/flag/PA.png|9407681f91e287935c4a7f987da34c63 +/views/img/flag/VA.png|14a0946355567991035d1c4a235b7890 +/views/img/flag/VI.png|e69dce8e3db81cbc4e43f41b41eb5de7 +/views/img/flag/BF.png|80b84a563590f903257bfe44f1332870 +/views/img/flag/SZ.png|cba65b0b5c6d94904dcba4f3150c5ca8 /views/img/flag/IQ.png|e80063e93b8c7a79490dfcfae80b6aae -/views/img/flag/ML.png|a902428bbc6d2e20381b5f4a58ffc750 -/views/img/flag/CD.png|1a91773608e0dc37943f2e3b64e2fd74 -/views/img/flag/CU.png|4ba302408d9eddb58f79ef741668bf3b -/views/img/flag/IS.png|e3afdbe32403f05ab6bed0acd8336604 +/views/img/flag/BW.png|5fb1b531e34de1e246560f3a9defefe2 /views/img/flag/WS.png|dbfe225a535339b992abd582c9e69037 -/views/img/flag/CM.png|7944de5a7885828172fe267c5f0bd666 -/views/img/flag/KM.png|130b19dbbed58a2896335af73c1a7ff2 +/views/img/flag/UG.png|2e03029719fda3470ee6263150a7466b +/views/img/flag/MW.png|eaadfcd54efd99816aa1e98cde55b48a /views/img/flag/BI.png|2bc04f56f098abfd22ec8dc9b4d25c6f -/views/img/flag/TD.png|c09a11652d7215dbbb86b9f2e08e1eaa -/views/img/flag/SH.png|ecfd4b85afd85b8bf8c531f8e6255cae -/views/img/flag/GR.png|1490aa27b7e0f14ac0757139cf3804fa -/views/img/flag/DZ.png|96aecc1300df553a35b3758e3ecfba3e -/views/img/flag/GE.png|6ece075c9a93ba4cabbd65f015fa91b3 -/views/img/flag/NU.png|d89e7c94b030bb809a10231c0ee38e8e -/views/img/flag/GD.png|2f520ce09043643b7252eb0ce75a3d0c -/views/img/flag/CV.png|0e39eebc150f3825588ebd015b958372 -/views/img/flag/PE.png|2213daa82fbd4344c53ed14272064ed3 -/views/img/flag/IN.png|c1b8cf0460974ae1739a2f0ee72a0a36 -/views/img/flag/CR.png|fb27f4596f9ac16b951e0f017dbeaa2b -/views/img/flag/MQ.png|cc1fc719aa70170cf59aa97989f32fca -/views/img/flag/AT.png|d94ad12cbb42e07163dad620027b3a80 -/views/img/flag/UY.png|bb2ddc17d73acbc625c0ec8ab5ff51c4 -/views/img/flag/BW.png|5fb1b531e34de1e246560f3a9defefe2 -/views/img/flag/CX.png|3f3aba1069496a40934637cf4b4f766c -/views/img/flag/ST.png|c879c939fdce2c819a2f80f1680580d2 -/views/img/flag/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/img/flag/VA.png|14a0946355567991035d1c4a235b7890 -/views/img/flag/NC.png|cc1fc719aa70170cf59aa97989f32fca -/views/img/flag/JP.png|e6f8733f45d9c7ac9dcf834aba625cbb -/views/img/flag/GL.png|4c8c04806671345cacfabbd0781aaa64 -/views/img/flag/LI.png|ba8539c6542d4d7e443a10f91bea414c -/views/img/flag/TM.png|58f31979cd5840ed53c4c0244226ad88 -/views/img/flag/CI.png|06b9dd31f9661b9a162857eef2f33cc2 +/views/img/flag/BD.png|ea5f4a802e6b2969197551c64750b9a6 +/views/img/flag/HU.png|aa1de41f497f81700e4bbf862e3454ee /views/img/flag/TK.png|3f70b39454fe3d56ea975185438edeb0 -/views/img/flag/BZ.png|9481ccc9362b14353caa982b525793a8 -/views/img/flag/BY.png|30eb3989b884d4aed254eef073a21e9f -/views/img/flag/WF.png|cc1fc719aa70170cf59aa97989f32fca +/views/img/flag/GH.png|748acbf0e69a5b10243d3ef200d9ea7f +/views/img/flag/SN.png|1a524290e23411b9f33e2e4426cb2d40 /views/img/flag/ID.png|85754149e4307e821f27c80389263d6e -/views/img/flag/FR.png|cc1fc719aa70170cf59aa97989f32fca -/views/img/flag/ES.png|6db63d7e4bee7add3ead8eb95c9668e8 -/views/img/flag/VI.png|e69dce8e3db81cbc4e43f41b41eb5de7 -/views/img/flag/GW.png|9103e6399b262a7ad40a5d06e0ea8ecd -/views/img/flag/DK.png|4c8c04806671345cacfabbd0781aaa64 -/views/img/flag/AI.png|59b67277582e2170cfe037c35ba4ed7a -/views/img/flag/SK.png|6bfe648618589d94ccad3c6e27aec692 +/views/img/flag/SD.png|fa421effd81aa5f626083d0b2474853b +/views/img/flag/index.php|be8b25f88c14bddd7711e4585ebae316 /views/img/flag/AM.png|3461136703e8e2b5dffe869e3e086ce1 -/views/img/flag/KR.png|26ddd3e45a9a097d781fd1c9cfddc468 -/views/img/flag/LB.png|a40045be63d6f413ff91c9b5867aa880 -/views/img/flag/FJ.png|dabe04af951004527f0b1094cfd218d1 -/views/img/flag/JO.png|30a9129bf6502226ba7fd9da08e4b35c -/views/img/flag/PR.png|587404b281120855ff304375851e3793 -/views/img/flag/TL.png|e782b6cfd00d15f709104755f400a578 -/views/img/flag/HN.png|e969c09f78ba886511b46ac692d9f204 -/views/img/flag/CF.png|5f181e4dc309c220174c64376759a89a +/views/img/flag/TV.png|87b460b75260e3da93f06e56840a95b9 +/views/img/flag/IL.png|ca066a0cb246da38676b6a4930b29971 +/views/img/flag/GP.png|cc1fc719aa70170cf59aa97989f32fca +/views/img/flag/DJ.png|5ddb0d34fd83107a3d83e18880fa0305 +/views/img/flag/AF.png|49d77e12111afc3d4194ade2664d286f +/views/img/flag/MQ.png|cc1fc719aa70170cf59aa97989f32fca +/views/img/flag/MR.png|88251c8ae9701c1c130b51c206462216 +/views/img/flag/LY.png|cc1fe9b7e51a1ffa91c5f79d26043a25 +/views/img/flag/ES.png|6db63d7e4bee7add3ead8eb95c9668e8 +/views/img/flag/KH.png|0ffb252a38a5001bd776633c7d294063 +/views/img/flag/BM.png|9dd3a4a2f7082b5ec1d62888cc091c49 +/views/img/flag/RS.png|6e44d2f1b54aeb9f6a470796c05307b8 +/views/img/flag/AX.png|6bfdcba08d5eac28c8b2f444d403fbd7 +/views/img/flag/QA.png|f38b2d29e8a446e5764d5258c8afd6eb +/views/img/flag/SV.png|7f337fe073caff1ecb41acae6a9d1e3d +/views/img/flag/BQ.png|f9da0a905e9fec2ff6a12d52b0bae61c +/views/img/flag/KE.png|ba0a3ef22e0a59d8db268ae25d4fcb77 +/views/img/flag/OM.png|03760a212630cc7c0e5471df8281355e +/views/img/flag/MZ.png|04cfeaaf203ceb1ffc56d95914956d3d /views/img/flag/RE.png|cc1fc719aa70170cf59aa97989f32fca -/views/img/unplugged.png|55b5eeee08952d538185a659abbbb932 -/views/img/clock.png|499ea8d7905f77624cb64b1af3f955b5 -/views/img/lengow-blue.png|33ff5e10a4ae11fd3c0fc780e1be15ea -/views/img/connection-module.png|edb3364c8b46d07cbaa7192944f01475 -/views/img/arrow-right.png|e56e5bb1dd1c9e23161dd7f0aa4293d2 -/views/img/modal-close.png|32cadb3a7cfff33ff4d79b53b817f8e2 -/views/img/carret-up.png|3e14398dbf0566a04e32160d61fb0dd8 +/views/img/flag/IS.png|e3afdbe32403f05ab6bed0acd8336604 +/views/img/flag/TM.png|58f31979cd5840ed53c4c0244226ad88 +/views/img/flag/CZ.png|c29892cb415d8489c5e4024a867fe8b6 +/views/img/flag/AN.png|a8c499377e0868f60a435229aa146fb1 +/views/img/connected-prestashop.png|190c1dd936024ad8bb95d42491e7fe1e +/views/img/bag.png|d812d529e1b5404cf7b92d4f36ab7abd +/views/img/plug-grey.png|4231ef1a002a23decaa0e3e292a417fc +/views/img/laser-gun.png|5b09dfd39f2c17e6e818e79fdf8c03c0 +/views/img/plugin-update.png|a350fb0045bd61298a90268d0026e022 /views/img/lengow-white.png|5de4e9d3f4037deb17f73b257504b102 -/views/img/box-close.png|73512c2351bfc39c6d10b95a3f2810c3 +/views/img/arrow-right.png|e56e5bb1dd1c9e23161dd7f0aa4293d2 /views/img/lengow-white-big.png|d55ced676fd66c03f5dd6ec637c1da15 +/views/img/lengow-blue.png|33ff5e10a4ae11fd3c0fc780e1be15ea /views/img/logo-blue.png|0d58de36da9bda59f6d3057d77ad9b76 -/views/img/home-products.png|99ff45448ea094f8c70b58a0cd4d9303 +/views/img/carret-down.png|f54e84c999caf3849f56fcf6537141bc +/views/img/tick.png|93392d528788c75f2c61f48632e3a93e /views/img/home-settings.png|4f7751e943137d3c10b71da358f7b1d7 +/views/img/box-close.png|73512c2351bfc39c6d10b95a3f2810c3 +/views/img/clock.png|499ea8d7905f77624cb64b1af3f955b5 +/views/img/unplugged.png|55b5eeee08952d538185a659abbbb932 /views/img/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/img/plane.png|7d27896af3e0f3cf6e353cccef8f8267 -/views/img/plugin-update.png|a350fb0045bd61298a90268d0026e022 -/views/img/connected-lengow.png|0a6a7a3e04ed7f6281f7c24a25cae074 /views/img/home-orders.png|db05b21ec6b166d844b42c0e807cb265 -/views/css/lengow-components.css|d8e1abd6cfd93e95c0c9cea6da0cc532 -/views/css/font-awesome.css|bf4b58c946c9234e4a6b9f7a70d38006 -/views/css/bootstrap-datepicker.css|d5260247b97663d887f4efe8ec894353 -/views/css/lengow-layout.css|768416b1c8fbc2d02f013f2bbee9ee5f -/views/css/lengow-pages.css|29a83763230d61367c09e5d61faf7d61 -/views/css/select2.css|8969ac4614d64a13dfc32e1eb4e731f7 -/views/css/lengow-tab.css|5b6066640ae15dce94cd2225d84cec50 -/views/css/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/fonts/fontawesome-webfont.woff|a35720c2fed2c7f043bc7e4ffb45e073 +/views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/Modal/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/PrestaShop/Admin/Sell/Order/Order/Blocks/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/PrestaShop/Admin/Sell/Order/Order/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/PrestaShop/Admin/Sell/Order/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/PrestaShop/Admin/Sell/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/PrestaShop/Admin/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/PrestaShop/index.php|be8b25f88c14bddd7711e4585ebae316 /views/fonts/fontawesome-webfont.woff2|db812d8a70a4e88e888744c1c9a27e89 -/views/fonts/fontawesome-webfont.ttf|a3de2170e4e9df77161ea5d3f31b2668 /views/fonts/FontAwesome.otf|87d8ca3ddc57e7d2da6226e480f90457 -/views/fonts/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/fonts/fontawesome-webfont.svg|f775f9cca88e21d45bebe185b27c0e5b +/views/fonts/fontawesome-webfont.ttf|a3de2170e4e9df77161ea5d3f31b2668 +/views/fonts/fontawesome-webfont.woff|a35720c2fed2c7f043bc7e4ffb45e073 /views/fonts/fontawesome-webfont.eot|32400f4e08932a94d8bfd2422702c446 -/views/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/lengow_feed/helpers/view/view.tpl|f60bd5669ed7ecf182c2073d044270fe -/views/templates/admin/lengow_feed/helpers/view/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/lengow_feed/helpers/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/lengow_feed/layout.tpl|8296463aac5333e3d045024628ee14d7 -/views/templates/admin/lengow_feed/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/lengow_order_setting/helpers/view/country_selector.tpl|a267b04ca30c63272a0518df44d2d132 -/views/templates/admin/lengow_order_setting/helpers/view/default_carrier.tpl|59082017288f80c73b1fde08de8fd088 -/views/templates/admin/lengow_order_setting/helpers/view/marketplace_matching.tpl|795fa9a03687067686437818681c1131 -/views/templates/admin/lengow_order_setting/helpers/view/marketplace_method.tpl|ebc5d69c98f9f796a83c1ae6a32420b0 -/views/templates/admin/lengow_order_setting/helpers/view/view.tpl|07ce03342ced4f4b9d8a505b790d891e -/views/templates/admin/lengow_order_setting/helpers/view/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/lengow_order_setting/helpers/view/marketplace_carrier.tpl|52c4ee9821380783e3816deb28f8f22f -/views/templates/admin/lengow_order_setting/helpers/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/lengow_order_setting/layout.tpl|901527885b6fdd8c04949bfe750e438d -/views/templates/admin/lengow_order_setting/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/header_order.tpl|452332339e744007db76a1c4e8ae5805 -/views/templates/admin/lengow_toolbox/helpers/view/view.tpl|d7f5ab6dca7d8abef5c987378bdc606a -/views/templates/admin/lengow_toolbox/helpers/view/index.php|8c05a3431d3dcff6cdbfb4890fcafeb2 -/views/templates/admin/lengow_toolbox/helpers/index.php|8c05a3431d3dcff6cdbfb4890fcafeb2 -/views/templates/admin/lengow_toolbox/layout.tpl|dce5c18c3f7ee6d8deb4b15ae67b9eed -/views/templates/admin/lengow_toolbox/index.php|8c05a3431d3dcff6cdbfb4890fcafeb2 -/views/templates/admin/footer.tpl|d2d993208162f4de715701b678b2606f -/views/templates/admin/lengow_home/helpers/view/connection_home.tpl|719d3053ad5fe0212ca04b836fe3ed15 -/views/templates/admin/lengow_home/helpers/view/connection_cms_result.tpl|a7bdfe86ab8654b2c0ece23fe5eee4e9 -/views/templates/admin/lengow_home/helpers/view/view.tpl|8e0c9ac0a8269c60c6ae2f64203f5d32 -/views/templates/admin/lengow_home/helpers/view/connection_catalog_failed.tpl|8dc9149312cf84a7f579508b69c7ae82 -/views/templates/admin/lengow_home/helpers/view/connection_cms.tpl|b9017bfcbb77996f2e307056ec476d91 -/views/templates/admin/lengow_home/helpers/view/connection_catalog.tpl|761994719aed4e1b7a115429b09d8fd4 +/views/fonts/fontawesome-webfont.svg|f775f9cca88e21d45bebe185b27c0e5b +/views/fonts/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/js/select2.js|2565df263f3a062418fb9ef1202d7e4e +/views/js/bootstrap.min.js|3584d6a859bebce245bae0a6e0606e2f +/views/js/clipboard.js|55db0ff82a3b6b247844ae0d07d85fc6 +/views/js/bootstrap-datepicker.js|5e12aafeadd2893b88641fa55e102dd7 +/views/js/lengow/order_setting.js|2bd3fe96012c29104f09b26f2a8fd926 +/views/js/lengow/toolbox.js|72db7b5a4e5b19702770ad899b5f3e9a +/views/js/lengow/home.js|1f2e8c28ae870b3476483d3759f76964 +/views/js/lengow/admin.js|62eeab452a15d83278e4d0c6dcdc50a1 +/views/js/lengow/main_setting.js|9489a296dc8ed80847c5990e1a6559f9 +/views/js/lengow/order.js|a0fc7953c8fa47b0436139fe9d966679 +/views/js/lengow/feed.js|e9fee6a905dff98bedd0d3599f5fa230 +/views/js/lengow/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/js/jquery.1.12.0.min.js|e63f1452800f328881a789956054aca3 +/views/js/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/lengow_help/view.html.twig|ac75f21ce360b309ed8e97f74fa9739c +/views/templates/admin/lengow_help/helpers/view/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/lengow_help/helpers/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/lengow_help/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/lengow_home/view.html.twig|ee4750eb0de808da6deb97835e56ddf9 +/views/templates/admin/lengow_home/helpers/view/connection_cms_result.html.twig|23a902c61b361e5247f18e41b16a4e73 +/views/templates/admin/lengow_home/helpers/view/connection_cms.html.twig|81094c513ff191843a9c048165fd09aa +/views/templates/admin/lengow_home/helpers/view/connection_home.html.twig|a774600317b19ed449c840704c68faa9 +/views/templates/admin/lengow_home/helpers/view/connection_catalog_failed.html.twig|0db14a7eb7f705cf5719680a2a5dc945 +/views/templates/admin/lengow_home/helpers/view/connection_catalog.html.twig|83af1a8fc959afd8d0268b36780dbcff /views/templates/admin/lengow_home/helpers/view/index.php|be8b25f88c14bddd7711e4585ebae316 /views/templates/admin/lengow_home/helpers/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/lengow_home/layout.tpl|d4e23ff27234d8621b4fc909e1aea5dd /views/templates/admin/lengow_home/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/lengow_order/helpers/view/no_order.tpl|806dda4cd3f405507f7e89046e222120 -/views/templates/admin/lengow_order/helpers/view/warning_message.tpl|821acd8febe35f9381d9462ed36e3fca -/views/templates/admin/lengow_order/helpers/view/view.tpl|c4dd33661b6ab2bfcaf4976f7c3c2732 -/views/templates/admin/lengow_order/helpers/view/last_importation.tpl|a8e4e40f74074b6f1a1a2318fab63f73 -/views/templates/admin/lengow_order/helpers/view/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/lengow_order/helpers/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/lengow_order/layout.tpl|901527885b6fdd8c04949bfe750e438d -/views/templates/admin/lengow_order/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/lengow_dashboard/helpers/view/status.tpl|1e6678a36f90f268f7d8fec583b22154 -/views/templates/admin/lengow_dashboard/helpers/view/dashboard.tpl|0951b2a85ef326dcd3d609e549f4625b -/views/templates/admin/lengow_dashboard/helpers/view/view.tpl|a568171b9cb074bd40eb038e74a1eba8 +/views/templates/admin/lengow_toolbox/view.html.twig|5abe57c8ee452c2154b4195b5feeb28a +/views/templates/admin/lengow_toolbox/helpers/view/index.php|8c05a3431d3dcff6cdbfb4890fcafeb2 +/views/templates/admin/lengow_toolbox/helpers/index.php|8c05a3431d3dcff6cdbfb4890fcafeb2 +/views/templates/admin/lengow_toolbox/index.php|8c05a3431d3dcff6cdbfb4890fcafeb2 +/views/templates/admin/lengow_feed/view.html.twig|e8724989bfa76762604bc627f7b75c13 +/views/templates/admin/lengow_feed/helpers/view/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/lengow_feed/helpers/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/lengow_feed/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/lengow_dashboard/view.html.twig|74d15f5dfed606982f7639ccc19ddd7d +/views/templates/admin/lengow_dashboard/helpers/view/dashboard.html.twig|175571a7d91434b4b5983179792d37ef +/views/templates/admin/lengow_dashboard/helpers/view/status.html.twig|3de233247bb523935d9815b4af09d709 /views/templates/admin/lengow_dashboard/helpers/view/index.php|eba0357470b4f2caf856c15f9ee875a0 /views/templates/admin/lengow_dashboard/helpers/index.php|eba0357470b4f2caf856c15f9ee875a0 -/views/templates/admin/lengow_dashboard/layout.tpl|89267905b72cffc708bb36c1c9bb1ca1 /views/templates/admin/lengow_dashboard/index.php|eba0357470b4f2caf856c15f9ee875a0 -/views/templates/admin/lengow_legals/helpers/view/view.tpl|f16dd97c1a6a5c475170492a0a851dc0 -/views/templates/admin/lengow_legals/helpers/view/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/lengow_legals/helpers/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/lengow_legals/layout.tpl|8296463aac5333e3d045024628ee14d7 -/views/templates/admin/lengow_legals/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/header.tpl|064d8925d83e23f681889828c402552f -/views/templates/admin/lengow_main_setting/helpers/view/view.tpl|6c982c3f0c4cad049ecc94594bd49642 +/views/templates/admin/lengow_main_setting/view.html.twig|6e830b0f6130a35a5c3e30f266c9bf39 /views/templates/admin/lengow_main_setting/helpers/view/index.php|be8b25f88c14bddd7711e4585ebae316 /views/templates/admin/lengow_main_setting/helpers/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/lengow_main_setting/layout.tpl|8296463aac5333e3d045024628ee14d7 /views/templates/admin/lengow_main_setting/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/lengow_help/helpers/view/view.tpl|922255f0c88cf95737dc8f46434bd806 -/views/templates/admin/lengow_help/helpers/view/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/lengow_help/helpers/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/admin/lengow_help/layout.tpl|8296463aac5333e3d045024628ee14d7 -/views/templates/admin/lengow_help/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/lengow_order_setting/view.html.twig|9e5271a47c865f5fa49213c5665c62d5 +/views/templates/admin/lengow_order_setting/helpers/view/marketplace_matching.html.twig|ac644436781a75c9eb7ce4deaedb03ff +/views/templates/admin/lengow_order_setting/helpers/view/country_selector.html.twig|ac29e562194e8495e3a7a2f5bebc0485 +/views/templates/admin/lengow_order_setting/helpers/view/marketplace_carrier.html.twig|7bd2bc1e67dd0db4e49aebf321e9df5b +/views/templates/admin/lengow_order_setting/helpers/view/marketplace_method.html.twig|683bda6c54f86a303dbdbd8ebbf9db7a +/views/templates/admin/lengow_order_setting/helpers/view/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/lengow_order_setting/helpers/view/default_carrier.html.twig|9875444050c7ce4089f037f0d632f6f6 +/views/templates/admin/lengow_order_setting/helpers/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/lengow_order_setting/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/twig/header.html.twig|ce5fcfbbb6174dd20c3195162032d178 +/views/templates/admin/twig/ps9_base.html.twig|ffe20427fc71b63dce2058eeb84473b7 +/views/templates/admin/twig/footer.html.twig|30db718af4997d59928f4c6d16ee0fc4 +/views/templates/admin/twig/header_order.html.twig|c2dc880a0a18fea802d4c2298566895a +/views/templates/admin/twig/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/twig/ps8_base.html.twig|bfa3900fffc28c257b07692055df0e4e +/views/templates/admin/lengow_legals/view.html.twig|2218ff4bee78e9ee159a2ff4cc61fd74 +/views/templates/admin/lengow_legals/helpers/view/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/lengow_legals/helpers/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/lengow_legals/index.php|be8b25f88c14bddd7711e4585ebae316 /views/templates/admin/order/info.tpl|af29d32a43c4709feab04d0ba90d0033 /views/templates/admin/order/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/hook/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/templates/hook/order/admin_order_side.tpl|88fc73bbfd960cc7b37165801151a387 -/views/templates/hook/order/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/lengow_order/view.html.twig|9f3a3e9f6d82022379dfb2e51cb7b23e +/views/templates/admin/lengow_order/helpers/view/last_importation.html.twig|88a48d8a27ad587491bb90bc1f5577f4 +/views/templates/admin/lengow_order/helpers/view/no_order.html.twig|4b09086b3ac6046e25d066a54a198243 +/views/templates/admin/lengow_order/helpers/view/warning_message.html.twig|ba3cc230e4eeb91d098dc47b3ad0b1f1 +/views/templates/admin/lengow_order/helpers/view/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/lengow_order/helpers/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/admin/lengow_order/index.php|be8b25f88c14bddd7711e4585ebae316 /views/templates/front/tagpage.tpl|f040d02eb2f79ed7d50e72f7f707db0e /views/templates/front/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/hook/order/admin_order_side.tpl|88fc73bbfd960cc7b37165801151a387 +/views/templates/hook/order/admin_order_tab.tpl|dde75b9aab71dec0b10131e2c4a3d361 +/views/templates/hook/order/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/templates/hook/index.php|be8b25f88c14bddd7711e4585ebae316 /views/templates/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/js/clipboard.js|55db0ff82a3b6b247844ae0d07d85fc6 -/views/js/select2.js|2565df263f3a062418fb9ef1202d7e4e -/views/js/bootstrap-datepicker.js|5e12aafeadd2893b88641fa55e102dd7 -/views/js/lengow/toolbox.js|72db7b5a4e5b19702770ad899b5f3e9a -/views/js/lengow/feed.js|5c133b329b482cecda4a5fc721ef32d5 -/views/js/lengow/order_setting.js|39bf665a3a387e60e7d4e23ee6cfb3b9 -/views/js/lengow/order.js|53696be1ee061487de8230f8312ad4b4 -/views/js/lengow/main_setting.js|1bfae4b8bf1c6ba01def0ef3a36d462c -/views/js/lengow/home.js|1f2e8c28ae870b3476483d3759f76964 -/views/js/lengow/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/js/lengow/admin.js|62eeab452a15d83278e4d0c6dcdc50a1 -/views/js/jquery.1.12.0.min.js|e63f1452800f328881a789956054aca3 -/views/js/bootstrap.min.js|3584d6a859bebce245bae0a6e0606e2f -/views/js/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/products.html.twig|a56a8ae0b199d49a9e20d523a22faa1b -/views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/Modal/update_shipping_modal.html.twig|74663ee30f4923a29ad683d779712f95 -/views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/Modal/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/shipping.html.twig|f8a6cd2da200718da882c869c94a5f19 -/views/PrestaShop/Admin/Sell/Order/Order/Blocks/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/PrestaShop/Admin/Sell/Order/Order/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/PrestaShop/Admin/Sell/Order/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/PrestaShop/Admin/Sell/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/PrestaShop/Admin/index.php|be8b25f88c14bddd7711e4585ebae316 -/views/PrestaShop/index.php|be8b25f88c14bddd7711e4585ebae316 -/webservice/cron.php|dbd507c0d4b89fbd5b81ab911fe6fdaa -/webservice/toolbox.php|460e115e59104dd9517039215f0376c5 -/webservice/export.php|93ae5e6f44bdb7e32564f6c9d771e184 +/views/css/bootstrap-datepicker.css|d5260247b97663d887f4efe8ec894353 +/views/css/lengow-layout.css|e826a03df31d2ceb9fd8c12c166beb0b +/views/css/font-awesome.css|bf4b58c946c9234e4a6b9f7a70d38006 +/views/css/select2.css|8969ac4614d64a13dfc32e1eb4e731f7 +/views/css/lengow-tab.css|5b6066640ae15dce94cd2225d84cec50 +/views/css/lengow-components.css|f4b8967a36a2d3cdf602112e7b541a60 +/views/css/lengow-pages.css|b4ed4b364d8036bfb4d889649481baf8 +/views/css/index.php|be8b25f88c14bddd7711e4585ebae316 +/views/index.php|be8b25f88c14bddd7711e4585ebae316 /webservice/index.php|be8b25f88c14bddd7711e4585ebae316 diff --git a/config/routes.yml b/config/routes.yml index 2b39e009..7a1ac426 100644 --- a/config/routes.yml +++ b/config/routes.yml @@ -1,36 +1,71 @@ -admin_orders_view: - path: /sell/orders/{orderId}/view - methods: [ GET, POST ] - defaults: - _disable_module_prefix: true - _controller: 'PrestaShop\Module\Lengow\Controller\AdminOrderController::viewAction' - _legacy_controller: AdminOrders - _legacy_link: AdminOrders:vieworder - _legacy_parameters: - id_order: orderId - options: - expose: true - requirements: - orderId: \d+ - -admin_orders_update_shipping: - path: /sell/orders/{orderId}/shipping - methods: [ POST ] - defaults: - _disable_module_prefix: true - _controller: 'PrestaShop\Module\Lengow\Controller\AdminOrderController::updateShippingAction' - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - -lengow_save_refund_reason: - path: /admin/lengow/refund-reason/save - methods: [ POST ] - defaults: - _controller: 'PrestaShop\Module\Lengow\Controller\AdminOrderController::saveRefundReason' - -lengow_save_refund_mode: - path: /admin/lengow/refund-mode/save - methods: [ POST ] - defaults: - _controller: 'PrestaShop\Module\Lengow\Controller\AdminOrderController::saveRefundMode' +lengow_home: + path: /lengow/home + methods: [ GET, POST ] + defaults: + _controller: 'PrestaShop\Module\Lengow\Controller\Admin\LengowHomeAdminController::indexAction' + _legacy_controller: AdminLengowHome + _legacy_link: AdminLengowHome + +lengow_dashboard: + path: /lengow/dashboard + methods: [ GET, POST ] + defaults: + _controller: 'PrestaShop\Module\Lengow\Controller\Admin\LengowDashboardAdminController::indexAction' + _legacy_controller: AdminLengowDashboard + _legacy_link: AdminLengowDashboard + +lengow_feed: + path: /lengow/feed + methods: [ GET, POST ] + defaults: + _controller: 'PrestaShop\Module\Lengow\Controller\Admin\LengowFeedAdminController::indexAction' + _legacy_controller: AdminLengowFeed + _legacy_link: AdminLengowFeed + +lengow_order: + path: /lengow/order + methods: [ GET, POST ] + defaults: + _controller: 'PrestaShop\Module\Lengow\Controller\Admin\LengowOrderAdminController::indexAction' + _legacy_controller: AdminLengowOrder + _legacy_link: AdminLengowOrder + +lengow_order_setting: + path: /lengow/order-setting + methods: [ GET, POST ] + defaults: + _controller: 'PrestaShop\Module\Lengow\Controller\Admin\LengowOrderSettingAdminController::indexAction' + _legacy_controller: AdminLengowOrderSetting + _legacy_link: AdminLengowOrderSetting + +lengow_main_setting: + path: /lengow/main-setting + methods: [ GET, POST ] + defaults: + _controller: 'PrestaShop\Module\Lengow\Controller\Admin\LengowMainSettingAdminController::indexAction' + _legacy_controller: AdminLengowMainSetting + _legacy_link: AdminLengowMainSetting + +lengow_help: + path: /lengow/help + methods: [ GET, POST ] + defaults: + _controller: 'PrestaShop\Module\Lengow\Controller\Admin\LengowHelpAdminController::indexAction' + _legacy_controller: AdminLengowHelp + _legacy_link: AdminLengowHelp + +lengow_legals: + path: /lengow/legals + methods: [ GET, POST ] + defaults: + _controller: 'PrestaShop\Module\Lengow\Controller\Admin\LengowLegalsAdminController::indexAction' + _legacy_controller: AdminLengowLegals + _legacy_link: AdminLengowLegals + +lengow_toolbox: + path: /lengow/toolbox + methods: [ GET, POST ] + defaults: + _controller: 'PrestaShop\Module\Lengow\Controller\Admin\LengowToolboxAdminController::indexAction' + _legacy_controller: AdminLengowToolbox + _legacy_link: AdminLengowToolbox diff --git a/config/services.yml b/config/services.yml new file mode 100644 index 00000000..f901d09d --- /dev/null +++ b/config/services.yml @@ -0,0 +1,3 @@ +imports: + - { resource: admin/services.yml } + diff --git a/controllers/admin/AdminLengowDashboardController.php b/controllers/admin/AdminLengowDashboardController.php deleted file mode 100644 index d66d8344..00000000 --- a/controllers/admin/AdminLengowDashboardController.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright 2021 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - */ -/* - * Admin Lengow dashboard Controller Class - */ -if (!defined('_PS_VERSION_')) { - exit; -} -class AdminLengowDashboardController extends ModuleAdminController -{ - /** - * Construct - */ - public function __construct() - { - $this->lang = false; - $this->explicitSelect = true; - $this->lite_display = true; - $this->meta_title = 'Configuration'; - $this->list_no_link = true; - $this->template = 'layout.tpl'; - $this->display = 'view'; - - parent::__construct(); - - $lengowController = new LengowDashboardController(); - $lengowController->postProcess(); - $lengowController->display(); - } -} diff --git a/controllers/admin/AdminLengowHelpController.php b/controllers/admin/AdminLengowHelpController.php deleted file mode 100755 index 0d8631db..00000000 --- a/controllers/admin/AdminLengowHelpController.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - */ -/* - * Admin Lengow help Controller Class - */ -if (!defined('_PS_VERSION_')) { - exit; -} -class AdminLengowHelpController extends ModuleAdminController -{ - /** - * Construct - */ - public function __construct() - { - $this->lang = true; - $this->explicitSelect = true; - $this->lite_display = true; - $this->meta_title = 'Configuration'; - $this->list_no_link = true; - $this->template = 'layout.tpl'; - $this->display = 'view'; - - parent::__construct(); - - $lengowController = new LengowHelpController(); - $lengowController->postProcess(); - $lengowController->display(); - } -} diff --git a/controllers/admin/AdminLengowHomeController.php b/controllers/admin/AdminLengowHomeController.php deleted file mode 100755 index 45de4a27..00000000 --- a/controllers/admin/AdminLengowHomeController.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - */ -/* - * Admin Lengow home Controller Class - */ -if (!defined('_PS_VERSION_')) { - exit; -} -class AdminLengowHomeController extends ModuleAdminController -{ - /** - * Construct - */ - public function __construct() - { - $this->lang = false; - $this->explicitSelect = true; - $this->lite_display = true; - $this->meta_title = 'Configuration'; - $this->list_no_link = true; - $this->template = 'layout.tpl'; - $this->display = 'view'; - - parent::__construct(); - - $lengowController = new LengowHomeController(); - $lengowController->postProcess(); - $lengowController->display(); - } -} diff --git a/controllers/admin/AdminLengowMainSettingController.php b/controllers/admin/AdminLengowMainSettingController.php deleted file mode 100755 index 782ee279..00000000 --- a/controllers/admin/AdminLengowMainSettingController.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - */ -/* - * Admin Lengow main setting Controller Class - */ -if (!defined('_PS_VERSION_')) { - exit; -} -class AdminLengowMainSettingController extends ModuleAdminController -{ - /** - * Construct - */ - public function __construct() - { - $this->lang = true; - $this->explicitSelect = true; - $this->lite_display = true; - $this->meta_title = 'Configuration'; - $this->list_no_link = true; - $this->template = 'layout.tpl'; - $this->display = 'view'; - - parent::__construct(); - - $lengowController = new LengowMainSettingController(); - $lengowController->postProcess(); - $lengowController->display(); - } -} diff --git a/controllers/admin/AdminLengowOrderController.php b/controllers/admin/AdminLengowOrderController.php deleted file mode 100755 index 52be3618..00000000 --- a/controllers/admin/AdminLengowOrderController.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - */ -/* - * Admin Lengow order Controller Class - */ -if (!defined('_PS_VERSION_')) { - exit; -} -class AdminLengowOrderController extends ModuleAdminController -{ - /** - * Construct - */ - public function __construct() - { - $this->lang = false; - $this->explicitSelect = true; - $this->lite_display = true; - $this->meta_title = 'Configuration'; - $this->list_no_link = true; - $this->template = 'layout.tpl'; - $this->display = 'view'; - - parent::__construct(); - - $lengowController = new LengowOrderController(); - $lengowController->postProcess(); - $lengowController->display(); - } -} diff --git a/controllers/admin/AdminLengowOrderSettingController.php b/controllers/admin/AdminLengowOrderSettingController.php deleted file mode 100755 index c94e8d77..00000000 --- a/controllers/admin/AdminLengowOrderSettingController.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - */ -/* - * Admin Lengow order setting Controller Class - */ -if (!defined('_PS_VERSION_')) { - exit; -} -class AdminLengowOrderSettingController extends ModuleAdminController -{ - /** - * Construct - */ - public function __construct() - { - $this->lang = false; - $this->explicitSelect = true; - $this->lite_display = true; - $this->meta_title = 'Configuration'; - $this->list_no_link = true; - $this->template = 'layout.tpl'; - $this->display = 'view'; - - parent::__construct(); - - $lengowController = new LengowOrderSettingController(); - $lengowController->postProcess(); - $lengowController->display(); - } -} diff --git a/controllers/admin/AdminLengowToolboxController.php b/controllers/admin/AdminLengowToolboxController.php deleted file mode 100644 index 8c5f45c2..00000000 --- a/controllers/admin/AdminLengowToolboxController.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright 2022 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - */ -/* - * Admin Lengow toolbox Controller Class - */ -if (!defined('_PS_VERSION_')) { - exit; -} -class AdminLengowToolboxController extends ModuleAdminController -{ - /** - * Construct - */ - public function __construct() - { - $this->lang = true; - $this->explicitSelect = true; - $this->lite_display = true; - $this->meta_title = 'Toolbox'; - $this->list_no_link = true; - $this->template = 'layout.tpl'; - $this->display = 'view'; - - parent::__construct(); - - $lengowController = new LengowToolboxController(); - $lengowController->postProcess(); - $lengowController->display(); - } -} diff --git a/controllers/front/cron.php b/controllers/front/cron.php new file mode 100644 index 00000000..c71090d0 --- /dev/null +++ b/controllers/front/cron.php @@ -0,0 +1,181 @@ + + * @copyright 2017 Lengow SAS + * @license http://www.apache.org/licenses/LICENSE-2.0 + * List params + * string sync Data type to synchronize + * integer days Synchronization interval time + * integer limit Maximum number of new orders created + * integer shop_id Shop id to import + * string marketplace_sku Lengow marketplace order id to synchronize + * string marketplace_name Lengow marketplace name to synchronize + * string created_from Synchronization of orders since + * string created_to Synchronization of orders until + * integer delivery_address_id Lengow delivery address id to synchronize + * boolean force_product Force import product when quantity is insufficient (1) or not (0) + * boolean force_sync Force synchronization order even if there are errors (1) or not (0) + * boolean debug_mode Activate debug mode (1) or not (0) + * boolean log_output Display log messages (1) or not (0) + * boolean get_sync See synchronization parameters in json format (1) or not (0) + */ +if (!defined('_PS_VERSION_')) { + exit; +} + +/** + * Lengow cron (order import / sync) front-office controller. + * + * Accessible at: /index.php?fc=module&module=lengow&controller=cron + * With pretty URLs: /module/lengow/cron + */ +class LengowCronModuleFrontController extends ModuleFrontController +{ + public function initContent(): void + { + set_time_limit(0); + ini_set('memory_limit', '1024M'); + header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); + header('Cache-Control: post-check=0, pre-check=0', false); + header('Pragma: no-cache'); + + LengowLog::registerShutdownFunction(); + + // check if Lengow is installed and enabled + if (!(bool) Module::getModuleIdByName($this->module->name)) { + $errorMessage = !$this->module->active + ? 'Lengow module is not active' + : 'Lengow module is not installed'; + header('HTTP/1.1 400 Bad Request'); + exit($errorMessage); + } + + // check IP access and Token + $token = Tools::getIsset(LengowImport::PARAM_TOKEN) ? Tools::getValue(LengowImport::PARAM_TOKEN) : ''; + if (!LengowMain::checkWebservicesAccess($token)) { + if ((bool) LengowConfiguration::get(LengowConfiguration::AUTHORIZED_IP_ENABLED)) { + $errorMessage = 'Unauthorized access for IP: ' . $_SERVER['REMOTE_ADDR']; + } else { + $errorMessage = $token !== '' + ? 'Unauthorised access for this token: ' . $token + : 'Unauthorised access: token parameter is empty'; + } + header('HTTP/1.1 403 Forbidden'); + exit($errorMessage); + } + + if (Tools::getIsset(LengowImport::PARAM_GET_SYNC) && Tools::getValue(LengowImport::PARAM_GET_SYNC) == 1) { + echo json_encode(LengowSync::getSyncData()); + } else { + $force = Tools::getIsset(LengowImport::PARAM_FORCE) + ? (bool) Tools::getValue(LengowImport::PARAM_FORCE) + : false; + $logOutput = Tools::getIsset(LengowImport::PARAM_LOG_OUTPUT) + ? (bool) Tools::getValue(LengowImport::PARAM_LOG_OUTPUT) + : false; + // get sync action if exists + $sync = Tools::getIsset(LengowImport::PARAM_SYNC) ? Tools::getValue(LengowImport::PARAM_SYNC) : false; + // sync catalogs id between Lengow and PrestaShop + if (!$sync || $sync === LengowSync::SYNC_CATALOG) { + LengowSync::syncCatalog($force, $logOutput); + } + // sync marketplace and marketplace carrier between Lengow and PrestaShop + if (!$sync || $sync === LengowSync::SYNC_CARRIER) { + LengowSync::syncCarrier($force, $logOutput); + } + // sync orders between Lengow and PrestaShop + if (!$sync || $sync === LengowSync::SYNC_ORDER) { + // array of params for import order + $params = [ + LengowImport::PARAM_TYPE => LengowImport::TYPE_CRON, + LengowImport::PARAM_LOG_OUTPUT => $logOutput, + ]; + // check if the GET parameters are available + if (Tools::getIsset(LengowImport::PARAM_FORCE_PRODUCT)) { + $params[LengowImport::PARAM_FORCE_PRODUCT] = (bool) Tools::getValue(LengowImport::PARAM_FORCE_PRODUCT); + } + if (Tools::getIsset(LengowImport::PARAM_FORCE_SYNC)) { + $params[LengowImport::PARAM_FORCE_SYNC] = (bool) Tools::getValue(LengowImport::PARAM_FORCE_SYNC); + } + if (Tools::getIsset(LengowImport::PARAM_DEBUG_MODE)) { + $params[LengowImport::PARAM_DEBUG_MODE] = (bool) Tools::getValue(LengowImport::PARAM_DEBUG_MODE); + } + if (Tools::getIsset(LengowImport::PARAM_MINUTES) && is_numeric(Tools::getValue(LengowImport::PARAM_MINUTES))) { + $params[LengowImport::PARAM_MINUTES] = (float) Tools::getValue(LengowImport::PARAM_MINUTES); + } + if (Tools::getIsset(LengowImport::PARAM_DAYS) && is_numeric(Tools::getValue(LengowImport::PARAM_DAYS))) { + $params[LengowImport::PARAM_DAYS] = (float) Tools::getValue(LengowImport::PARAM_DAYS); + } + if (Tools::getIsset(LengowImport::PARAM_CREATED_FROM)) { + $params[LengowImport::PARAM_CREATED_FROM] = Tools::getValue(LengowImport::PARAM_CREATED_FROM); + } + if (Tools::getIsset(LengowImport::PARAM_CREATED_TO)) { + $params[LengowImport::PARAM_CREATED_TO] = Tools::getValue(LengowImport::PARAM_CREATED_TO); + } + if (Tools::getIsset(LengowImport::PARAM_LIMIT) && is_numeric(Tools::getValue(LengowImport::PARAM_LIMIT))) { + $params[LengowImport::PARAM_LIMIT] = (int) Tools::getValue(LengowImport::PARAM_LIMIT); + } + if (Tools::getIsset(LengowImport::PARAM_MARKETPLACE_SKU)) { + $params[LengowImport::PARAM_MARKETPLACE_SKU] = Tools::getValue(LengowImport::PARAM_MARKETPLACE_SKU); + } + if (Tools::getIsset(LengowImport::PARAM_MARKETPLACE_NAME)) { + $params[LengowImport::PARAM_MARKETPLACE_NAME] = Tools::getValue(LengowImport::PARAM_MARKETPLACE_NAME); + } + if (Tools::getIsset(LengowImport::PARAM_DELIVERY_ADDRESS_ID)) { + $params[LengowImport::PARAM_DELIVERY_ADDRESS_ID] = (int) Tools::getValue( + LengowImport::PARAM_DELIVERY_ADDRESS_ID + ); + } + if (Tools::getIsset(LengowImport::PARAM_SHOP_ID) && is_numeric(Tools::getValue(LengowImport::PARAM_SHOP_ID))) { + $params[LengowImport::PARAM_SHOP_ID] = (int) Tools::getValue(LengowImport::PARAM_SHOP_ID); + } + // import orders + $import = new LengowImport($params); + $import->exec(); + } + // sync actions between Lengow and PrestaShop + if (!$sync || $sync === LengowSync::SYNC_ACTION) { + LengowAction::checkFinishAction($logOutput); + LengowAction::checkOldAction($logOutput); + LengowAction::checkActionNotSent($logOutput); + } + // sync options between Lengow and PrestaShop + if (!$sync || $sync === LengowSync::SYNC_CMS_OPTION) { + LengowSync::setCmsOption($force, $logOutput); + } + // sync marketplaces between Lengow and PrestaShop + if ($sync === LengowSync::SYNC_MARKETPLACE) { + LengowSync::getMarketplaces($force, $logOutput); + } + // sync status account between Lengow and PrestaShop + if ($sync === LengowSync::SYNC_STATUS_ACCOUNT) { + LengowSync::getStatusAccount($force, $logOutput); + } + // sync plugin data between Lengow and PrestaShop + if ($sync === LengowSync::SYNC_PLUGIN_DATA) { + LengowSync::getPluginData($force, $logOutput); + } + // sync option is not valid + if ($sync && !in_array($sync, LengowSync::$syncActions, true)) { + header('HTTP/1.1 400 Bad Request'); + exit('Action: ' . $sync . ' is not a valid action'); + } + } + + exit; + } +} diff --git a/controllers/front/export.php b/controllers/front/export.php new file mode 100644 index 00000000..22b4bf40 --- /dev/null +++ b/controllers/front/export.php @@ -0,0 +1,245 @@ + + * @copyright 2017 Lengow SAS + * @license http://www.apache.org/licenses/LICENSE-2.0 + * List params + * string mode Number of products exported + * string format Format of exported files ('csv','yaml','xml','json') + * boolean stream Stream file (1) or generate a file on server (0) + * integer offset Offset of total product + * integer limit Limit number of exported product + * boolean selection Export product selection (1) or all products (0) + * boolean out_of_stock Export out of stock product (1) Export only product in stock (0) + * string product_ids List of product id separate with comma (1,2,3) + * boolean variation Export product Variation (1) Export parent product only (0) + * boolean inactive Export inactive product (1) or not (0) + * integer shop Export a specific shop + * string currency Convert prices with a specific currency + * string language Translate content with a specific language + * boolean legacy_fields Export feed with v2 fields (1) or v3 fields (0) + * boolean log_output See logs (1) or not (0) + * boolean update_export_date Change last export date in data base (1) or not (0) + * boolean get_params See export parameters and authorized values in json format (1) or not (0) + */ +if (!defined('_PS_VERSION_')) { + exit; +} + +/** + * Lengow export front-office controller. + * + * Accessible at: /index.php?fc=module&module=lengow&controller=export + * With pretty URLs: /module/lengow/export + */ +class LengowExportModuleFrontController extends ModuleFrontController +{ + public function initContent(): void + { + set_time_limit(0); + ini_set('memory_limit', '1024M'); + header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); + header('Cache-Control: post-check=0, pre-check=0', false); + header('Pragma: no-cache'); + + LengowLog::registerShutdownFunction(); + + // check if Lengow is installed and enabled + if (!(bool) Module::getModuleIdByName($this->module->name)) { + $errorMessage = !$this->module->active + ? 'Lengow module is not active' + : 'Lengow module is not installed'; + header('HTTP/1.1 400 Bad Request'); + exit($errorMessage); + } + + // CheckIP + $token = Tools::getIsset(LengowExport::PARAM_TOKEN) ? Tools::getValue(LengowExport::PARAM_TOKEN) : ''; + if (!LengowMain::checkWebservicesAccess($token, LengowContext::getContext()->shop->id)) { + if ((bool) LengowConfiguration::get(LengowConfiguration::AUTHORIZED_IP_ENABLED)) { + $errorMessage = 'Unauthorized access for IP: ' . $_SERVER['REMOTE_ADDR']; + } else { + $errorMessage = $token !== '' + ? 'Unauthorised access for this token: ' . $token + : 'Unauthorised access: token parameter is empty'; + } + header('HTTP/1.1 403 Forbidden'); + exit($errorMessage); + } + + // get params data + $getParams = Tools::getIsset(LengowExport::PARAM_GET_PARAMS) + ? (bool) Tools::getValue(LengowExport::PARAM_GET_PARAMS) + : false; + // get mode + $mode = ( + Tools::getIsset(LengowExport::PARAM_MODE) + && (Tools::getValue(LengowExport::PARAM_MODE) === 'size' || Tools::getValue(LengowExport::PARAM_MODE) === 'total') + ) ? Tools::getValue(LengowExport::PARAM_MODE) : null; + // export format (csv, yaml, xml, json) + $format = Tools::getIsset(LengowExport::PARAM_FORMAT) + ? Tools::getValue(LengowExport::PARAM_FORMAT) + : LengowConfiguration::getGlobalValue(LengowConfiguration::EXPORT_FORMAT); + // export in file or not + $stream = Tools::getIsset(LengowExport::PARAM_STREAM) + ? (bool) Tools::getValue(LengowExport::PARAM_STREAM) + : !(bool) LengowConfiguration::getGlobalValue(LengowConfiguration::EXPORT_FILE_ENABLED); + // export offset + $offset = Tools::getIsset(LengowExport::PARAM_OFFSET) ? (int) Tools::getValue(LengowExport::PARAM_OFFSET) : null; + // export limit + $limit = Tools::getIsset(LengowExport::PARAM_LIMIT) ? (int) Tools::getValue(LengowExport::PARAM_LIMIT) : null; + // export specific shop + if (Tools::getIsset(LengowExport::PARAM_SHOP)) { + $shop = new Shop((int) Tools::getValue(LengowExport::PARAM_SHOP)); + if ($shop->id) { + $shop::setContext(Shop::CONTEXT_SHOP, $shop->id); + LengowContext::getContext()->shop = $shop; + } + } + $idShop = (int) LengowContext::getContext()->shop->id; + // export lengow selection + $selection = Tools::getIsset(LengowExport::PARAM_LEGACY_SELECTION) + ? !(bool) Tools::getValue(LengowExport::PARAM_LEGACY_SELECTION) + : null; + if ($selection !== null || Tools::getIsset(LengowExport::PARAM_SELECTION)) { + $selection = $selection !== null ? $selection : (bool) Tools::getValue(LengowExport::PARAM_SELECTION); + } else { + $selection = (bool) LengowConfiguration::get(LengowConfiguration::SELECTION_ENABLED, null, null, $idShop); + } + // export out of stock products + $outOfStock = Tools::getIsset(LengowExport::PARAM_LEGACY_OUT_OF_STOCK) + ? (bool) Tools::getValue(LengowExport::PARAM_LEGACY_OUT_OF_STOCK) + : null; + if ($outOfStock !== null || Tools::getIsset(LengowExport::PARAM_OUT_OF_STOCK)) { + $outOfStock = $outOfStock !== null ? $outOfStock : (bool) Tools::getValue(LengowExport::PARAM_OUT_OF_STOCK); + } else { + $outOfStock = (bool) LengowConfiguration::get(LengowConfiguration::OUT_OF_STOCK_ENABLED, null, null, $idShop); + } + // export specific products + $productIds = []; + $ids = Tools::getIsset(LengowExport::PARAM_LEGACY_PRODUCT_IDS) + ? Tools::getValue(LengowExport::PARAM_LEGACY_PRODUCT_IDS) + : null; + if ($ids !== null || Tools::getIsset(LengowExport::PARAM_PRODUCT_IDS)) { + $ids = $ids !== null ? $ids : Tools::getValue(LengowExport::PARAM_PRODUCT_IDS); + if (Tools::strlen($ids) > 0) { + $ids = str_replace([';', '|', ':'], ',', $ids); + $ids = preg_replace('/[^0-9\,]/', '', $ids); + $productIds = explode(',', $ids); + } + } + // export product variation + $variation = null; + if (Tools::getIsset(LengowExport::PARAM_LEGACY_VARIATION)) { + if (Tools::getValue(LengowExport::PARAM_LEGACY_VARIATION) === 'simple') { + $variation = false; + } elseif (Tools::getValue(LengowExport::PARAM_LEGACY_VARIATION) === 'full') { + $variation = true; + } + } + if ($variation !== null || Tools::getIsset(LengowExport::PARAM_VARIATION)) { + $variation = $variation !== null ? $variation : (bool) Tools::getValue(LengowExport::PARAM_VARIATION); + } else { + $variation = (bool) LengowConfiguration::get(LengowConfiguration::VARIATION_ENABLED, null, null, $idShop); + } + // export inactive products + $inactive = null; + if (Tools::getValue(LengowExport::PARAM_LEGACY_INACTIVE)) { + if (Tools::getValue(LengowExport::PARAM_LEGACY_INACTIVE) === 'enabled') { + $inactive = false; + } elseif (Tools::getValue(LengowExport::PARAM_LEGACY_INACTIVE) === 'all') { + $inactive = true; + } + } + if ($inactive !== null || Tools::getIsset(LengowExport::PARAM_INACTIVE)) { + $inactive = $inactive !== null ? $inactive : (bool) Tools::getValue(LengowExport::PARAM_INACTIVE); + } else { + $inactive = (bool) LengowConfiguration::get(LengowConfiguration::INACTIVE_ENABLED, null, null, $idShop); + } + // convert price for a specific currency + $currency = Tools::getIsset(LengowExport::PARAM_LEGACY_CURRENCY) + ? Tools::getValue(LengowExport::PARAM_LEGACY_CURRENCY) + : null; + if ($currency !== null || Tools::getIsset(LengowExport::PARAM_CURRENCY)) { + $currency = $currency !== null ? $currency : Tools::getValue(LengowExport::PARAM_CURRENCY); + $idCurrency = (int) Currency::getIdByIsoCode($currency); + if ($idCurrency !== 0) { + LengowContext::getContext()->currency = new Currency($idCurrency); + } + } + // define language + $language = Tools::getIsset(LengowExport::PARAM_LEGACY_LANGUAGE) + ? Tools::getValue(LengowExport::PARAM_LEGACY_LANGUAGE) + : null; + if ($language !== null || Tools::getIsset(LengowExport::PARAM_LANGUAGE)) { + $language = $language !== null ? $language : Tools::getValue(LengowExport::PARAM_LANGUAGE); + $languageId = (int) Language::getIdByIso($language); + if ($languageId === 0) { + $languageId = LengowContext::getContext()->language->id; + } + } elseif (Tools::getIsset(LengowExport::PARAM_LANGUAGE_ID)) { + $languageId = (int) Tools::getValue(LengowExport::PARAM_LANGUAGE_ID); + if (!Language::getLanguage($languageId)) { + $languageId = LengowContext::getContext()->language->id; + } + } else { + $languageId = LengowContext::getContext()->language->id; + } + // get legacy fields + $legacyFields = Tools::getIsset(LengowExport::PARAM_LEGACY_FIELDS) + ? (bool) Tools::getValue(LengowExport::PARAM_LEGACY_FIELDS) + : null; + // update export date + $updateExportDate = Tools::getIsset(LengowExport::PARAM_UPDATE_EXPORT_DATE) + ? (bool) Tools::getValue(LengowExport::PARAM_UPDATE_EXPORT_DATE) + : true; + // See logs or not + $logOutput = Tools::getIsset(LengowExport::PARAM_LOG_OUTPUT) + ? (bool) Tools::getValue(LengowExport::PARAM_LOG_OUTPUT) + : true; + + $export = new LengowExport( + [ + LengowExport::PARAM_FORMAT => $format, + LengowExport::PARAM_STREAM => $stream, + LengowExport::PARAM_PRODUCT_IDS => $productIds, + LengowExport::PARAM_LIMIT => $limit, + LengowExport::PARAM_OFFSET => $offset, + LengowExport::PARAM_OUT_OF_STOCK => $outOfStock, + LengowExport::PARAM_VARIATION => $variation, + LengowExport::PARAM_INACTIVE => $inactive, + LengowExport::PARAM_LEGACY_FIELDS => $legacyFields, + LengowExport::PARAM_SELECTION => $selection, + LengowExport::PARAM_LANGUAGE_ID => $languageId, + LengowExport::PARAM_UPDATE_EXPORT_DATE => $updateExportDate, + LengowExport::PARAM_LOG_OUTPUT => $logOutput, + ] + ); + + if ($getParams) { + echo $export->getExportParams(); + } elseif ($mode === 'size') { + echo $export->getTotalExportProduct(); + } elseif ($mode === 'total') { + echo $export->getTotalProduct(); + } else { + $export->exec(); + } + + exit; + } +} diff --git a/controllers/front/index.php b/controllers/front/index.php new file mode 100644 index 00000000..6b008a2d --- /dev/null +++ b/controllers/front/index.php @@ -0,0 +1,34 @@ + + * @copyright 2007-2016 PrestaShop SA + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + * International Registered Trademark & Property of PrestaShop SA + */ +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; diff --git a/controllers/front/toolbox.php b/controllers/front/toolbox.php new file mode 100644 index 00000000..6043125c --- /dev/null +++ b/controllers/front/toolbox.php @@ -0,0 +1,136 @@ + + * @copyright 2021 Lengow SAS + * @license http://www.apache.org/licenses/LICENSE-2.0 + * List params + * string toolbox_action Toolbox specific action + * string type Type of data to display + * string created_from Synchronization of orders since + * string created_to Synchronization of orders until + * string date Log date to download + * string marketplace_name Lengow marketplace name to synchronize + * string marketplace_sku Lengow marketplace order id to synchronize + * string process Type of process for order action + * boolean force Force synchronization order even if there are errors (1) or not (0) + * integer shop_id Shop id to synchronize + * integer days Synchronization interval time + */ +if (!defined('_PS_VERSION_')) { + exit; +} + +/** + * Lengow toolbox front-office controller. + * + * Accessible at: /index.php?fc=module&module=lengow&controller=toolbox + * With pretty URLs: /module/lengow/toolbox + */ +class LengowToolboxModuleFrontController extends ModuleFrontController +{ + public function initContent(): void + { + set_time_limit(0); + header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); + header('Cache-Control: post-check=0, pre-check=0', false); + header('Pragma: no-cache'); + + LengowLog::registerShutdownFunction(); + + // check if Lengow is installed and enabled + if (!(bool) Module::getModuleIdByName($this->module->name)) { + $errorMessage = !$this->module->active + ? 'Lengow module is not active' + : 'Lengow module is not installed'; + header('HTTP/1.1 400 Bad Request'); + exit($errorMessage); + } + + // check IP access and Token + $token = Tools::getValue(LengowToolbox::PARAM_TOKEN, ''); + if (!LengowMain::checkWebservicesAccess($token)) { + if ((bool) LengowConfiguration::get(LengowConfiguration::AUTHORIZED_IP_ENABLED)) { + $errorMessage = 'Unauthorized access for IP: ' . $_SERVER['REMOTE_ADDR']; + } else { + $errorMessage = $token !== '' + ? 'Unauthorised access for this token: ' . $token + : 'Unauthorised access: token parameter is empty'; + } + header('HTTP/1.1 403 Forbidden'); + exit($errorMessage); + } + + $action = Tools::getValue(LengowToolbox::PARAM_TOOLBOX_ACTION, LengowToolbox::ACTION_DATA); + // check if toolbox action is valid + if (!in_array($action, LengowToolbox::$toolboxActions, true)) { + header('HTTP/1.1 400 Bad Request'); + exit('Action: ' . $action . ' is not a valid action'); + } + + switch ($action) { + case LengowToolbox::ACTION_LOG: + $date = Tools::getValue(LengowToolbox::PARAM_DATE, null); + LengowToolbox::downloadLog($date); + break; + case LengowToolbox::ACTION_ORDER: + $process = Tools::getValue(LengowToolbox::PARAM_PROCESS, LengowToolbox::PROCESS_TYPE_SYNC); + $error = false; + if ($process === LengowToolbox::PROCESS_TYPE_GET_DATA) { + $result = LengowToolbox::getOrderData( + Tools::getValue(LengowToolbox::PARAM_MARKETPLACE_SKU, null), + Tools::getValue(LengowToolbox::PARAM_MARKETPLACE_NAME, null), + Tools::getValue(LengowToolbox::PARAM_TYPE, null) + ); + } else { + $result = LengowToolbox::syncOrders( + [ + LengowToolbox::PARAM_CREATED_TO => Tools::getValue(LengowToolbox::PARAM_CREATED_TO, null), + LengowToolbox::PARAM_CREATED_FROM => Tools::getValue(LengowToolbox::PARAM_CREATED_FROM, null), + LengowToolbox::PARAM_DAYS => Tools::getValue(LengowToolbox::PARAM_DAYS, null), + LengowToolbox::PARAM_FORCE => Tools::getValue(LengowToolbox::PARAM_FORCE, null), + LengowToolbox::PARAM_MARKETPLACE_NAME => Tools::getValue( + LengowToolbox::PARAM_MARKETPLACE_NAME, + null + ), + LengowToolbox::PARAM_MARKETPLACE_SKU => Tools::getValue(LengowToolbox::PARAM_MARKETPLACE_SKU, null), + LengowToolbox::PARAM_SHOP_ID => Tools::getValue(LengowToolbox::PARAM_SHOP_ID, null), + ] + ); + } + if (isset($result[LengowToolbox::ERRORS][LengowToolbox::ERROR_CODE])) { + $error = true; + if ($result[LengowToolbox::ERRORS][LengowToolbox::ERROR_CODE] === LengowConnector::CODE_404) { + header('HTTP/1.1 404 Not Found'); + } else { + header('HTTP/1.1 403 Forbidden'); + } + } + if (!$error) { + header('Content-Type: application/json'); + } + echo json_encode($result); + break; + default: + header('Content-Type: application/json'); + $type = (string) (Tools::getValue(LengowToolbox::PARAM_TYPE) ?: LengowToolbox::DATA_TYPE_CMS); + echo json_encode(LengowToolbox::getData($type)); + break; + } + + exit; + } +} diff --git a/controllers/index.php b/controllers/index.php old mode 100755 new mode 100644 diff --git a/dod.md b/dod.md index 9c7c92c3..67586d10 100755 --- a/dod.md +++ b/dod.md @@ -2,8 +2,8 @@ ## Liste des critères ## -* Recetter sa feature sur les versions 1.6 et 1.7 : -* Coder en respectant la version de PHP 5.5 : +* Recetter sa feature sur les versions 8.x et 9.x : +* Coder en respectant la version de PHP 8.1 : * Pas de modification de comportement de fonction : * Principe SOLID (au moins le S) : * Coding Style (PSR2) : @@ -19,10 +19,10 @@ ## Explication des critères ## -### Recetter sa feature sur les versions 1.6 et 1.7 ### +### Recetter sa feature sur les versions 8.x et 9.x ### Tester son développement sur toutes les versions compatibles avec le module -### Coder en respectant la version de PHP 5.5 ### +### Coder en respectant la version de PHP 8.1 ### Coder en respectant tous les standards de la version de PHP requise ### Pas de modification de comportement de fonction ### diff --git a/controllers/admin/AdminLengowLegalsController.php b/en.php old mode 100755 new mode 100644 similarity index 56% rename from controllers/admin/AdminLengowLegalsController.php rename to en.php index b384a5bf..3dbd8b02 --- a/controllers/admin/AdminLengowLegalsController.php +++ b/en.php @@ -18,31 +18,10 @@ * @copyright 2017 Lengow SAS * @license http://www.apache.org/licenses/LICENSE-2.0 */ -/* - * Admin Lengow legals Controller Class - */ if (!defined('_PS_VERSION_')) { exit; } -class AdminLengowLegalsController extends ModuleAdminController -{ - /** - * Construct - */ - public function __construct() - { - $this->lang = true; - $this->explicitSelect = true; - $this->lite_display = true; - $this->meta_title = 'Legals'; - $this->list_no_link = true; - $this->template = 'layout.tpl'; - $this->display = 'view'; - - parent::__construct(); - - $lengowController = new LengowLegalsController(); - $lengowController->postProcess(); - $lengowController->display(); - } -} +$_MODULE = []; +$_MODULE['<{lengow}prestashop>lengow_5bece808b0b66f50124ebc25494dc4d3'] = 'Lengow'; +$_MODULE['<{lengow}prestashop>lengow_9ef78860db1855920221009a4456cb3e'] = 'Lengow allows you to easily export your product catalogue from your PrestaShop store and sell on Amazon, Cdiscount, Google Shopping, Criteo, LeGuide.com, Ebay, Rakuten, Priceminister. Choose from our 1,800 available marketing channels!'; +$_MODULE['<{lengow}prestashop>lengow_45a0d53148ff9dd1449664816ca3ee2a'] = 'Are you sure you want to uninstall the Lengow module?'; diff --git a/es.php b/es.php index 0a3f2755..aa2b7854 100755 --- a/es.php +++ b/es.php @@ -11,5 +11,5 @@ } $_MODULE = []; $_MODULE['<{lengow}prestashop>lengow_5bece808b0b66f50124ebc25494dc4d3'] = 'Lengow'; -$_MODULE['<{lengow}prestashop>lengow_75d51c9dc3497701321f7e5b8a8f0f58'] = 'Con su modulo Lengow para PrestaShop, exporte facilmente sus productos desde su PrestaShop y vende en Amazon, Ebay, Facebook, Google Shopping… Haga su elección entre más de 1 800 canales de distribución y consigue nuevos clientes en todo el mundo !'; +$_MODULE['<{lengow}prestashop>lengow_9ef78860db1855920221009a4456cb3e'] = 'Lengow le permite exportar fácilmente su catálogo de productos desde su tienda PrestaShop y vender en Amazon, Cdiscount, Google Shopping, Criteo, LeGuide.com, Ebay, Rakuten, Priceminister. ¡Elija entre nuestros 1.800 canales de marketing disponibles!'; $_MODULE['<{lengow}prestashop>lengow_45a0d53148ff9dd1449664816ca3ee2a'] = '¿Estás seguro de que quieres suprimir el módulo?'; diff --git a/fr.php b/fr.php index 67671193..8f44b4fd 100755 --- a/fr.php +++ b/fr.php @@ -11,5 +11,5 @@ } $_MODULE = []; $_MODULE['<{lengow}prestashop>lengow_5bece808b0b66f50124ebc25494dc4d3'] = 'Lengow'; -$_MODULE['<{lengow}prestashop>lengow_75d51c9dc3497701321f7e5b8a8f0f58'] = 'Avec votre module Lengow pour PrestaShop vendez rapidement vos produits sur Amazon, Ebay, Facebook, Google Shopping et d’autres et touchez facilement de nouveaux clients partout dans le monde. Plus de 1 800 canaux marketing vous attendent sur la plateforme Lengow !'; -$_MODULE['<{lengow}prestashop>lengow_45a0d53148ff9dd1449664816ca3ee2a'] = 'Etes-vous de vouloir désinstaller le module Lengow ?'; +$_MODULE['<{lengow}prestashop>lengow_9ef78860db1855920221009a4456cb3e'] = 'Lengow vous permet d\'exporter facilement votre catalogue produits depuis votre boutique PrestaShop et de vendre sur Amazon, Cdiscount, Google Shopping, Criteo, LeGuide.com, Ebay, Rakuten, Priceminister. Choisissez parmi nos 1 800 canaux marketing disponibles !'; +$_MODULE['<{lengow}prestashop>lengow_45a0d53148ff9dd1449664816ca3ee2a'] = 'Êtes-vous sûr de vouloir désinstaller le module Lengow ?'; diff --git a/it.php b/it.php index 2c5e60d4..f281218d 100755 --- a/it.php +++ b/it.php @@ -11,5 +11,5 @@ } $_MODULE = []; $_MODULE['<{lengow}prestashop>lengow_5bece808b0b66f50124ebc25494dc4d3'] = 'Lengow'; -$_MODULE['<{lengow}prestashop>lengow_75d51c9dc3497701321f7e5b8a8f0f58'] = 'Con Lengow puoi esportare facilmente i tuoi prodotti da PrestaShop e vendere su Amazon, Ebay, Facebook, Google Shopping… fai la tua scelta tra più di 1800 canali di diffusione !'; +$_MODULE['<{lengow}prestashop>lengow_9ef78860db1855920221009a4456cb3e'] = 'Lengow ti permette di esportare facilmente il tuo catalogo prodotti dal tuo negozio PrestaShop e vendere su Amazon, Cdiscount, Google Shopping, Criteo, LeGuide.com, Ebay, Rakuten, Priceminister. Scegli tra i nostri 1.800 canali di marketing disponibili!'; $_MODULE['<{lengow}prestashop>lengow_45a0d53148ff9dd1449664816ca3ee2a'] = 'Sei sicuro di voler disinstallare il modulo Lengow ?'; diff --git a/lengow.php b/lengow.php index 29e63326..378e6d10 100755 --- a/lengow.php +++ b/lengow.php @@ -23,6 +23,9 @@ if (!defined('_PS_VERSION_')) { exit; } + +use PrestaShop\PrestaShop\Adapter\SymfonyContainer; + /** * Lengow */ @@ -31,12 +34,14 @@ class Lengow extends Module /** * Lengow Install Class */ - private $installClass; + /** @var LengowInstall */ + private LengowInstall $installClass; /** * Lengow Hook Class */ - private $hookClass; + /** @var LengowHook */ + private LengowHook $hookClass; /** * Construct @@ -49,20 +54,22 @@ public function __construct() $this->author = 'Lengow'; $this->module_key = '__LENGOW_PRESTASHOP_PRODUCT_KEY__'; $this->ps_versions_compliancy = [ - 'min' => '1.7.8', - 'max' => '8.99.99', + 'min' => '8.0.0', + 'max' => '9.99.99', ]; $this->bootstrap = true; parent::__construct(); - $this->displayName = $this->l('Lengow'); + LengowContext::setContext($this->context); + + $this->displayName = 'Lengow'; $this->description = $this->l('Lengow allows you to easily export your product catalogue from your PrestaShop store and sell on Amazon, Cdiscount, Google Shopping, Criteo, LeGuide.com, Ebay, Rakuten, Priceminister. Choose from our 1,800 available marketing channels!'); $this->confirmUninstall = $this->l('Are you sure you want to uninstall the Lengow module?'); - $this->installClass = new LengowInstall($this); - $this->hookClass = new LengowHook($this); + $this->installClass = new LengowInstall($this, $this->context); + $this->hookClass = new LengowHook($this, $this->context); if (self::isInstalled($this->name)) { $oldVersion = LengowConfiguration::getGlobalValue( @@ -70,28 +77,66 @@ public function __construct() ); if ($oldVersion !== $this->version) { $this->installClass->clearCaches(); + LengowInstall::setInstallationStatus(false); + $this->installClass->update($oldVersion); LengowConfiguration::updateGlobalValue( LengowConfiguration::PLUGIN_VERSION, $this->version ); - $this->installClass->update($oldVersion); $this->installClass->clearCaches(); } } - $this->context = Context::getContext(); $this->context->smarty->assign('lengow_link', new LengowLink()); } /** * Configure Link * Redirect on lengow configure page + * + * @return void + */ + public function getContent(): void + { + $sfContainer = SymfonyContainer::getInstance(); + if ($sfContainer === null) { + return; + } + $router = $sfContainer->get('router'); + try { + Tools::redirectAdmin($router->generate('lengow_home')); + } catch (Symfony\Component\Routing\Exception\RouteNotFoundException $e) { + $this->clearCompiledCache(); + Tools::redirectAdmin( + $this->context->link->getAdminLink('AdminModules', true, [], ['configure' => $this->name]) + ); + } + } + + /** + * Deletes Symfony routing and container cache files for all environments so they are + * rebuilt fresh on the next request with this module's routes and services included. + * + * Both the routing cache (UrlGenerator/UrlMatcher) and the compiled DI container entry-point + * are deleted because both are built during $kernel->handle() which runs before parent::install() + * registers the module in the database. + * + * @return void */ - public function getContent() + private function clearCompiledCache(): void { - $link = new LengowLink(); - $configLink = $link->getAbsoluteAdminLink('AdminLengowHome'); - Tools::redirect($configLink, ''); + $routingFiles = ['UrlGenerator.php', 'UrlGenerator.php.meta', 'UrlMatcher.php', 'UrlMatcher.php.meta']; + foreach (['dev', 'prod'] as $env) { + $cacheDir = _PS_ROOT_DIR_ . '/var/cache/' . $env . '/'; + foreach ($routingFiles as $file) { + @unlink($cacheDir . $file); + } + // Remove the compiled container entry-point so the DI container is recompiled + // on the next request and module services (controllers) are properly registered. + foreach (glob($cacheDir . 'app*Container.php') ?: [] as $containerFile) { + @unlink($containerFile); + } + } } /** @@ -99,12 +144,16 @@ public function getContent() * * @return bool */ - public function install() + public function install(): bool { $this->installClass->clearCaches(); if (!parent::install()) { return false; } + // Routing/container cache was built by the current request's kernel before this module was + // registered in the DB, so it lacks lengow routes and services. Delete it now so the next + // request rebuilds it fresh. + $this->clearCompiledCache(); $isInstalled = $this->installClass->install(); $this->installClass->clearCaches(); @@ -116,7 +165,7 @@ public function install() * * @return bool */ - public function uninstall() + public function uninstall(): bool { $this->installClass->clearCaches(); if (!parent::uninstall()) { @@ -133,7 +182,7 @@ public function uninstall() * * @return bool */ - public function reset() + public function reset(): bool { $this->installClass->clearCaches(); $isReset = $this->installClass->reset(); @@ -143,34 +192,73 @@ public function reset() } /** - * Hook to display the icon + * Register legacy webservice URLs as PS-native routes pointing to the FO controllers. + * + * Old URLs (modules/lengow/webservice/*.php) still work because: + * - The physical PHP files no longer exist, so Apache forwards to index.php + * - PS Dispatcher picks up these routes and dispatches to the FO controllers + * + * @return array> */ - public function hookDisplayBackOfficeHeader() + public function hookModuleRoutes(): array { - $this->hookClass->hookDisplayBackOfficeHeader(); + return [ + 'lengow-cron' => [ + 'controller' => 'cron', + 'rule' => 'modules/lengow/webservice/cron.php', + 'keywords' => [], + 'params' => [ + 'fc' => 'module', + 'module' => 'lengow', + ], + ], + 'lengow-export' => [ + 'controller' => 'export', + 'rule' => 'modules/lengow/webservice/export.php', + 'keywords' => [], + 'params' => [ + 'fc' => 'module', + 'module' => 'lengow', + ], + ], + 'lengow-toolbox' => [ + 'controller' => 'toolbox', + 'rule' => 'modules/lengow/webservice/toolbox.php', + 'keywords' => [], + 'params' => [ + 'fc' => 'module', + 'module' => 'lengow', + ], + ], + ]; } /** - * Hook on Home page - * @depercated Use hookDisplayHome instead + * Hook to display the icon + * + * @return void */ - public function hookHome() + public function hookDisplayBackOfficeHeader(): void { - $this->hookClass->hookDisplayHome(); + $this->hookClass->hookDisplayBackOfficeHeader(); } /** * Hook on Home page + * + * @return void */ - public function hookDisplayHome() + public function hookDisplayHome(): void { $this->hookClass->hookDisplayHome(); } /** * Hook on Payment page + * + * @return void */ - public function hookDisplayPaymentTop() + public function hookDisplayPaymentTop(): void { $this->hookClass->hookPaymentTop(); } @@ -180,7 +268,7 @@ public function hookDisplayPaymentTop() * * @return mixed */ - public function hookDisplayFooter() + public function hookDisplayFooter(): mixed { return $this->hookClass->hookFooter(); } @@ -188,9 +276,11 @@ public function hookDisplayFooter() /** * Hook on order confirmation page to init order's product list * - * @param array $args Arguments of hook + * @param array $args Arguments of hook + * + * @return void */ - public function hookDisplayOrderConfirmation($args) + public function hookDisplayOrderConfirmation(array $args): void { $this->hookClass->hookOrderConfirmation($args); } @@ -198,8 +288,12 @@ public function hookDisplayOrderConfirmation($args) /** * Order status update * Event This hook launches modules when the status of an order changes + * + * @param array $args + * + * @return void */ - public function hookActionOrderStatusUpdate($args) + public function hookActionOrderStatusUpdate(array $args): void { $this->hookClass->hookUpdateOrderStatus($args); } @@ -207,19 +301,23 @@ public function hookActionOrderStatusUpdate($args) /** * Order status post update * - * @param array $args Arguments of hook + * @param array $args Arguments of hook + * + * @return void */ - public function hookActionOrderStatusPostUpdate($args) + public function hookActionOrderStatusPostUpdate(array $args): void { - $this->hookClass->hookActionOrderStatusPostUpdate($args); + $this->hookClass->hookActionOrderStatusPostUpdate($args); } /** * Hook for update order if isset tracking number * - * @param array $args Arguments of hook + * @param array $args Arguments of hook + * + * @return void */ - public function hookActionObjectUpdateAfter($args) + public function hookActionObjectUpdateAfter(array $args): void { $this->hookClass->hookActionObjectUpdateAfter($args); } @@ -227,11 +325,11 @@ public function hookActionObjectUpdateAfter($args) /** * Hook on admin page's order * - * @param array $args Arguments of hook + * @param array $args Arguments of hook * * @return mixed */ - public function hookDisplayAdminOrder($args) + public function hookDisplayAdminOrder(array $args): mixed { return $this->hookClass->hookAdminOrder($args); } @@ -239,19 +337,47 @@ public function hookDisplayAdminOrder($args) /** * Hook on admin page's order side * - * @param array $args Arguments of hook + * @param array $args Arguments of hook * * @return mixed */ - public function hookDisplayAdminOrderSide($args) + public function hookDisplayAdminOrderSide(array $args): mixed { return $this->hookClass->hookAdminOrderSide($args); } + /** + * Hook to add a Lengow tab link in the order detail tabs + * + * @param array $params + * + * @return string + */ + public function hookDisplayAdminOrderTabLink(array $params): string + { + return $this->hookClass->hookDisplayAdminOrderTabLink($params); + } + + /** + * Hook to add Lengow tab content in the order detail tabs + * + * @param array $params + * + * @return string + */ + public function hookDisplayAdminOrderTabContent(array $params): string + { + return $this->hookClass->hookDisplayAdminOrderTabContent($params); + } + /** * Hook when a product line is refunded + * + * @param array $args + * + * @return void */ - public function hookActionProductCancel($args) + public function hookActionProductCancel(array $args): void { $this->hookClass->hookActionProductCancel($args); } diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 00000000..f5b6d4f3 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,18 @@ +# _PS_ROOT_DIR_=~/prestashop/root PS_DEV_TOOLS_DIR=~/.config/composer/vendor/prestashop/php-dev-tools phpstan analyse --configuration=tests/phpstan/phpstan.neon + +includes: + - %env.PS_DEV_TOOLS_DIR%/phpstan/ps-module-extension.neon +parameters: + level: 6 + excludePaths: + - vendor + ignoreErrors: + # External third-party module classes (optional runtime dependencies, loaded conditionally) + - identifier: class.notFound + message: '#(MondialRelay|MondialrelayCarrierMethod|MondialrelayClasslib|Mondialrelay|MRRelayDetail|MRTools|SCFields|Colissimo_simplicite|Socolissimo)#' + reportUnmatched: false + # DIRECTORY_SEPARATOR path resolution: PHPStan tests both / and \ variants + - identifier: includeOnce.fileNotFound + reportUnmatched: false + - identifier: requireOnce.fileNotFound + reportUnmatched: false diff --git a/src/Controller/Admin/AbstractLengowAdminController.php b/src/Controller/Admin/AbstractLengowAdminController.php new file mode 100644 index 00000000..dc94d517 --- /dev/null +++ b/src/Controller/Admin/AbstractLengowAdminController.php @@ -0,0 +1,108 @@ + + * @copyright 2021 Lengow SAS + * @license http://www.apache.org/licenses/LICENSE-2.0 + */ + +declare(strict_types=1); + +namespace PrestaShop\Module\Lengow\Controller\Admin; + +if (!defined('_PS_VERSION_')) { + exit; +} + +use PrestaShop\PrestaShop\Adapter\LegacyContext; +use PrestaShopBundle\Controller\Admin\PrestaShopAdminController; +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Twig\Environment; + +if ( + !class_exists('PrestaShopBundle\Controller\Admin\PrestaShopAdminController') + && class_exists('PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController') +) { + class_alias( + 'PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController', + 'PrestaShopBundle\Controller\Admin\PrestaShopAdminController' + ); +} + +abstract class AbstractLengowAdminController extends PrestaShopAdminController +{ + abstract protected function getPageTitle(): string; + protected \Context $legacyContext; + + public function __construct( + LegacyContext $legacyContext, + protected readonly Environment $twig, + ) { + $this->legacyContext = $legacyContext->getContext(); + \LengowContext::setContext($this->legacyContext); + } + + protected function handleLegacyPostAction(Request $request, object $legacyController): ?Response + { + $action = (string) $request->get('action', ''); + if ($action === '') { + return null; + } + + $legacyControllerName = (string) $request->attributes->get('_legacy_controller', ''); + if ($request->isMethod('POST') && $legacyControllerName !== '' && !$this->isGranted('update', $legacyControllerName)) { + return new JsonResponse( + ['success' => false, 'message' => $this->trans('You do not have permission to edit this.', [], 'Admin.Notifications.Error')], + Response::HTTP_FORBIDDEN + ); + } + + $legacyController->postProcess(); + if (!method_exists($legacyController, 'consumeJsonResponse')) { + return new Response('', Response::HTTP_NO_CONTENT); + } + + $payload = $legacyController->consumeJsonResponse(); + if ($payload === null) { + return new Response('', Response::HTTP_NO_CONTENT); + } + + return new JsonResponse( + $payload, + Response::HTTP_OK, + [], + false + ); + } + + protected function renderLegacyPage(string $template, object $legacyController): Response + { + $legacyController->display(); + + return $this->render( + $template, + array_merge( + $legacyController->getTemplateVars(), + [ + 'base_layout' => '@Modules/lengow/views/templates/admin/twig/ps9_base.html.twig', + 'layoutTitle' => $this->getPageTitle(), + ] + ) + ); + } +} diff --git a/src/Controller/Admin/LengowDashboardAdminController.php b/src/Controller/Admin/LengowDashboardAdminController.php new file mode 100644 index 00000000..df6d47c2 --- /dev/null +++ b/src/Controller/Admin/LengowDashboardAdminController.php @@ -0,0 +1,53 @@ + + * @copyright 2021 Lengow SAS + * @license http://www.apache.org/licenses/LICENSE-2.0 + */ + +declare(strict_types=1); + +namespace PrestaShop\Module\Lengow\Controller\Admin; + +if (!defined('_PS_VERSION_')) { + exit; +} + +use PrestaShopBundle\Security\Attribute\AdminSecurity; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +class LengowDashboardAdminController extends AbstractLengowAdminController +{ + protected function getPageTitle(): string + { + return (new \LengowTranslation($this->legacyContext))->t('tab.dashboard'); + } + + #[AdminSecurity("is_granted('read', request.get('_legacy_controller'))")] + public function indexAction(Request $request): Response + { + $lengowController = new \LengowDashboardController($this->legacyContext, $this->twig, true); + + $response = $this->handleLegacyPostAction($request, $lengowController); + if ($response instanceof Response) { + return $response; + } + + return $this->renderLegacyPage('@Modules/lengow/views/templates/admin/lengow_dashboard/view.html.twig', $lengowController); + } +} diff --git a/src/Controller/Admin/LengowFeedAdminController.php b/src/Controller/Admin/LengowFeedAdminController.php new file mode 100644 index 00000000..0a40347f --- /dev/null +++ b/src/Controller/Admin/LengowFeedAdminController.php @@ -0,0 +1,53 @@ + + * @copyright 2017 Lengow SAS + * @license http://www.apache.org/licenses/LICENSE-2.0 + */ + +declare(strict_types=1); + +namespace PrestaShop\Module\Lengow\Controller\Admin; + +if (!defined('_PS_VERSION_')) { + exit; +} + +use PrestaShopBundle\Security\Attribute\AdminSecurity; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +class LengowFeedAdminController extends AbstractLengowAdminController +{ + protected function getPageTitle(): string + { + return (new \LengowTranslation($this->legacyContext))->t('tab.product'); + } + + #[AdminSecurity("is_granted('read', request.get('_legacy_controller'))")] + public function indexAction(Request $request): Response + { + $lengowController = new \LengowFeedController($this->legacyContext, $this->twig, true); + + $response = $this->handleLegacyPostAction($request, $lengowController); + if ($response instanceof Response) { + return $response; + } + + return $this->renderLegacyPage('@Modules/lengow/views/templates/admin/lengow_feed/view.html.twig', $lengowController); + } +} diff --git a/src/Controller/Admin/LengowHelpAdminController.php b/src/Controller/Admin/LengowHelpAdminController.php new file mode 100644 index 00000000..d6b9ab50 --- /dev/null +++ b/src/Controller/Admin/LengowHelpAdminController.php @@ -0,0 +1,51 @@ + + * @copyright 2017 Lengow SAS + * @license http://www.apache.org/licenses/LICENSE-2.0 + */ +declare(strict_types=1); + +namespace PrestaShop\Module\Lengow\Controller\Admin; + +if (!defined('_PS_VERSION_')) { + exit; +} + +use PrestaShopBundle\Security\Attribute\AdminSecurity; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +class LengowHelpAdminController extends AbstractLengowAdminController +{ + protected function getPageTitle(): string + { + return (new \LengowTranslation($this->legacyContext))->t('tab.help'); + } + + #[AdminSecurity("is_granted('read', request.get('_legacy_controller'))")] + public function indexAction(Request $request): Response + { + $lengowController = new \LengowHelpController($this->legacyContext, $this->twig, true); + $response = $this->handleLegacyPostAction($request, $lengowController); + if ($response instanceof Response) { + return $response; + } + + return $this->renderLegacyPage('@Modules/lengow/views/templates/admin/lengow_help/view.html.twig', $lengowController); + } +} diff --git a/src/Controller/Admin/LengowHomeAdminController.php b/src/Controller/Admin/LengowHomeAdminController.php new file mode 100644 index 00000000..8cd9d5f8 --- /dev/null +++ b/src/Controller/Admin/LengowHomeAdminController.php @@ -0,0 +1,53 @@ + + * @copyright 2017 Lengow SAS + * @license http://www.apache.org/licenses/LICENSE-2.0 + */ + +declare(strict_types=1); + +namespace PrestaShop\Module\Lengow\Controller\Admin; + +if (!defined('_PS_VERSION_')) { + exit; +} + +use PrestaShopBundle\Security\Attribute\AdminSecurity; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +class LengowHomeAdminController extends AbstractLengowAdminController +{ + protected function getPageTitle(): string + { + return (new \LengowTranslation($this->legacyContext))->t('tab.home'); + } + + #[AdminSecurity("is_granted('read', request.get('_legacy_controller'))")] + public function indexAction(Request $request): Response + { + $lengowController = new \LengowHomeController($this->legacyContext, $this->twig, true); + + $response = $this->handleLegacyPostAction($request, $lengowController); + if ($response instanceof Response) { + return $response; + } + + return $this->renderLegacyPage('@Modules/lengow/views/templates/admin/lengow_home/view.html.twig', $lengowController); + } +} diff --git a/src/Controller/Admin/LengowLegalsAdminController.php b/src/Controller/Admin/LengowLegalsAdminController.php new file mode 100644 index 00000000..e0c7f3ac --- /dev/null +++ b/src/Controller/Admin/LengowLegalsAdminController.php @@ -0,0 +1,51 @@ + + * @copyright 2017 Lengow SAS + * @license http://www.apache.org/licenses/LICENSE-2.0 + */ +declare(strict_types=1); + +namespace PrestaShop\Module\Lengow\Controller\Admin; + +if (!defined('_PS_VERSION_')) { + exit; +} + +use PrestaShopBundle\Security\Attribute\AdminSecurity; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +class LengowLegalsAdminController extends AbstractLengowAdminController +{ + protected function getPageTitle(): string + { + return (new \LengowTranslation($this->legacyContext))->t('tab.legals'); + } + + #[AdminSecurity("is_granted('read', request.get('_legacy_controller'))")] + public function indexAction(Request $request): Response + { + $lengowController = new \LengowLegalsController($this->legacyContext, $this->twig, true); + $response = $this->handleLegacyPostAction($request, $lengowController); + if ($response instanceof Response) { + return $response; + } + + return $this->renderLegacyPage('@Modules/lengow/views/templates/admin/lengow_legals/view.html.twig', $lengowController); + } +} diff --git a/src/Controller/Admin/LengowMainSettingAdminController.php b/src/Controller/Admin/LengowMainSettingAdminController.php new file mode 100644 index 00000000..44e754b2 --- /dev/null +++ b/src/Controller/Admin/LengowMainSettingAdminController.php @@ -0,0 +1,51 @@ + + * @copyright 2017 Lengow SAS + * @license http://www.apache.org/licenses/LICENSE-2.0 + */ +declare(strict_types=1); + +namespace PrestaShop\Module\Lengow\Controller\Admin; + +if (!defined('_PS_VERSION_')) { + exit; +} + +use PrestaShopBundle\Security\Attribute\AdminSecurity; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +class LengowMainSettingAdminController extends AbstractLengowAdminController +{ + protected function getPageTitle(): string + { + return (new \LengowTranslation($this->legacyContext))->t('tab.main_setting'); + } + + #[AdminSecurity("is_granted('read', request.get('_legacy_controller'))")] + public function indexAction(Request $request): Response + { + $lengowController = new \LengowMainSettingController($this->legacyContext, $this->twig, true); + $response = $this->handleLegacyPostAction($request, $lengowController); + if ($response instanceof Response) { + return $response; + } + + return $this->renderLegacyPage('@Modules/lengow/views/templates/admin/lengow_main_setting/view.html.twig', $lengowController); + } +} diff --git a/src/Controller/Admin/LengowOrderAdminController.php b/src/Controller/Admin/LengowOrderAdminController.php new file mode 100644 index 00000000..0285e02f --- /dev/null +++ b/src/Controller/Admin/LengowOrderAdminController.php @@ -0,0 +1,53 @@ + + * @copyright 2017 Lengow SAS + * @license http://www.apache.org/licenses/LICENSE-2.0 + */ + +declare(strict_types=1); + +namespace PrestaShop\Module\Lengow\Controller\Admin; + +if (!defined('_PS_VERSION_')) { + exit; +} + +use PrestaShopBundle\Security\Attribute\AdminSecurity; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +class LengowOrderAdminController extends AbstractLengowAdminController +{ + protected function getPageTitle(): string + { + return (new \LengowTranslation($this->legacyContext))->t('tab.order'); + } + + #[AdminSecurity("is_granted('read', request.get('_legacy_controller'))")] + public function indexAction(Request $request): Response + { + $lengowController = new \LengowOrderController($this->legacyContext, $this->twig, true); + + $response = $this->handleLegacyPostAction($request, $lengowController); + if ($response instanceof Response) { + return $response; + } + + return $this->renderLegacyPage('@Modules/lengow/views/templates/admin/lengow_order/view.html.twig', $lengowController); + } +} diff --git a/src/Controller/Admin/LengowOrderSettingAdminController.php b/src/Controller/Admin/LengowOrderSettingAdminController.php new file mode 100644 index 00000000..3778b15b --- /dev/null +++ b/src/Controller/Admin/LengowOrderSettingAdminController.php @@ -0,0 +1,51 @@ + + * @copyright 2017 Lengow SAS + * @license http://www.apache.org/licenses/LICENSE-2.0 + */ +declare(strict_types=1); + +namespace PrestaShop\Module\Lengow\Controller\Admin; + +if (!defined('_PS_VERSION_')) { + exit; +} + +use PrestaShopBundle\Security\Attribute\AdminSecurity; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +class LengowOrderSettingAdminController extends AbstractLengowAdminController +{ + protected function getPageTitle(): string + { + return (new \LengowTranslation($this->legacyContext))->t('tab.order_setting'); + } + + #[AdminSecurity("is_granted('read', request.get('_legacy_controller'))")] + public function indexAction(Request $request): Response + { + $lengowController = new \LengowOrderSettingController($this->legacyContext, $this->twig, true); + $response = $this->handleLegacyPostAction($request, $lengowController); + if ($response instanceof Response) { + return $response; + } + + return $this->renderLegacyPage('@Modules/lengow/views/templates/admin/lengow_order_setting/view.html.twig', $lengowController); + } +} diff --git a/src/Controller/Admin/LengowToolboxAdminController.php b/src/Controller/Admin/LengowToolboxAdminController.php new file mode 100644 index 00000000..95778efc --- /dev/null +++ b/src/Controller/Admin/LengowToolboxAdminController.php @@ -0,0 +1,51 @@ + + * @copyright 2017 Lengow SAS + * @license http://www.apache.org/licenses/LICENSE-2.0 + */ +declare(strict_types=1); + +namespace PrestaShop\Module\Lengow\Controller\Admin; + +if (!defined('_PS_VERSION_')) { + exit; +} + +use PrestaShopBundle\Security\Attribute\AdminSecurity; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +class LengowToolboxAdminController extends AbstractLengowAdminController +{ + protected function getPageTitle(): string + { + return (new \LengowTranslation($this->legacyContext))->t('tab.toolbox'); + } + + #[AdminSecurity("is_granted('read', request.get('_legacy_controller'))")] + public function indexAction(Request $request): Response + { + $lengowController = new \LengowToolboxController($this->legacyContext, $this->twig, true); + $response = $this->handleLegacyPostAction($request, $lengowController); + if ($response instanceof Response) { + return $response; + } + + return $this->renderLegacyPage('@Modules/lengow/views/templates/admin/lengow_toolbox/view.html.twig', $lengowController); + } +} diff --git a/backup/override/index.php b/src/Controller/Admin/index.php old mode 100755 new mode 100644 similarity index 100% rename from backup/override/index.php rename to src/Controller/Admin/index.php diff --git a/src/Controller/AdminOrderController.php b/src/Controller/AdminOrderController.php deleted file mode 100644 index f5759a19..00000000 --- a/src/Controller/AdminOrderController.php +++ /dev/null @@ -1,632 +0,0 @@ - - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - */ - -namespace PrestaShop\Module\Lengow\Controller; - -use PrestaShop\PrestaShop\Core\Domain\CartRule\Exception\InvalidCartRuleDiscountValueException; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\UpdateOrderShippingDetailsCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\CannotEditDeliveredOrderProductException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\CannotFindProductInOrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\DuplicateProductInOrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\DuplicateProductInOrderInvoiceException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidAmountException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidCancelProductException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidOrderStateException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidProductQuantityException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\NegativePaymentAmountException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderEmailSendException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\TransistEmailSendingException; -use PrestaShop\PrestaShop\Core\Domain\Order\Query\GetOrderForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderForViewing; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductOutOfStockException; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\QuerySorting; -use PrestaShop\PrestaShop\Core\Order\OrderSiblingProviderInterface; -use PrestaShopBundle\Controller\Admin\Sell\Order\ActionsBarButtonsCollection; -use PrestaShopBundle\Controller\Admin\Sell\Order\OrderController; -use PrestaShopBundle\Exception\InvalidModuleException; -use PrestaShopBundle\Form\Admin\Sell\Customer\PrivateNoteType; -use PrestaShopBundle\Form\Admin\Sell\Order\AddOrderCartRuleType; -use PrestaShopBundle\Form\Admin\Sell\Order\AddProductRowType; -use PrestaShopBundle\Form\Admin\Sell\Order\ChangeOrderAddressType; -use PrestaShopBundle\Form\Admin\Sell\Order\ChangeOrderCurrencyType; -use PrestaShopBundle\Form\Admin\Sell\Order\EditProductRowType; -use PrestaShopBundle\Form\Admin\Sell\Order\InternalNoteType; -use PrestaShopBundle\Form\Admin\Sell\Order\OrderMessageType; -use PrestaShopBundle\Form\Admin\Sell\Order\OrderPaymentType; -use PrestaShopBundle\Form\Admin\Sell\Order\UpdateOrderShippingType; -use PrestaShopBundle\Form\Admin\Sell\Order\UpdateOrderStatusType; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -if (!defined('_PS_VERSION_')) { - exit; -} - -class AdminOrderController extends OrderController -{ - /** - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param int $orderId - * @param Request $request - * - * @return Response - */ - public function viewAction(int $orderId, Request $request): Response - { - try { - if (!$this->isFromLengow($orderId)) { - return parent::viewAction($orderId, $request); - } - /** @var OrderForViewing $orderForViewing */ - $orderForViewing = $this->getQueryBus()->handle(new GetOrderForViewing($orderId, QuerySorting::DESC)); - } catch (OrderException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - - return $this->redirectToRoute('admin_orders_index'); - } - $locale = new \LengowTranslation(); - $formFactory = $this->get('form.factory'); - $updateOrderStatusForm = $formFactory->createNamed( - 'update_order_status', - UpdateOrderStatusType::class, - [ - 'new_order_status_id' => $orderForViewing->getHistory()->getCurrentOrderStatusId(), - ] - ); - $updateOrderStatusActionBarForm = $formFactory->createNamed( - 'update_order_status_action_bar', - UpdateOrderStatusType::class, - [ - 'new_order_status_id' => $orderForViewing->getHistory()->getCurrentOrderStatusId(), - ] - ); - - $addOrderCartRuleForm = $this->createForm(AddOrderCartRuleType::class, [], [ - 'order_id' => $orderId, - ]); - $addOrderPaymentForm = $this->createForm(OrderPaymentType::class, [ - 'id_currency' => $orderForViewing->getCurrencyId(), - ], [ - 'id_order' => $orderId, - ]); - - $orderMessageForm = $this->createForm(OrderMessageType::class, [ - 'lang_id' => $orderForViewing->getCustomer()->getLanguageId(), - ], [ - 'action' => $this->generateUrl('admin_orders_send_message', ['orderId' => $orderId]), - ]); - $orderMessageForm->handleRequest($request); - - $changeOrderCurrencyForm = $this->createForm(ChangeOrderCurrencyType::class, [], [ - 'current_currency_id' => $orderForViewing->getCurrencyId(), - ]); - - $changeOrderAddressForm = null; - $privateNoteForm = null; - - if (null !== $orderForViewing->getCustomer() && $orderForViewing->getCustomer()->getId() !== 0) { - $changeOrderAddressForm = $this->createForm(ChangeOrderAddressType::class, [], [ - 'customer_id' => $orderForViewing->getCustomer()->getId(), - ]); - - $privateNoteForm = $this->createForm(PrivateNoteType::class, [ - 'note' => $orderForViewing->getCustomer()->getPrivateNote(), - ]); - } - - $updateOrderShippingForm = $this->createForm(UpdateOrderShippingType::class, [ - 'new_carrier_id' => $orderForViewing->getCarrierId(), - ], [ - 'order_id' => $orderId, - ]); - $isActiveReturnCarrier = false; - $isActiveReturnTrackingNumber = false; - if ($this->isFromLengow($orderId)) { - $isActiveReturnTrackingNumber = $this->isActiveReturnTrackingNumber($orderId); - $isActiveReturnCarrier = $this->isActiveReturnTrackingCarrier($orderId); - } - - if ($isActiveReturnTrackingNumber) { - $returnTrackingNumber = $this->getReturnTrackingNumber($orderId); - $updateOrderShippingForm->add(\LengowAction::ARG_RETURN_TRACKING_NUMBER, TextType::class, [ - 'required' => false, - 'data' => $returnTrackingNumber, - ]); - } - - if ($isActiveReturnCarrier) { - $returnCarrier = $this->getReturnCarrier($orderId); - $updateOrderShippingForm->add(\LengowAction::ARG_RETURN_CARRIER, ChoiceType::class, [ - 'required' => false, - 'data' => $returnCarrier, - 'choices' => \LengowCarrier::getCarriersChoices( - $orderForViewing->getCustomer()->getLanguageId() - ), - ]); - } - $currencyDataProvider = $this->container->get('prestashop.adapter.data_provider.currency'); - $orderCurrency = $currencyDataProvider->getCurrencyById($orderForViewing->getCurrencyId()); - - $addProductRowForm = $this->createForm(AddProductRowType::class, [], [ - 'order_id' => $orderId, - 'currency_id' => $orderForViewing->getCurrencyId(), - 'symbol' => $orderCurrency->symbol, - ]); - $editProductRowForm = $this->createForm(EditProductRowType::class, [], [ - 'order_id' => $orderId, - 'symbol' => $orderCurrency->symbol, - ]); - - $internalNoteForm = $this->createForm(InternalNoteType::class, [ - 'note' => $orderForViewing->getNote(), - ]); - - $formBuilder = $this->get('prestashop.core.form.identifiable_object.builder.cancel_product_form_builder'); - $backOfficeOrderButtons = new ActionsBarButtonsCollection(); - - try { - $this->dispatchHook( - 'actionGetAdminOrderButtons', - [ - 'controller' => $this, - 'id_order' => $orderId, - 'actions_bar_buttons_collection' => $backOfficeOrderButtons, - ] - ); - - $cancelProductForm = $formBuilder->getFormFor($orderId); - if ($this->isFromLengow($orderId)) { - $lengowOrder = new \LengowOrder($orderId); - $marketplace = $lengowOrder->getMarketplace(); - $refundReasons = $marketplace->getRefundReasons(); - $refundMode = $marketplace->getRefundModes(); - $refundSelectedDatas = $lengowOrder->getRefundDataFromLengowOrder($orderId, $marketplace->name); - } - } catch (\Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - - return $this->redirectToRoute('admin_orders_index'); - } - - $this->handleOutOfStockProduct($orderForViewing); - - $merchandiseReturnEnabled = (bool) $this->configuration->get('PS_ORDER_RETURN'); - - /** @var OrderSiblingProviderInterface $orderSiblingProvider */ - $orderSiblingProvider = $this->get('prestashop.adapter.order.order_sibling_provider'); - - $paginationNum = (int) $this->configuration->get('PS_ORDER_PRODUCTS_NB_PER_PAGE', self::DEFAULT_PRODUCTS_NUMBER); - $paginationNumOptions = self::PRODUCTS_PAGINATION_OPTIONS; - if (!in_array($paginationNum, $paginationNumOptions)) { - $paginationNumOptions[] = $paginationNum; - } - sort($paginationNumOptions); - $metatitle = sprintf( - '%s %s %s', - $this->trans('Orders', 'Admin.Orderscustomers.Feature'), - $this->configuration->get('PS_NAVIGATION_PIPE', '>'), - $this->trans( - 'Order %reference% from %firstname% %lastname%', - 'Admin.Orderscustomers.Feature', - [ - '%reference%' => $orderForViewing->getReference(), - '%firstname%' => $orderForViewing->getCustomer()->getFirstName(), - '%lastname%' => $orderForViewing->getCustomer()->getLastName(), - ] - ) - ); - - return $this->render('@PrestaShop/Admin/Sell/Order/Order/view.html.twig', [ - 'showContentHeader' => true, - 'enableSidebar' => true, - 'orderCurrency' => $orderCurrency, - 'meta_title' => $metatitle, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'orderForViewing' => $orderForViewing, - 'addOrderCartRuleForm' => $addOrderCartRuleForm->createView(), - 'updateOrderStatusForm' => $updateOrderStatusForm->createView(), - 'updateOrderStatusActionBarForm' => $updateOrderStatusActionBarForm->createView(), - 'addOrderPaymentForm' => $addOrderPaymentForm->createView(), - 'changeOrderCurrencyForm' => $changeOrderCurrencyForm->createView(), - 'privateNoteForm' => $privateNoteForm ? $privateNoteForm->createView() : null, - 'updateOrderShippingForm' => $updateOrderShippingForm->createView(), - 'cancelProductForm' => $cancelProductForm->createView(), - 'invoiceManagementIsEnabled' => $orderForViewing->isInvoiceManagementIsEnabled(), - 'changeOrderAddressForm' => $changeOrderAddressForm ? $changeOrderAddressForm->createView() : null, - 'orderMessageForm' => $orderMessageForm->createView(), - 'addProductRowForm' => $addProductRowForm->createView(), - 'editProductRowForm' => $editProductRowForm->createView(), - 'backOfficeOrderButtons' => $backOfficeOrderButtons, - 'merchandiseReturnEnabled' => $merchandiseReturnEnabled, - 'priceSpecification' => $this->getContextLocale()->getPriceSpecification($orderCurrency->iso_code)->toArray(), - 'previousOrderId' => $orderSiblingProvider->getPreviousOrderId($orderId), - 'nextOrderId' => $orderSiblingProvider->getNextOrderId($orderId), - 'paginationNum' => $paginationNum, - 'paginationNumOptions' => $paginationNumOptions, - 'isAvailableQuantityDisplayed' => $this->configuration->getBoolean('PS_STOCK_MANAGEMENT'), - 'internalNoteForm' => $internalNoteForm->createView(), - 'returnTrackingNumber' => $this->getReturnTrackingNumber($orderId), - 'returnCarrier' => $this->getReturnCarrier($orderId), - 'isActiveReturnTrackingNumber' => $isActiveReturnTrackingNumber, - 'isActiveReturnCarrier' => $isActiveReturnCarrier, - 'returnTrackingNumberLabel' => $locale->t('order.screen.return_tracking_number_label'), - 'returnCarrierLabel' => $locale->t('order.screen.return_carrier_label'), - 'returnCarrierName' => $this->getReturnCarrierName($orderId), - 'refundReasons' => $refundReasons ?? [], - 'refundModes' => $refundMode ?? [], - 'refundReasonSelected' => $refundSelectedDatas['refund_reason'] ?? '', - 'refundModeSelected' => $refundSelectedDatas['refund_mode'] ?? '', - ]); - } - - /** - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_orders_view", - * redirectQueryParamsToKeep={"orderId"}, - * message="You do not have permission to edit this." - * ) - * - * @param int $orderId - * @param Request $request - * - * @return RedirectResponse - */ - public function updateShippingAction(int $orderId, Request $request): RedirectResponse - { - $form = $this->createForm(UpdateOrderShippingType::class, [], [ - 'order_id' => $orderId, - ]); - - if ($this->isFromLengow($orderId)) { - if ($this->isActiveReturnTrackingNumber($orderId)) { - $form->add(\LengowAction::ARG_RETURN_TRACKING_NUMBER, TextType::class, [ - 'required' => false, - ]); - } - if ($this->isActiveReturnTrackingCarrier($orderId)) { - $order = new \LengowOrder($orderId); - $form->add(\LengowAction::ARG_RETURN_CARRIER, ChoiceType::class, [ - 'required' => false, - 'choices' => \LengowCarrier::getCarriersChoices( - $order->id_lang - ), - ]); - } - } - - $form->handleRequest($request); - - if ($form->isSubmitted() && $form->isValid()) { - $data = $form->getData(); - - try { - if (!empty($data[\LengowAction::ARG_RETURN_TRACKING_NUMBER])) { - \LengowOrderDetail::updateOrderReturnTrackingNumber( - $data[\LengowAction::ARG_RETURN_TRACKING_NUMBER], - $orderId - ); - } - if (!empty($data[\LengowAction::ARG_RETURN_CARRIER])) { - \LengowOrderDetail::updateOrderReturnCarrier( - (int) $data[\LengowAction::ARG_RETURN_CARRIER], - $orderId - ); - } - $this->getCommandBus()->handle( - new UpdateOrderShippingDetailsCommand( - $orderId, - (int) $data['current_order_carrier_id'], - (int) $data['new_carrier_id'], - $data['tracking_number'] - ) - ); - - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - } catch (TransistEmailSendingException $e) { - $this->addFlash( - 'error', - $this->trans( - 'An error occurred while sending an email to the customer.', - 'Admin.Orderscustomers.Notification' - ) - ); - } catch (\Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - } else { - // exit ('form not valid'); - } - - return $this->redirectToRoute('admin_orders_view', [ - 'orderId' => $orderId, - ]); - } - - /** - * @param OrderForViewing $orderForViewing - */ - private function handleOutOfStockProduct(OrderForViewing $orderForViewing) - { - $isStockManagementEnabled = $this->configuration->getBoolean('PS_STOCK_MANAGEMENT'); - if (!$isStockManagementEnabled || $orderForViewing->isDelivered() || $orderForViewing->isShipped()) { - return; - } - - foreach ($orderForViewing->getProducts()->getProducts() as $product) { - if ($product->getAvailableQuantity() <= 0) { - $this->addFlash( - 'warning', - $this->trans('This product is out of stock:', 'Admin.Orderscustomers.Notification') . ' ' . $product->getName() - ); - } - } - } - - /** - * @param \Exception $e - * - * @return array - */ - private function getErrorMessages(\Exception $e) - { - $refundableQuantity = 0; - if ($e instanceof InvalidCancelProductException) { - $refundableQuantity = $e->getRefundableQuantity(); - } - $orderInvoiceNumber = '#unknown'; - if ($e instanceof DuplicateProductInOrderInvoiceException) { - $orderInvoiceNumber = $e->getOrderInvoiceNumber(); - } - - return [ - CannotEditDeliveredOrderProductException::class => $this->trans('You cannot edit the cart once the order delivered.', 'Admin.Orderscustomers.Notification'), - OrderNotFoundException::class => $e instanceof OrderNotFoundException ? - $this->trans( - 'Order #%d cannot be loaded.', - 'Admin.Orderscustomers.Notification', - ['#%d' => $e->getOrderId()->getValue()] - ) : '', - OrderEmailSendException::class => $this->trans( - 'An error occurred while sending the e-mail to the customer.', - 'Admin.Orderscustomers.Notification' - ), - OrderException::class => $this->trans( - $e->getMessage(), - 'Admin.Orderscustomers.Notification' - ), - InvalidAmountException::class => $this->trans( - 'Only numbers and decimal points (".") are allowed in the amount fields, e.g. 10.50 or 1050.', - 'Admin.Orderscustomers.Notification' - ), - InvalidCartRuleDiscountValueException::class => [ - InvalidCartRuleDiscountValueException::INVALID_MIN_PERCENT => $this->trans( - 'Percent value must be greater than 0.', - 'Admin.Orderscustomers.Notification' - ), - InvalidCartRuleDiscountValueException::INVALID_MAX_PERCENT => $this->trans( - 'Percent value cannot exceed 100.', - 'Admin.Orderscustomers.Notification' - ), - InvalidCartRuleDiscountValueException::INVALID_MIN_AMOUNT => $this->trans( - 'Amount value must be greater than 0.', - 'Admin.Orderscustomers.Notification' - ), - InvalidCartRuleDiscountValueException::INVALID_MAX_AMOUNT => $this->trans( - 'Discount value cannot exceed the total price of this order.', - 'Admin.Orderscustomers.Notification' - ), - InvalidCartRuleDiscountValueException::INVALID_FREE_SHIPPING => $this->trans( - 'Shipping discount value cannot exceed the total price of this order.', - 'Admin.Orderscustomers.Notification' - ), - ], - InvalidCancelProductException::class => [ - InvalidCancelProductException::INVALID_QUANTITY => $this->trans( - 'Positive product quantity is required.', - 'Admin.Notifications.Error' - ), - InvalidCancelProductException::QUANTITY_TOO_HIGH => $this->trans( - 'Please enter a maximum quantity of [1].', - 'Admin.Orderscustomers.Notification', - ['[1]' => $refundableQuantity] - ), - InvalidCancelProductException::NO_REFUNDS => $this->trans( - 'Please select at least one product.', - 'Admin.Orderscustomers.Notification' - ), - InvalidCancelProductException::INVALID_AMOUNT => $this->trans( - 'Please enter a positive amount.', - 'Admin.Orderscustomers.Notification' - ), - InvalidCancelProductException::NO_GENERATION => $this->trans( - 'Please generate at least one credit slip or voucher.', - 'Admin.Orderscustomers.Notification' - ), - ], - InvalidModuleException::class => $this->trans( - 'You must choose a payment module to create the order.', - 'Admin.Orderscustomers.Notification' - ), - ProductOutOfStockException::class => $this->trans( - 'There are not enough products in stock.', - 'Admin.Catalog.Notification' - ), - NegativePaymentAmountException::class => $this->trans( - 'Invalid value: the payment must be a positive amount.', - 'Admin.Notifications.Error' - ), - InvalidOrderStateException::class => [ - InvalidOrderStateException::ALREADY_PAID => $this->trans( - 'Invalid action: this order has already been paid.', - 'Admin.Notifications.Error' - ), - InvalidOrderStateException::DELIVERY_NOT_FOUND => $this->trans( - 'Invalid action: this order has not been delivered.', - 'Admin.Notifications.Error' - ), - InvalidOrderStateException::UNEXPECTED_DELIVERY => $this->trans( - 'Invalid action: this order has already been delivered.', - 'Admin.Notifications.Error' - ), - InvalidOrderStateException::NOT_PAID => $this->trans( - 'Invalid action: this order has not been paid.', - 'Admin.Notifications.Error' - ), - InvalidOrderStateException::INVALID_ID => $this->trans( - 'You must choose an order status to create the order.', - 'Admin.Orderscustomers.Notification' - ), - ], - - OrderConstraintException::class => [ - OrderConstraintException::INVALID_CUSTOMER_MESSAGE => $this->trans( - 'The order message given is invalid.', - 'Admin.Orderscustomers.Notification' - ), - ], - InvalidProductQuantityException::class => $this->trans( - 'Positive product quantity is required.', - 'Admin.Notifications.Error' - ), - DuplicateProductInOrderException::class => $this->trans( - 'This product is already in your order, please edit the quantity instead.', - 'Admin.Notifications.Error' - ), - DuplicateProductInOrderInvoiceException::class => $this->trans( - 'This product is already in the invoice [1], please edit the quantity instead.', - 'Admin.Notifications.Error', - ['[1]' => $orderInvoiceNumber] - ), - CannotFindProductInOrderException::class => $this->trans( - 'You cannot edit the price of a product that no longer exists in your catalog.', - 'Admin.Notifications.Error' - ), - ]; - } - - /** - * @return bool - */ - private function isActiveReturnTrackingNumber(int $orderId): bool - { - $lengowOrder = new \LengowOrder($orderId); - if ($lengowOrder->getMarketplace()) { - return $lengowOrder->getMarketplace()->hasReturnTrackingNumber(); - } - - return false; - } - - /** - * @return bool - */ - private function isActiveReturnTrackingCarrier(int $orderId): bool - { - $lengowOrder = new \LengowOrder($orderId); - if ($lengowOrder->getMarketplace()) { - return $lengowOrder->getMarketplace()->hasReturnTrackingCarrier(); - } - - return false; - } - - /** - * @param int $orderId - * - * @return string - */ - private function getReturnTrackingNumber(int $orderId): string - { - return \LengowOrderDetail::getOrderReturnTrackingNumber($orderId); - } - - /** - * @param int $orderId - * - * @return string - */ - private function getReturnCarrier(int $orderId): string - { - return \LengowOrderDetail::getOrderReturnCarrier($orderId); - } - - /** - * @param int $orderId - * - * @return string - */ - private function getReturnCarrierName(int $orderId): string - { - return \LengowOrderDetail::getOrderReturnCarrierName($orderId); - } - - /** - * @param int $orderId - */ - private function isFromLengow(int $orderId): bool - { - return \LengowOrder::isFromLengow($orderId); - } - - public function saveRefundReason(Request $request) - { - $data = json_decode($request->getContent(), true); - $orderId = (int) $data['orderId']; - $reason = $data['reason'] ?? ''; - - if (empty($orderId) || empty($reason)) { - return new JsonResponse(['success' => false, 'message' => 'Données manquantes']); - } - - \Db::getInstance()->update('lengow_orders', [ - 'refund_reason' => pSQL($reason), - ], 'id_order = ' . (int) $orderId); - - return new JsonResponse(['success' => true]); - } - - public function saveRefundMode(Request $request) - { - $data = json_decode($request->getContent(), true); - $orderId = (int) $data['orderId']; - $reason = $data['mode'] ?? ''; - - if (empty($orderId) || empty($reason)) { - return new JsonResponse(['success' => false, 'message' => 'Données manquantes']); - } - - \Db::getInstance()->update('lengow_orders', [ - 'refund_mode' => pSQL($reason), - ], 'id_order = ' . (int) $orderId); - - return new JsonResponse(['success' => true]); - } -} diff --git a/controllers/admin/index.php b/src/Enum/index.php old mode 100755 new mode 100644 similarity index 100% rename from controllers/admin/index.php rename to src/Enum/index.php diff --git a/controllers/admin/AdminLengowFeedController.php b/src/Service/OrderRefundDataUpdater.php old mode 100755 new mode 100644 similarity index 53% rename from controllers/admin/AdminLengowFeedController.php rename to src/Service/OrderRefundDataUpdater.php index 5b9a7c3a..6ca76973 --- a/controllers/admin/AdminLengowFeedController.php +++ b/src/Service/OrderRefundDataUpdater.php @@ -1,6 +1,6 @@ - * @copyright 2017 Lengow SAS + * @copyright 2026 Lengow SAS * @license http://www.apache.org/licenses/LICENSE-2.0 */ -/* - * Admin Lengow feed Controller Class - */ + +declare(strict_types=1); + +namespace PrestaShop\Module\Lengow\Service; + if (!defined('_PS_VERSION_')) { exit; } -class AdminLengowFeedController extends ModuleAdminController + +final class OrderRefundDataUpdater { - /** - * Construct - */ - public function __construct() + public function updateRefundReason(int $orderId, string $reason): bool { - $this->lang = true; - $this->explicitSelect = true; - $this->lite_display = true; - $this->meta_title = 'Configuration'; - $this->list_no_link = true; - $this->template = 'layout.tpl'; - $this->display = 'view'; - - parent::__construct(); + return \Db::getInstance()->update( + 'lengow_orders', + ['refund_reason' => pSQL($reason)], + 'id_order = ' . $orderId + ); + } - $lengowController = new LengowFeedController(); - $lengowController->postProcess(); - $lengowController->display(); + public function updateRefundMode(int $orderId, string $mode): bool + { + return \Db::getInstance()->update( + 'lengow_orders', + ['refund_mode' => pSQL($mode)], + 'id_order = ' . $orderId + ); } } diff --git a/src/Service/index.php b/src/Service/index.php new file mode 100644 index 00000000..cbb2c701 --- /dev/null +++ b/src/Service/index.php @@ -0,0 +1,34 @@ + + * @copyright 2007-2016 PrestaShop SA + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + * International Registered Trademark & Property of PrestaShop SA + */ +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; diff --git a/tests/index.php b/tests/index.php new file mode 100644 index 00000000..cbb2c701 --- /dev/null +++ b/tests/index.php @@ -0,0 +1,34 @@ + + * @copyright 2007-2016 PrestaShop SA + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + * International Registered Trademark & Property of PrestaShop SA + */ +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; diff --git a/tests/phpstan/index.php b/tests/phpstan/index.php new file mode 100644 index 00000000..cbb2c701 --- /dev/null +++ b/tests/phpstan/index.php @@ -0,0 +1,34 @@ + + * @copyright 2007-2016 PrestaShop SA + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + * International Registered Trademark & Property of PrestaShop SA + */ +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; diff --git a/tools/build.sh b/tools/build.sh index 7daafbaf..35887af9 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -154,10 +154,10 @@ remove_files "$FOLDER_TMP" "dod.md" remove_files "$FOLDER_TMP" "README.md" # remove .gitignore remove_files "$FOLDER_TMP" ".gitignore" -# remove php-cs-fixer-cache +# remove php-cs-fixer conf & cache remove_files "$FOLDER_TMP" ".php-cs-fixer.cache" -remove_files "$FOLDER_TMP" ".php-cs-fixer.dist.php" remove_files "$FOLDER_TMP" ".php_cs.cache" +remove_files "$FOLDER_TMP" ".php-cs-fixer.dist.php" # remove .git remove_files "$FOLDER_TMP" ".git" rm -Rf "$FOLDER_TMP/.github" @@ -222,4 +222,4 @@ else mv "$ARCHIVE_NAME" ~/shared fi sleep 3 -echo "End of build." \ No newline at end of file +echo "End of build." diff --git a/tools/checkmd5.php b/tools/checkmd5.php index 180677bd..882f2ccc 100755 --- a/tools/checkmd5.php +++ b/tools/checkmd5.php @@ -1,5 +1,4 @@ + */ +function explorer(string $path): array { $paths = []; if (is_dir($path)) { @@ -65,7 +69,14 @@ function explorer($path) return $paths; } -function writeCsv($fp, $text, &$frontKey = []) +/** + * @param resource $fp + * @param string|array $text + * @param list $frontKey + * + * @return void + */ +function writeCsv($fp, $text, array &$frontKey = []): void { if (is_array($text)) { foreach ($text as $k => $v) { diff --git a/tools/translate.php b/tools/translate.php index f820850e..c582d793 100755 --- a/tools/translate.php +++ b/tools/translate.php @@ -1,5 +1,4 @@ $text + * @param list $frontKey + * + * @return void + */ +function writeCsv($fp, $text, array &$frontKey = []): void { if (is_array($text)) { foreach ($text as $k => $v) { diff --git a/tools/vars.enc b/tools/vars.enc index fcf15248..8e121716 100644 Binary files a/tools/vars.enc and b/tools/vars.enc differ diff --git a/vendor/autoload.php b/vendor/autoload.php index d0890515..b0df7528 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -2,6 +2,21 @@ // autoload.php @generated by Composer +if (PHP_VERSION_ID < 50600) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL; + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, $err); + } elseif (!headers_sent()) { + echo $err; + } + } + throw new RuntimeException($err); +} + require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit4bfa755ad204a2f10b057f94fa964aec::getLoader(); +return ComposerAutoloaderInit30bb8244360bd03582d49c20c2bea86f::getLoader(); diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index afef3fa2..7824d8f7 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -42,35 +42,37 @@ */ class ClassLoader { - /** @var ?string */ + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ private $vendorDir; // PSR-4 /** - * @var array[] - * @psalm-var array> + * @var array> */ private $prefixLengthsPsr4 = array(); /** - * @var array[] - * @psalm-var array> + * @var array> */ private $prefixDirsPsr4 = array(); /** - * @var array[] - * @psalm-var array + * @var list */ private $fallbackDirsPsr4 = array(); // PSR-0 /** - * @var array[] - * @psalm-var array> + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> */ private $prefixesPsr0 = array(); /** - * @var array[] - * @psalm-var array + * @var list */ private $fallbackDirsPsr0 = array(); @@ -78,8 +80,7 @@ class ClassLoader private $useIncludePath = false; /** - * @var string[] - * @psalm-var array + * @var array */ private $classMap = array(); @@ -87,29 +88,29 @@ class ClassLoader private $classMapAuthoritative = false; /** - * @var bool[] - * @psalm-var array + * @var array */ private $missingClasses = array(); - /** @var ?string */ + /** @var string|null */ private $apcuPrefix; /** - * @var self[] + * @var array */ private static $registeredLoaders = array(); /** - * @param ?string $vendorDir + * @param string|null $vendorDir */ public function __construct($vendorDir = null) { $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); } /** - * @return string[] + * @return array> */ public function getPrefixes() { @@ -121,8 +122,7 @@ public function getPrefixes() } /** - * @return array[] - * @psalm-return array> + * @return array> */ public function getPrefixesPsr4() { @@ -130,8 +130,7 @@ public function getPrefixesPsr4() } /** - * @return array[] - * @psalm-return array + * @return list */ public function getFallbackDirs() { @@ -139,8 +138,7 @@ public function getFallbackDirs() } /** - * @return array[] - * @psalm-return array + * @return list */ public function getFallbackDirsPsr4() { @@ -148,8 +146,7 @@ public function getFallbackDirsPsr4() } /** - * @return string[] Array of classname => path - * @psalm-return array + * @return array Array of classname => path */ public function getClassMap() { @@ -157,8 +154,7 @@ public function getClassMap() } /** - * @param string[] $classMap Class to filename map - * @psalm-param array $classMap + * @param array $classMap Class to filename map * * @return void */ @@ -175,24 +171,25 @@ public function addClassMap(array $classMap) * Registers a set of PSR-0 directories for a given prefix, either * appending or prepending to the ones previously set for this prefix. * - * @param string $prefix The prefix - * @param string[]|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories * * @return void */ public function add($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { if ($prepend) { $this->fallbackDirsPsr0 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr0 ); } else { $this->fallbackDirsPsr0 = array_merge( $this->fallbackDirsPsr0, - (array) $paths + $paths ); } @@ -201,19 +198,19 @@ public function add($prefix, $paths, $prepend = false) $first = $prefix[0]; if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = (array) $paths; + $this->prefixesPsr0[$first][$prefix] = $paths; return; } if ($prepend) { $this->prefixesPsr0[$first][$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixesPsr0[$first][$prefix] ); } else { $this->prefixesPsr0[$first][$prefix] = array_merge( $this->prefixesPsr0[$first][$prefix], - (array) $paths + $paths ); } } @@ -222,9 +219,9 @@ public function add($prefix, $paths, $prepend = false) * Registers a set of PSR-4 directories for a given namespace, either * appending or prepending to the ones previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param string[]|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException * @@ -232,17 +229,18 @@ public function add($prefix, $paths, $prepend = false) */ public function addPsr4($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { // Register directories for the root namespace. if ($prepend) { $this->fallbackDirsPsr4 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr4 ); } else { $this->fallbackDirsPsr4 = array_merge( $this->fallbackDirsPsr4, - (array) $paths + $paths ); } } elseif (!isset($this->prefixDirsPsr4[$prefix])) { @@ -252,18 +250,18 @@ public function addPsr4($prefix, $paths, $prepend = false) throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); } $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; + $this->prefixDirsPsr4[$prefix] = $paths; } elseif ($prepend) { // Prepend directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixDirsPsr4[$prefix] ); } else { // Append directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( $this->prefixDirsPsr4[$prefix], - (array) $paths + $paths ); } } @@ -272,8 +270,8 @@ public function addPsr4($prefix, $paths, $prepend = false) * Registers a set of PSR-0 directories for a given prefix, * replacing any others previously set for this prefix. * - * @param string $prefix The prefix - * @param string[]|string $paths The PSR-0 base directories + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories * * @return void */ @@ -290,8 +288,8 @@ public function set($prefix, $paths) * Registers a set of PSR-4 directories for a given namespace, * replacing any others previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param string[]|string $paths The PSR-4 base directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories * * @throws \InvalidArgumentException * @@ -425,7 +423,8 @@ public function unregister() public function loadClass($class) { if ($file = $this->findFile($class)) { - includeFile($file); + $includeFile = self::$includeFile; + $includeFile($file); return true; } @@ -476,9 +475,9 @@ public function findFile($class) } /** - * Returns the currently registered loaders indexed by their corresponding vendor directories. + * Returns the currently registered loaders keyed by their corresponding vendor directories. * - * @return self[] + * @return array */ public static function getRegisteredLoaders() { @@ -555,18 +554,26 @@ private function findFileWithExtension($class, $ext) return false; } -} -/** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - * - * @param string $file - * @return void - * @private - */ -function includeFile($file) -{ - include $file; + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } } diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index 01581949..2052022f 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -21,15 +21,28 @@ * See also https://getcomposer.org/doc/07-runtime.md#installed-versions * * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final */ class InstalledVersions { + /** + * @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to + * @internal + */ + private static $selfDir = null; + /** * @var mixed[]|null - * @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array}|array{}|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null */ private static $installed; + /** + * @var bool + */ + private static $installedIsLocalDir; + /** * @var bool|null */ @@ -37,7 +50,7 @@ class InstalledVersions /** * @var array[] - * @psalm-var array}> + * @psalm-var array}> */ private static $installedByVendor = array(); @@ -96,7 +109,7 @@ public static function isInstalled($packageName, $includeDevRequirements = true) { foreach (self::getInstalled() as $installed) { if (isset($installed['versions'][$packageName])) { - return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']); + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; } } @@ -117,7 +130,7 @@ public static function isInstalled($packageName, $includeDevRequirements = true) */ public static function satisfies(VersionParser $parser, $packageName, $constraint) { - $constraint = $parser->parseConstraints($constraint); + $constraint = $parser->parseConstraints((string) $constraint); $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); return $provided->matches($constraint); @@ -241,7 +254,7 @@ public static function getInstallPath($packageName) /** * @return array - * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string} + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} */ public static function getRootPackage() { @@ -255,7 +268,7 @@ public static function getRootPackage() * * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. * @return array[] - * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array} + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} */ public static function getRawData() { @@ -278,7 +291,7 @@ public static function getRawData() * Returns the raw data of all installed.php which are currently loaded for custom implementations * * @return array[] - * @psalm-return list}> + * @psalm-return list}> */ public static function getAllRawData() { @@ -301,17 +314,35 @@ public static function getAllRawData() * @param array[] $data A vendor/composer/installed.php data set * @return void * - * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array} $data + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data */ public static function reload($data) { self::$installed = $data; self::$installedByVendor = array(); + + // when using reload, we disable the duplicate protection to ensure that self::$installed data is + // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not, + // so we have to assume it does not, and that may result in duplicate data being returned when listing + // all installed packages for example + self::$installedIsLocalDir = false; + } + + /** + * @return string + */ + private static function getSelfDir() + { + if (self::$selfDir === null) { + self::$selfDir = strtr(__DIR__, '\\', '/'); + } + + return self::$selfDir; } /** * @return array[] - * @psalm-return list}> + * @psalm-return list}> */ private static function getInstalled() { @@ -320,19 +351,27 @@ private static function getInstalled() } $installed = array(); + $copiedLocalDir = false; if (self::$canGetVendors) { + $selfDir = self::getSelfDir(); foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + $vendorDir = strtr($vendorDir, '\\', '/'); if (isset(self::$installedByVendor[$vendorDir])) { $installed[] = self::$installedByVendor[$vendorDir]; } elseif (is_file($vendorDir.'/composer/installed.php')) { /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ $required = require $vendorDir.'/composer/installed.php'; - $installed[] = self::$installedByVendor[$vendorDir] = $required; - if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { - self::$installed = $installed[count($installed) - 1]; + self::$installedByVendor[$vendorDir] = $required; + $installed[] = $required; + if (self::$installed === null && $vendorDir.'/composer' === $selfDir) { + self::$installed = $required; + self::$installedIsLocalDir = true; } } + if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) { + $copiedLocalDir = true; + } } } @@ -348,7 +387,7 @@ private static function getInstalled() } } - if (self::$installed !== array()) { + if (self::$installed !== array() && !$copiedLocalDir) { $installed[] = self::$installed; } diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 0c5abcef..b8bc5ddf 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -2,7 +2,7 @@ // autoload_classmap.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( @@ -17,6 +17,7 @@ 'LengowConfiguration' => $baseDir . '/classes/models/LengowConfiguration.php', 'LengowConfigurationForm' => $baseDir . '/classes/models/LengowConfigurationForm.php', 'LengowConnector' => $baseDir . '/classes/models/LengowConnector.php', + 'LengowContext' => $baseDir . '/classes/models/LengowContext.php', 'LengowController' => $baseDir . '/classes/controllers/LengowController.php', 'LengowCountry' => $baseDir . '/classes/models/LengowCountry.php', 'LengowCustomer' => $baseDir . '/classes/models/LengowCustomer.php', @@ -57,5 +58,15 @@ 'LengowToolboxController' => $baseDir . '/classes/controllers/LengowToolboxController.php', 'LengowToolboxElement' => $baseDir . '/classes/models/LengowToolboxElement.php', 'LengowTranslation' => $baseDir . '/classes/models/LengowTranslation.php', - 'PrestaShop\\Module\\Lengow\\Controller\\AdminOrderController' => $baseDir . '/src/Controller/AdminOrderController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\AbstractLengowAdminController' => $baseDir . '/src/Controller/Admin/AbstractLengowAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowDashboardAdminController' => $baseDir . '/src/Controller/Admin/LengowDashboardAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowFeedAdminController' => $baseDir . '/src/Controller/Admin/LengowFeedAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowHelpAdminController' => $baseDir . '/src/Controller/Admin/LengowHelpAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowHomeAdminController' => $baseDir . '/src/Controller/Admin/LengowHomeAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowLegalsAdminController' => $baseDir . '/src/Controller/Admin/LengowLegalsAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowMainSettingAdminController' => $baseDir . '/src/Controller/Admin/LengowMainSettingAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowOrderAdminController' => $baseDir . '/src/Controller/Admin/LengowOrderAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowOrderSettingAdminController' => $baseDir . '/src/Controller/Admin/LengowOrderSettingAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowToolboxAdminController' => $baseDir . '/src/Controller/Admin/LengowToolboxAdminController.php', + 'PrestaShop\\Module\\Lengow\\Service\\OrderRefundDataUpdater' => $baseDir . '/src/Service/OrderRefundDataUpdater.php', ); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php index b7fc0125..15a2ff3a 100644 --- a/vendor/composer/autoload_namespaces.php +++ b/vendor/composer/autoload_namespaces.php @@ -2,7 +2,7 @@ // autoload_namespaces.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 06646c2c..b22f76c6 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -2,9 +2,10 @@ // autoload_psr4.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\' => array($baseDir . '/src/Controller/Admin'), 'Lengow\\' => array($baseDir . '/src'), ); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index b3e5073b..45ec90e7 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit4bfa755ad204a2f10b057f94fa964aec +class ComposerAutoloaderInit30bb8244360bd03582d49c20c2bea86f { private static $loader; @@ -22,31 +22,14 @@ public static function getLoader() return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit4bfa755ad204a2f10b057f94fa964aec', 'loadClassLoader'), true, true); - self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); - spl_autoload_unregister(array('ComposerAutoloaderInit4bfa755ad204a2f10b057f94fa964aec', 'loadClassLoader')); - - $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); - if ($useStaticLoader) { - require __DIR__ . '/autoload_static.php'; - - call_user_func(\Composer\Autoload\ComposerStaticInit4bfa755ad204a2f10b057f94fa964aec::getInitializer($loader)); - } else { - $map = require __DIR__ . '/autoload_namespaces.php'; - foreach ($map as $namespace => $path) { - $loader->set($namespace, $path); - } - - $map = require __DIR__ . '/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - $loader->setPsr4($namespace, $path); - } - - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); - } - } + require __DIR__ . '/platform_check.php'; + + spl_autoload_register(array('ComposerAutoloaderInit30bb8244360bd03582d49c20c2bea86f', 'loadClassLoader'), true, true); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); + spl_autoload_unregister(array('ComposerAutoloaderInit30bb8244360bd03582d49c20c2bea86f', 'loadClassLoader')); + + require __DIR__ . '/autoload_static.php'; + call_user_func(\Composer\Autoload\ComposerStaticInit30bb8244360bd03582d49c20c2bea86f::getInitializer($loader)); $loader->register(true); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 87efdf91..e55768bc 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,17 +4,25 @@ namespace Composer\Autoload; -class ComposerStaticInit4bfa755ad204a2f10b057f94fa964aec +class ComposerStaticInit30bb8244360bd03582d49c20c2bea86f { public static $prefixLengthsPsr4 = array ( - 'L' => + 'P' => + array ( + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\' => 42, + ), + 'L' => array ( 'Lengow\\' => 7, ), ); public static $prefixDirsPsr4 = array ( - 'Lengow\\' => + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\' => + array ( + 0 => __DIR__ . '/../..' . '/src/Controller/Admin', + ), + 'Lengow\\' => array ( 0 => __DIR__ . '/../..' . '/src', ), @@ -32,6 +40,7 @@ class ComposerStaticInit4bfa755ad204a2f10b057f94fa964aec 'LengowConfiguration' => __DIR__ . '/../..' . '/classes/models/LengowConfiguration.php', 'LengowConfigurationForm' => __DIR__ . '/../..' . '/classes/models/LengowConfigurationForm.php', 'LengowConnector' => __DIR__ . '/../..' . '/classes/models/LengowConnector.php', + 'LengowContext' => __DIR__ . '/../..' . '/classes/models/LengowContext.php', 'LengowController' => __DIR__ . '/../..' . '/classes/controllers/LengowController.php', 'LengowCountry' => __DIR__ . '/../..' . '/classes/models/LengowCountry.php', 'LengowCustomer' => __DIR__ . '/../..' . '/classes/models/LengowCustomer.php', @@ -72,15 +81,25 @@ class ComposerStaticInit4bfa755ad204a2f10b057f94fa964aec 'LengowToolboxController' => __DIR__ . '/../..' . '/classes/controllers/LengowToolboxController.php', 'LengowToolboxElement' => __DIR__ . '/../..' . '/classes/models/LengowToolboxElement.php', 'LengowTranslation' => __DIR__ . '/../..' . '/classes/models/LengowTranslation.php', - 'PrestaShop\\Module\\Lengow\\Controller\\AdminOrderController' => __DIR__ . '/../..' . '/src/Controller/AdminOrderController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\AbstractLengowAdminController' => __DIR__ . '/../..' . '/src/Controller/Admin/AbstractLengowAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowDashboardAdminController' => __DIR__ . '/../..' . '/src/Controller/Admin/LengowDashboardAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowFeedAdminController' => __DIR__ . '/../..' . '/src/Controller/Admin/LengowFeedAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowHelpAdminController' => __DIR__ . '/../..' . '/src/Controller/Admin/LengowHelpAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowHomeAdminController' => __DIR__ . '/../..' . '/src/Controller/Admin/LengowHomeAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowLegalsAdminController' => __DIR__ . '/../..' . '/src/Controller/Admin/LengowLegalsAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowMainSettingAdminController' => __DIR__ . '/../..' . '/src/Controller/Admin/LengowMainSettingAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowOrderAdminController' => __DIR__ . '/../..' . '/src/Controller/Admin/LengowOrderAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowOrderSettingAdminController' => __DIR__ . '/../..' . '/src/Controller/Admin/LengowOrderSettingAdminController.php', + 'PrestaShop\\Module\\Lengow\\Controller\\Admin\\LengowToolboxAdminController' => __DIR__ . '/../..' . '/src/Controller/Admin/LengowToolboxAdminController.php', + 'PrestaShop\\Module\\Lengow\\Service\\OrderRefundDataUpdater' => __DIR__ . '/../..' . '/src/Service/OrderRefundDataUpdater.php', ); public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit4bfa755ad204a2f10b057f94fa964aec::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit4bfa755ad204a2f10b057f94fa964aec::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit4bfa755ad204a2f10b057f94fa964aec::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit30bb8244360bd03582d49c20c2bea86f::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit30bb8244360bd03582d49c20c2bea86f::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit30bb8244360bd03582d49c20c2bea86f::$classMap; }, null, ClassLoader::class); } diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 84952b60..71568d8e 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -1,22 +1,22 @@ array( - 'pretty_version' => '3.8.0', - 'version' => '3.8.0.0', + 'name' => 'prestashop/lengow', + 'pretty_version' => '3.9.4', + 'version' => '3.9.4.0', + 'reference' => null, 'type' => 'prestashop-module', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => null, - 'name' => 'prestashop/lengow', 'dev' => true, ), 'versions' => array( 'prestashop/lengow' => array( - 'pretty_version' => '3.8.0', - 'version' => '3.8.0.0', + 'pretty_version' => '3.9.4', + 'version' => '3.9.4.0', + 'reference' => null, 'type' => 'prestashop-module', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => null, 'dev_requirement' => false, ), ), diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php new file mode 100644 index 00000000..2beb1491 --- /dev/null +++ b/vendor/composer/platform_check.php @@ -0,0 +1,25 @@ += 80100)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + throw new \RuntimeException( + 'Composer detected issues in your platform: ' . implode(' ', $issues) + ); +} diff --git a/vendor/index.php b/vendor/index.php new file mode 100755 index 00000000..cbb2c701 --- /dev/null +++ b/vendor/index.php @@ -0,0 +1,34 @@ + + * @copyright 2007-2016 PrestaShop SA + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + * International Registered Trademark & Property of PrestaShop SA + */ +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; diff --git a/views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/Modal/update_shipping_modal.html.twig b/views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/Modal/update_shipping_modal.html.twig deleted file mode 100644 index f622f214..00000000 --- a/views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/Modal/update_shipping_modal.html.twig +++ /dev/null @@ -1,93 +0,0 @@ -{#** - * 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 - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/products.html.twig b/views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/products.html.twig deleted file mode 100644 index d2310454..00000000 --- a/views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/products.html.twig +++ /dev/null @@ -1,390 +0,0 @@ -{#** - * 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 - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set isColumnLocationDisplayed = false %} -{% set isColumnRefundedDisplayed = false %} -{% for product in orderForViewing.products.products|slice(0, paginationNum) %} - {% if product.location is not empty %} - {% set isColumnLocationDisplayed = true %} - {% endif %} - {% if product.quantityRefunded > 0 %} - {% set isColumnRefundedDisplayed = true %} - {% endif %} -{% endfor %} - -
-
-

- {{ 'Products'|trans({}, 'Admin.Global') }} ({{ orderForViewing.products.products|length }}) -

-
- -
-
-
-
- - {% set formOptions = { - 'attr': { - 'data-order-id': orderForViewing.id, - 'data-is-delivered': orderForViewing.isDelivered, - 'data-is-tax-included': orderForViewing.isTaxIncluded, - 'data-discounts-amount': orderForViewing.prices.discountsAmountRaw, - 'data-price-specification': priceSpecification|json_encode - } - } %} - {{ form_start(cancelProductForm, formOptions) }} - - {# PRODUCT TABLE #} - - - - - - - - - - - - {% if orderForViewing.hasInvoice() %} - - {% endif %} - {% if not orderForViewing.delivered %} - - {% endif %} - - - - - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/product_list.html.twig' %} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/add_product_row.html.twig' %} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/edit_product_row.html.twig' %} - -
-

{{ 'Product'|trans({}, 'Admin.Global') }}

-
-

{{ 'Price per unit'|trans({}, 'Admin.Advparameters.Feature') }}

- {{ orderForViewing.taxMethod }} -
-

{{ 'Quantity'|trans({}, 'Admin.Global') }}

-
-

{{ 'Stock location'|trans({}, 'Admin.Orderscustomers.Feature') }}

-
-

{{ 'Refunded'|trans({}, 'Admin.Orderscustomers.Feature') }}

-
-

{{ 'Available'|trans({}, 'Admin.Global') }}

-
-

{{ 'Total'|trans({}, 'Admin.Global') }}

- {{ orderForViewing.taxMethod }} -
-

{{ 'Invoice'|trans({}, 'Admin.Global') }}

-
-

{{ 'Actions'|trans({}, 'Admin.Global') }}

-
-

{{ 'Partial refund'|trans({}, 'Admin.Orderscustomers.Feature') }}

-
- - - {# PAGINATION AND ADD NEW PRODUCT/DISCOUNT #} -
-
-
- - -
- - {% set numPages = max(orderForViewing.products.products|length / paginationNum, 1)|round(0, 'ceil') %} - -
- -
- {% if not orderForViewing.delivered %} - - {% endif %} - -
- -
- - {# DISCOUNT LIST #} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/discount_list.html.twig' with { - 'discounts': orderForViewing.discounts.discounts, - 'orderId': orderForViewing.id - } %} - - - {# ORDER TOTALS #} - -
-
- -
-

- {{ 'Products'|trans({}, 'Admin.Global') }} -

- {{ orderForViewing.prices.productsPriceFormatted }} -
- -
-

- {{ 'Discounts'|trans({}, 'Admin.Global') }} -

- -{{ orderForViewing.prices.discountsAmountFormatted }} -
- - {% if orderForViewing.prices.wrappingPriceRaw.greaterThan(number(0)) %} -
-

- {{ 'Wrapping'|trans({}, 'Admin.Orderscustomers.Feature') }} -

- {{ orderForViewing.prices.wrappingPriceFormatted }} -
- {% endif %} - -
-

- {{ 'Shipping'|trans({}, 'Admin.Catalog.Feature') }} -

-
- {{ orderForViewing.prices.shippingPriceFormatted }} -
-
- {{ form_widget(cancelProductForm.shipping_amount) }} -
-
{{ orderCurrency.symbol }}
-
-
-

(max - {{ orderForViewing.prices.shippingRefundableAmountFormatted }} - tax included)

-
-
-
- - {% if not orderForViewing.taxIncluded %} -
-

- {{ 'Taxes'|trans({}, 'Admin.Global') }} -

- {{ orderForViewing.prices.taxesAmountFormatted }} -
- {% endif %} - -
-

- {{ 'Total'|trans({}, 'Admin.Global') }} -

- {{ orderForViewing.prices.totalAmountFormatted }} -
- -
-
- - {# PRICE DISPLAY #} -

- - {{ 'For this customer group, prices are displayed as: [1]%tax_method%[/1]'|trans({ - '%tax_method%': orderForViewing.taxMethod, - '[1]': '', - '[/1]': '' - }, 'Admin.Orderscustomers.Notification')|raw }}. - - {% if not configuration('PS_ORDER_RETURN') %} - {{ 'Merchandise returns are disabled'|trans({}, 'Admin.Orderscustomers.Notification') }} - {% endif %} - -

- - {# PRODUCT CANCEL #} -
- {% if refundReasons is defined and refundReasons is not empty %} -
- - -
- {% endif %} - {% if refundModes is defined and refundModes is not empty %} -
- - -
- {% endif %} -
- {{ form_widget(cancelProductForm.restock) }} -
-
- {{ form_widget(cancelProductForm.credit_slip) }} -
-
- {{ form_widget(cancelProductForm.voucher) }} -
-
-
- {{ form_widget(cancelProductForm.shipping) }} - ({{ orderForViewing.prices.shippingRefundableAmountFormatted }}) -
-
-
- {{ 'This order has been partially paid by voucher. Choose the amount you want to refund:'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ form_widget(cancelProductForm.voucher_refund_type) }} -
- {{ 'Error. You cannot refund a negative amount.'|trans({}, 'Admin.Orderscustomers.Notification') }} -
-
-
-
- {{ form_widget(cancelProductForm.cancel) }} - {{ form_widget(cancelProductForm.save) }} -
- - {{ form_end(cancelProductForm) }} -
-
- -{% if refundReasons is defined and refundReasons is not empty %} - {% block javascripts %} - - {% endblock %} -{% endif %} diff --git a/views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/shipping.html.twig b/views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/shipping.html.twig deleted file mode 100644 index 92839a46..00000000 --- a/views/PrestaShop/Admin/Sell/Order/Order/Blocks/View/shipping.html.twig +++ /dev/null @@ -1,110 +0,0 @@ -{#** - * 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 - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if not orderForViewing.virtual %} - - {% if orderForViewing.shipping.giftMessage %} -
- -
- {{ orderForViewing.shipping.giftMessage }} -
-
- {% endif %} - - - - - - - - - - - {% if isActiveReturnTrackingNumber is defined and isActiveReturnTrackingNumber and returnTrackingNumber is defined %} - - {% endif %} - {% if isActiveReturnCarrier is defined and isActiveReturnCarrier and returnCarrier is defined %} - - {% endif %} - - - - - {% for carrier in orderForViewing.shipping.carriers %} - - - - - - - - {% if isActiveReturnTrackingNumber is defined and isActiveReturnTrackingNumber and returnTrackingNumber is defined %} - - {% endif %} - {% if isActiveReturnCarrier is defined and isActiveReturnCarrier and returnCarrier is defined %} - - {% endif %} - - - - {% endfor %} - -
{{ 'Date'|trans({}, 'Admin.Global') }} {{ 'Carrier'|trans({}, 'Admin.Shipping.Feature') }}{{ 'Weight'|trans({}, 'Admin.Global') }}{{ 'Shipping cost'|trans({}, 'Admin.Shipping.Feature') }}{{ 'Tracking number'|trans({}, 'Admin.Shipping.Feature') }}{{ returnTrackingNumberLabel }}{{ returnCarrierLabel }}
{{ carrier.date|date_format_lite }} {{ carrier.name }}{{ carrier.weight }}{{ carrier.price }} - {% if carrier.trackingNumber %} - {% if carrier.trackingUrl %} - {{ carrier.trackingNumber }} - {% else %} - {{ carrier.trackingNumber }} - {% endif %} - {% endif %} - - {{ returnTrackingNumber }} - - {{ returnCarrierName }} - - {% if carrier.canEdit %} - - {{ 'Edit'|trans({}, 'Admin.Actions') }} - - {% endif %} -
- - {% if orderForViewing.shipping.carrierModuleInfo %} - {{ orderForViewing.shipping.carrierModuleInfo|raw }} - {% endif %} -{% else %} -

- {{ 'Shipping does not apply to virtual orders'|trans({}, 'Admin.Orderscustomers.Feature') }} -

-{% endif %} diff --git a/views/css/lengow-components.css b/views/css/lengow-components.css index 0445e22f..17bfa9ef 100755 --- a/views/css/lengow-components.css +++ b/views/css/lengow-components.css @@ -13,6 +13,10 @@ top: 0; } +a.lgw-box-link { + text-decoration: none !important; +} + .lgw-box-link .lgw-box { top: 0; color: #555; @@ -436,6 +440,7 @@ a.lgw-box-link:hover { border: 1px solid #d7d7d7; background: #fafafa; height: 44px; + padding: 0 !important; } .select2-container--default .select2-selection--single .select2-selection__rendered { @@ -634,7 +639,7 @@ a.lgw-box-link:hover { padding: 2px; border-radius: 50px; margin-right: 7px; - height: 18px; + height: 22px; border: 0; background: #d7d7d7; transition: all 100ms ease; @@ -666,7 +671,7 @@ a.lgw-box-link:hover { } .lgw-switch.checked span { - left: 24px; + left: 20px; /* was 24px: corrected for box-sizing:border-box (42px outer - 2px right padding - 18px circle = 22px, minus 2px initial padding = 20px) */ } .lgw-switch.checked:hover div, diff --git a/views/css/lengow-layout.css b/views/css/lengow-layout.css index 0cd455e7..cbbd5f66 100755 --- a/views/css/lengow-layout.css +++ b/views/css/lengow-layout.css @@ -27,6 +27,55 @@ body.page-topbar .cms-global{ margin: 0 auto; } +.lgw-ps9-content { + position: relative; + padding-top: 58px; +} + +.lgw-ps9-content .lengow-nav-top { + left: -16px; + right: -16px; + top: -16px; +} + +.lgw-ps9-content .lengow-nav li:not(.lengow_float_right) + li.lengow_float_right { + margin-left: auto; +} + +.lgw-ps9-content #lengow_logo a { + display: flex; + align-items: center; +} +.lgw-ps9-content #lengow_logo img { + margin-top: 0; +} + +.lgw-ps9-content #lgw-debug { + top: 38px; +} + +.lgw-ps9-content .lengow-nav-bottom { + top: 38px; + left: -16px; + right: -16px; +} + +.lgw-ps9-content:has(.lengow-nav-bottom) .cms-global { + padding-top: 54px; +} + +.lgw-ps9-content .lgw-container .accordion .marketplace { + display: flex; + align-items: center; + justify-content: space-between; + height: 40px; + padding-top: 0; + padding-bottom: 0; +} +.lgw-ps9-content .lgw-container .accordion .score { + float: none; +} + .lgw-block { display: block; line-height: 54px; @@ -387,7 +436,7 @@ body.page-sidebar-closed .lengow-nav-bottom { height: 54px; display: block; padding: 0 15px; - text-decoration: none; + text-decoration: none !important; transition: all 100ms ease; } diff --git a/views/css/lengow-pages.css b/views/css/lengow-pages.css index d0d1d6b4..d773ef27 100755 --- a/views/css/lengow-pages.css +++ b/views/css/lengow-pages.css @@ -206,15 +206,15 @@ } .lgw-home-header { - height: 240px; color: white; - padding: 60px 30px 0; + padding: 60px 30px; background: #2e3340; } .lgw-home-header h1 { margin: 15px 0 5px; font-weight: 300; + color: white; } .adminlengowhome .lgw-row h5 { @@ -227,6 +227,24 @@ margin: 60px 0 30px; } +.lgw-home-menu { + display: flex; + align-items: stretch; +} + +.lgw-home-menu .lgw-col-4 { + display: flex; +} + +.lgw-home-menu a.lgw-box-link { + display: flex; + flex: 1; +} + +.lgw-home-menu a.lgw-box-link .lgw-box { + flex: 1; +} + .lgw-home-menu .lgw-box { min-height: 280px; } diff --git a/views/js/lengow/feed.js b/views/js/lengow/feed.js index 9edafb74..8e7eeaab 100755 --- a/views/js/lengow/feed.js +++ b/views/js/lengow/feed.js @@ -50,9 +50,18 @@ document.addEventListener('DOMContentLoaded', function() { (function ($) { $(document).ready(function () { + function lengowIsValidUrl(url) { + try { + var parsed = new URL(url, window.location.origin); + return parsed.protocol === 'http:' || parsed.protocol === 'https:'; + } catch (e) { + return false; + } + } + function reloadTotal(data, idShop) { - lengow_jquery("#block_" + idShop + " .lengow_exported").html(data['total_export_product']); - lengow_jquery("#block_" + idShop + " .lengow_total").html(data['total_product']); + lengow_jquery("#block_" + idShop + " .lengow_exported").text(data['total_export_product']); + lengow_jquery("#block_" + idShop + " .lengow_total").text(data['total_product']); } $('.lgw-container').on('change', '.lengow_switch_option', function () { @@ -271,7 +280,7 @@ document.addEventListener('DOMContentLoaded', function() { $('.lengow_table').on('click', '.table_row td:not(.no-link)', function(){ var url = $(this).closest('.table_row').find('.feed_name a').attr('href'); - if (url) { + if (url && lengowIsValidUrl(url)) { window.open(url, '_blank'); }; return false; diff --git a/views/js/lengow/main_setting.js b/views/js/lengow/main_setting.js index 332df55d..3380becd 100755 --- a/views/js/lengow/main_setting.js +++ b/views/js/lengow/main_setting.js @@ -117,6 +117,15 @@ function openModal(){ (function ($) { $(document).ready(function () { + function lengowIsValidUrl(url) { + try { + var parsed = new URL(url, window.location.origin); + return parsed.protocol === 'http:' || parsed.protocol === 'https:'; + } catch (e) { + return false; + } + } + // modal // open modal $('.lgw-modal-delete').click(function(){ @@ -189,8 +198,9 @@ function openModal(){ } }); $('#download_log').click(function() { - if ($('#select_log').val() !== null) { - window.location.href = $('#select_log').val(); + var logUrl = $('#select_log').val(); + if (logUrl !== null && lengowIsValidUrl(logUrl)) { + window.location.href = logUrl; } }); // submit form diff --git a/views/js/lengow/order.js b/views/js/lengow/order.js index 5e89124e..78666f48 100755 --- a/views/js/lengow/order.js +++ b/views/js/lengow/order.js @@ -21,6 +21,15 @@ (function ($) { $(document).ready(function () { + function lengowIsValidUrl(url) { + try { + var parsed = new URL(url, window.location.origin); + return parsed.protocol === 'http:' || parsed.protocol === 'https:'; + } catch (e) { + return false; + } + } + $('#lengow_order_wrapper').on('click', '.lgw-pagination a', function () { if ($(this).parent().hasClass('disabled')) { return false; @@ -173,7 +182,7 @@ $('#lengow_order_wrapper').on('click', '#table_order td.link', function() { var link = $(this).parents('tr').find('td.reference a'); - if (link.length > 0){ + if (link.length > 0 && lengowIsValidUrl(link.attr('href'))){ window.open(link.attr('href')); } return false; @@ -199,7 +208,7 @@ $('.lengow_table').on('click', '.table_row td:not(.no-link)', function(){ var url = $(this).closest('.table_row').find('.reference a').attr('href'); - if (url) { + if (url && lengowIsValidUrl(url)) { window.open(url, '_blank'); }; return false; diff --git a/views/js/lengow/order_setting.js b/views/js/lengow/order_setting.js index e785866a..37e53bdc 100755 --- a/views/js/lengow/order_setting.js +++ b/views/js/lengow/order_setting.js @@ -36,7 +36,7 @@ function addScoreCarrier() { } }); - $(this).parents('li.lengow_marketplace').find('.score').html(nbs+' / '+total); + $(this).parents('li.lengow_marketplace').find('.score').text(nbs+' / '+total); if (nbs == total){ $(this).parents('li.lengow_marketplace') .find('.score') diff --git a/views/templates/admin/footer.tpl b/views/templates/admin/footer.tpl deleted file mode 100755 index ff2da61c..00000000 --- a/views/templates/admin/footer.tpl +++ /dev/null @@ -1,96 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - - diff --git a/views/templates/admin/header.tpl b/views/templates/admin/header.tpl deleted file mode 100755 index c7551191..00000000 --- a/views/templates/admin/header.tpl +++ /dev/null @@ -1,108 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - - - - - - - - - - - - - - -{if $displayToolbar eq 1} -
- -
-{/if} - - - - - - - diff --git a/views/templates/admin/header_order.tpl b/views/templates/admin/header_order.tpl deleted file mode 100755 index 6d858599..00000000 --- a/views/templates/admin/header_order.tpl +++ /dev/null @@ -1,33 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - - \ No newline at end of file diff --git a/views/templates/admin/lengow_dashboard/helpers/view/dashboard.html.twig b/views/templates/admin/lengow_dashboard/helpers/view/dashboard.html.twig new file mode 100644 index 00000000..dd6542bf --- /dev/null +++ b/views/templates/admin/lengow_dashboard/helpers/view/dashboard.html.twig @@ -0,0 +1,84 @@ +{# + * Copyright 2021 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +
+
+ {% if debugMode %} +
+ {{ locale.t('menu.debug_active') }} +
+ {% endif %} +
+
+ {% if not pluginIsUpToDate %} + {{ locale.t('menu.new_version_available', {'version': pluginData['version']}) }} + + {% endif %} +
+
+ {% if merchantStatus and merchantStatus['type'] == 'free_trial' and not merchantStatus['expired'] %} + {{ locale.t('menu.counter', {'counter': merchantStatus['day']}) }} + + {{ locale.t('menu.upgrade_account') }} + + {% endif %} +
+
+
+ lengow +

{{ locale.t('dashboard.screen.welcome_back') }}

+ + {{ locale.t('dashboard.screen.go_to_lengow') }} + +
+ +
+

{{ locale.t('dashboard.screen.some_help_title') }}

+

+ + {{ locale.t('dashboard.screen.get_in_touch') }} + +

+

+ {{ locale.t('dashboard.screen.visit_help_center') }} + {{ locale.t('dashboard.screen.configure_plugin') }} +

+
+
+
diff --git a/views/templates/admin/lengow_dashboard/helpers/view/dashboard.tpl b/views/templates/admin/lengow_dashboard/helpers/view/dashboard.tpl deleted file mode 100644 index 7629eabd..00000000 --- a/views/templates/admin/lengow_dashboard/helpers/view/dashboard.tpl +++ /dev/null @@ -1,99 +0,0 @@ -{* - * Copyright 2021 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2021 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} -
-
- {if $debugMode} -
- {$locale->t('menu.debug_active')|escape:'htmlall':'UTF-8'} -
- {/if} -
-
- {if !$pluginIsUpToDate } - {$locale->t('menu.new_version_available', ['version' => $pluginData['version']])|escape:'htmlall':'UTF-8'} - - {/if} -
-
- {if $merchantStatus && $merchantStatus['type'] == 'free_trial' && !$merchantStatus['expired']} - {$locale->t('menu.counter', ['counter' => $merchantStatus['day']])|escape:'htmlall':'UTF-8'} - - {$locale->t('menu.upgrade_account')|escape:'htmlall':'UTF-8'} - - {/if} -
-
-
- lengow -

{$locale->t('dashboard.screen.welcome_back')|escape:'htmlall':'UTF-8'}

- - {$locale->t('dashboard.screen.go_to_lengow')|escape:'htmlall':'UTF-8'} - -
- -
-

{$locale->t('dashboard.screen.some_help_title')|escape:'htmlall':'UTF-8'}

-

- - {$locale->t('dashboard.screen.get_in_touch')|escape:'htmlall':'UTF-8'} - -

-

- {$locale->t('dashboard.screen.visit_help_center')|escape:'htmlall':'UTF-8'} - {$locale->t('dashboard.screen.configure_plugin')|escape:'htmlall':'UTF-8'} -

-
-
-
\ No newline at end of file diff --git a/views/templates/admin/lengow_dashboard/helpers/view/status.html.twig b/views/templates/admin/lengow_dashboard/helpers/view/status.html.twig new file mode 100644 index 00000000..1277190e --- /dev/null +++ b/views/templates/admin/lengow_dashboard/helpers/view/status.html.twig @@ -0,0 +1,35 @@ +{# + * Copyright 2021 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +
+
+
+
+
+

{{ locale.t('status.screen.title_end_free_trial') }}

+

{{ locale.t('status.screen.subtitle_end_free_trial') }}

+

{{ locale.t('status.screen.first_description_end_free_trial') }}

+

{{ locale.t('status.screen.second_description_end_free_trial') }}

+

{{ locale.t('status.screen.third_description_end_free_trial')|raw }}

+ + +
+
+
+ lengow +
+
+
+
+
+
diff --git a/views/templates/admin/lengow_dashboard/helpers/view/status.tpl b/views/templates/admin/lengow_dashboard/helpers/view/status.tpl deleted file mode 100644 index 823d7043..00000000 --- a/views/templates/admin/lengow_dashboard/helpers/view/status.tpl +++ /dev/null @@ -1,50 +0,0 @@ -{* - * Copyright 2021 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2021 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} -
-
-
-
-
-

{$locale->t('status.screen.title_end_free_trial')|escape:'htmlall':'UTF-8'}

-

{$locale->t('status.screen.subtitle_end_free_trial')|escape:'htmlall':'UTF-8'}

-

{$locale->t('status.screen.first_description_end_free_trial')|escape:'htmlall':'UTF-8'}

-

{$locale->t('status.screen.second_description_end_free_trial')|escape:'htmlall':'UTF-8'}

-

{html_entity_decode($locale->t('status.screen.third_description_end_free_trial')|escape:'htmlall':'UTF-8')}

- - -
-
-
- lengow -
-
-
-
-
-
\ No newline at end of file diff --git a/views/templates/admin/lengow_dashboard/helpers/view/view.tpl b/views/templates/admin/lengow_dashboard/helpers/view/view.tpl deleted file mode 100644 index c61ec30f..00000000 --- a/views/templates/admin/lengow_dashboard/helpers/view/view.tpl +++ /dev/null @@ -1,26 +0,0 @@ -{* - * Copyright 2021 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2021 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - - -{if ($merchantStatus && $merchantStatus['type'] == 'free_trial' && $merchantStatus['expired'])} - {include file='./status.tpl'} -{else} - {include file='./dashboard.tpl'} -{/if} \ No newline at end of file diff --git a/views/templates/admin/lengow_dashboard/layout.tpl b/views/templates/admin/lengow_dashboard/layout.tpl deleted file mode 100644 index ef1349e2..00000000 --- a/views/templates/admin/lengow_dashboard/layout.tpl +++ /dev/null @@ -1,24 +0,0 @@ -{* - * Copyright 2021 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2021 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -{include file='../header.tpl'} -{html_entity_decode($content|escape:'htmlall':'UTF-8')} -{include file='../footer.tpl'} - diff --git a/views/templates/admin/lengow_dashboard/view.html.twig b/views/templates/admin/lengow_dashboard/view.html.twig new file mode 100644 index 00000000..73eee822 --- /dev/null +++ b/views/templates/admin/lengow_dashboard/view.html.twig @@ -0,0 +1,22 @@ +{# + * Copyright 2021 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +{% extends base_layout %} + +{% block lengow_header %} + {% include '@Modules/lengow/views/templates/admin/twig/header.html.twig' %} +{% endblock %} + +{% block lengow_content %} + + {% if merchantStatus and merchantStatus['type'] == 'free_trial' and merchantStatus['expired'] %} + {% include '@Modules/lengow/views/templates/admin/lengow_dashboard/helpers/view/status.html.twig' %} + {% else %} + {% include '@Modules/lengow/views/templates/admin/lengow_dashboard/helpers/view/dashboard.html.twig' %} + {% endif %} +{% endblock %} + +{% block lengow_footer %} + {% include '@Modules/lengow/views/templates/admin/twig/footer.html.twig' %} +{% endblock %} diff --git a/views/templates/admin/lengow_feed/helpers/view/view.tpl b/views/templates/admin/lengow_feed/helpers/view/view.tpl deleted file mode 100755 index f6ef6c57..00000000 --- a/views/templates/admin/lengow_feed/helpers/view/view.tpl +++ /dev/null @@ -1,158 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -
-
- {if $debugMode} -
- {$locale->t('menu.debug_active')|escape:'htmlall':'UTF-8'} -
- {/if} - {foreach from=$shopCollection item=shop} -
-
- - - -
-
-
- - -
-
-

- {$shop['total_export_product']|escape:'htmlall':'UTF-8'} - {$locale->t('product.screen.nb_exported')|escape:'htmlall':'UTF-8'} -

-

- {$shop['total_product']|escape:'htmlall':'UTF-8'} - {$locale->t('product.screen.nb_available')|escape:'htmlall':'UTF-8'} -

-
-
-
-
-
- -
- -
-
-
-
- -
- -
-
-
-
- -
- -
-
-
-
- -
- -
-
-
- -
- {/foreach} -
-
- diff --git a/views/templates/admin/lengow_feed/layout.tpl b/views/templates/admin/lengow_feed/layout.tpl deleted file mode 100755 index 3b92863a..00000000 --- a/views/templates/admin/lengow_feed/layout.tpl +++ /dev/null @@ -1,23 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -{include file='../header.tpl'} -{html_entity_decode($content|escape:'htmlall':'UTF-8')} -{include file='../footer.tpl'} diff --git a/views/templates/admin/lengow_feed/view.html.twig b/views/templates/admin/lengow_feed/view.html.twig new file mode 100644 index 00000000..9d8fdcba --- /dev/null +++ b/views/templates/admin/lengow_feed/view.html.twig @@ -0,0 +1,151 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +{% extends base_layout %} + +{% block lengow_header %} + {% include '@Modules/lengow/views/templates/admin/twig/header.html.twig' %} +{% endblock %} + +{% block lengow_content %} +
+
+ {% if debugMode %} +
+ {{ locale.t('menu.debug_active') }} +
+ {% endif %} + {% for shop in shopCollection %} +
+
+ + + +
+
+
+ + +
+
+

+ {{ shop['total_export_product'] }} + {{ locale.t('product.screen.nb_exported') }} +

+

+ {{ shop['total_product'] }} + {{ locale.t('product.screen.nb_available') }} +

+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ {% endfor %} +
+
+ +{% endblock %} + +{% block lengow_footer %} + {% include '@Modules/lengow/views/templates/admin/twig/footer.html.twig' %} +{% endblock %} diff --git a/views/templates/admin/lengow_help/helpers/view/view.tpl b/views/templates/admin/lengow_help/helpers/view/view.tpl deleted file mode 100755 index 56d2359a..00000000 --- a/views/templates/admin/lengow_help/helpers/view/view.tpl +++ /dev/null @@ -1,44 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} -
-
- {if $debugMode} -
- {$locale->t('menu.debug_active')|escape:'htmlall':'UTF-8'} -
- {/if} -
-

{$locale->t('help.screen.title')|escape:'htmlall':'UTF-8'}

-

- {$locale->t('help.screen.contain_text_support')|escape:'htmlall':'UTF-8'} - - {$locale->t('help.screen.title_lengow_support')|escape:'htmlall':'UTF-8'} - -

-

{$locale->t('help.screen.contain_text_support_hour')|escape:'htmlall':'UTF-8'}

-

- {$locale->t('help.screen.find_answer')|escape:'htmlall':'UTF-8'} - - {$locale->t('help.screen.link_prestashop_guide')|escape:'htmlall':'UTF-8'} - -

-
-
-
diff --git a/views/templates/admin/lengow_help/layout.tpl b/views/templates/admin/lengow_help/layout.tpl deleted file mode 100755 index 3b92863a..00000000 --- a/views/templates/admin/lengow_help/layout.tpl +++ /dev/null @@ -1,23 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -{include file='../header.tpl'} -{html_entity_decode($content|escape:'htmlall':'UTF-8')} -{include file='../footer.tpl'} diff --git a/views/templates/admin/lengow_help/view.html.twig b/views/templates/admin/lengow_help/view.html.twig new file mode 100644 index 00000000..e7efedef --- /dev/null +++ b/views/templates/admin/lengow_help/view.html.twig @@ -0,0 +1,41 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +{% extends base_layout %} + +{% block lengow_header %} + {% include '@Modules/lengow/views/templates/admin/twig/header.html.twig' %} +{% endblock %} + +{% block lengow_content %} +
+
+ {% if debugMode %} +
+ {{ locale.t('menu.debug_active') }} +
+ {% endif %} +
+

{{ locale.t('help.screen.title') }}

+

+ {{ locale.t('help.screen.contain_text_support') }} + + {{ locale.t('help.screen.title_lengow_support') }} + +

+

{{ locale.t('help.screen.contain_text_support_hour') }}

+

+ {{ locale.t('help.screen.find_answer') }} + + {{ locale.t('help.screen.link_prestashop_guide') }} + +

+
+
+
+{% endblock %} + +{% block lengow_footer %} + {% include '@Modules/lengow/views/templates/admin/twig/footer.html.twig' %} +{% endblock %} diff --git a/views/templates/admin/lengow_home/helpers/view/connection_catalog.html.twig b/views/templates/admin/lengow_home/helpers/view/connection_catalog.html.twig new file mode 100644 index 00000000..254ca1f4 --- /dev/null +++ b/views/templates/admin/lengow_home/helpers/view/connection_catalog.html.twig @@ -0,0 +1,45 @@ +{# + * Copyright 2021 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +
+

{{ locale.t('connection.catalog.link_title') }}

+

{{ locale.t('connection.catalog.link_description') }}

+

+ {{ catalogList|length }} + {{ locale.t('connection.catalog.link_catalog_avalaible') }} +

+
+
+ {% for shop in shopCollection %} +
+ + +
+ {% endfor %} +
+
+ +
diff --git a/views/templates/admin/lengow_home/helpers/view/connection_catalog.tpl b/views/templates/admin/lengow_home/helpers/view/connection_catalog.tpl deleted file mode 100644 index e41697b5..00000000 --- a/views/templates/admin/lengow_home/helpers/view/connection_catalog.tpl +++ /dev/null @@ -1,61 +0,0 @@ -{* - * Copyright 2021 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2021 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -
-

{$locale->t('connection.catalog.link_title')|escape:'htmlall':'UTF-8'}

-

{$locale->t('connection.catalog.link_description')|escape:'htmlall':'UTF-8'}

-

- {$catalogList|@count|escape:'htmlall':'UTF-8'} - {$locale->t('connection.catalog.link_catalog_avalaible')|escape:'htmlall':'UTF-8'} -

-
-
- {foreach from=$shopCollection item=shop} -
- - -
- {/foreach} -
-
- -
diff --git a/views/templates/admin/lengow_home/helpers/view/connection_catalog_failed.html.twig b/views/templates/admin/lengow_home/helpers/view/connection_catalog_failed.html.twig new file mode 100644 index 00000000..991cf706 --- /dev/null +++ b/views/templates/admin/lengow_home/helpers/view/connection_catalog_failed.html.twig @@ -0,0 +1,41 @@ +{# + * Copyright 2021 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +
+

{{ locale.t('connection.catalog.failed_title') }}

+
+
+ prestashop + lengow + unplugged +
+
+

{{ locale.t('connection.catalog.failed_description_first') }}

+

{{ locale.t('connection.catalog.failed_description_second') }}

+

+ {{ locale.t('connection.cms.failed_help') }} + + {{ locale.t('connection.cms.failed_help_center') }} + + {{ locale.t('connection.cms.failed_help_or') }} + + {{ locale.t('connection.cms.failed_help_customer_success_team') }} + +

+
+
+ + + {{ locale.t('connection.cms.success_button') }} + +
diff --git a/views/templates/admin/lengow_home/helpers/view/connection_catalog_failed.tpl b/views/templates/admin/lengow_home/helpers/view/connection_catalog_failed.tpl deleted file mode 100644 index 9f88edc2..00000000 --- a/views/templates/admin/lengow_home/helpers/view/connection_catalog_failed.tpl +++ /dev/null @@ -1,57 +0,0 @@ -{* - * Copyright 2021 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2021 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -
-

{$locale->t('connection.catalog.failed_title')|escape:'htmlall':'UTF-8'}

-
-
- prestashop - lengow - unplugged -
-
-

{$locale->t('connection.catalog.failed_description_first')|escape:'htmlall':'UTF-8'}

-

{$locale->t('connection.catalog.failed_description_second')|escape:'htmlall':'UTF-8'}

-

- {$locale->t('connection.cms.failed_help')|escape:'htmlall':'UTF-8'} - - {$locale->t('connection.cms.failed_help_center')|escape:'htmlall':'UTF-8'} - - {$locale->t('connection.cms.failed_help_or')|escape:'htmlall':'UTF-8'} - - {$locale->t('connection.cms.failed_help_customer_success_team')|escape:'htmlall':'UTF-8'} - -

-
-
- - - {$locale->t('connection.cms.success_button')|escape:'htmlall':'UTF-8'} - -
\ No newline at end of file diff --git a/views/templates/admin/lengow_home/helpers/view/connection_cms.html.twig b/views/templates/admin/lengow_home/helpers/view/connection_cms.html.twig new file mode 100644 index 00000000..5603eae4 --- /dev/null +++ b/views/templates/admin/lengow_home/helpers/view/connection_cms.html.twig @@ -0,0 +1,40 @@ +{# + * Copyright 2021 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +
+
+

{{ locale.t('connection.cms.credentials_title') }}

+
+
+ + +
+
+

{{ locale.t('connection.cms.credentials_description') }}

+

+ {{ locale.t('connection.cms.credentials_help') }} + + {{ locale.t('connection.cms.credentials_help_center') }} + +

+
+
+ +
+
diff --git a/views/templates/admin/lengow_home/helpers/view/connection_cms.tpl b/views/templates/admin/lengow_home/helpers/view/connection_cms.tpl deleted file mode 100644 index 084c4a6f..00000000 --- a/views/templates/admin/lengow_home/helpers/view/connection_cms.tpl +++ /dev/null @@ -1,55 +0,0 @@ -{* - * Copyright 2021 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2021 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} -
-
-

{$locale->t('connection.cms.credentials_title')|escape:'htmlall':'UTF-8'}

-
-
- - -
-
-

{$locale->t('connection.cms.credentials_description')|escape:'htmlall':'UTF-8'}

-

- {$locale->t('connection.cms.credentials_help')|escape:'htmlall':'UTF-8'} - - {$locale->t('connection.cms.credentials_help_center')|escape:'htmlall':'UTF-8'} - -

-
-
- -
-
diff --git a/views/templates/admin/lengow_home/helpers/view/connection_cms_result.html.twig b/views/templates/admin/lengow_home/helpers/view/connection_cms_result.html.twig new file mode 100644 index 00000000..6c97a1ea --- /dev/null +++ b/views/templates/admin/lengow_home/helpers/view/connection_cms_result.html.twig @@ -0,0 +1,91 @@ +{# + * Copyright 2021 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +
+ {% if cmsConnected %} +
+

{{ locale.t('connection.cms.success_title') }}

+
+
+ prestashop + lengow + connection +
+ {% if hasCatalogToLink %} +
+

{{ locale.t('connection.cms.success_description_first_catalog') }}

+

{{ locale.t('connection.cms.success_description_second_catalog') }}

+
+
+ +
+ {% else %} +
+

{{ locale.t('connection.cms.success_description_first') }}

+

+ {{ locale.t('connection.cms.success_description_second') }} + + {{ locale.t('connection.cms.success_description_second_go_to_lengow') }} + +

+
+ + {% endif %} + {% else %} +
+

{{ locale.t('connection.cms.failed_title') }}

+
+
+ prestashop + lengow + unplugged +
+
+ {% if credentialsValid %} +

{{ locale.t('connection.cms.failed_description') }}

+ {% else %} +

{{ locale.t('connection.cms.failed_description_first_credentials') }}

+ {% if lengowUrl == 'lengow.net' %} +

{{ locale.t('connection.cms.failed_description_second_credentials_preprod') }}

+ {% else %} +

{{ locale.t('connection.cms.failed_description_second_credentials_prod') }}

+ {% endif %} + {% endif %} +

+ {{ locale.t('connection.cms.failed_help') }} + + {{ locale.t('connection.cms.failed_help_center') }} + + {{ locale.t('connection.cms.failed_help_or') }} + + {{ locale.t('connection.cms.failed_help_customer_success_team') }} + +

+
+
+ +
+ {% endif %} +
diff --git a/views/templates/admin/lengow_home/helpers/view/connection_cms_result.tpl b/views/templates/admin/lengow_home/helpers/view/connection_cms_result.tpl deleted file mode 100644 index 2ef98c88..00000000 --- a/views/templates/admin/lengow_home/helpers/view/connection_cms_result.tpl +++ /dev/null @@ -1,107 +0,0 @@ -{* - * Copyright 2021 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2021 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -
- {if $cmsConnected} -
-

{$locale->t('connection.cms.success_title')|escape:'htmlall':'UTF-8'}

-
-
- prestashop - lengow - connection -
- {if $hasCatalogToLink} -
-

{$locale->t('connection.cms.success_description_first_catalog')|escape:'htmlall':'UTF-8'}

-

{$locale->t('connection.cms.success_description_second_catalog')|escape:'htmlall':'UTF-8'}

-
-
- -
- {else} -
-

{$locale->t('connection.cms.success_description_first')|escape:'htmlall':'UTF-8'}

-

- {$locale->t('connection.cms.success_description_second')|escape:'htmlall':'UTF-8'} - - {$locale->t('connection.cms.success_description_second_go_to_lengow')|escape:'htmlall':'UTF-8'} - -

-
- - {/if} - {else} -
-

{$locale->t('connection.cms.failed_title')|escape:'htmlall':'UTF-8'}

-
-
- prestashop - lengow - unplugged -
-
- {if $credentialsValid} -

{$locale->t('connection.cms.failed_description')|escape:'htmlall':'UTF-8'}

- {else} -

{$locale->t('connection.cms.failed_description_first_credentials')|escape:'htmlall':'UTF-8'}

- {if $lengowUrl === 'lengow.net'} -

{$locale->t('connection.cms.failed_description_second_credentials_preprod')|escape:'htmlall':'UTF-8'}

- {else} -

{$locale->t('connection.cms.failed_description_second_credentials_prod')|escape:'htmlall':'UTF-8'}

- {/if} - {/if} -

- {$locale->t('connection.cms.failed_help')|escape:'htmlall':'UTF-8'} - - {$locale->t('connection.cms.failed_help_center')|escape:'htmlall':'UTF-8'} - - {$locale->t('connection.cms.failed_help_or')|escape:'htmlall':'UTF-8'} - - {$locale->t('connection.cms.failed_help_customer_success_team')|escape:'htmlall':'UTF-8'} - -

-
-
- -
- {/if} -
diff --git a/views/templates/admin/lengow_home/helpers/view/connection_home.html.twig b/views/templates/admin/lengow_home/helpers/view/connection_home.html.twig new file mode 100644 index 00000000..c4b59c78 --- /dev/null +++ b/views/templates/admin/lengow_home/helpers/view/connection_home.html.twig @@ -0,0 +1,35 @@ +{# + * Copyright 2021 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +
+
+

{{ locale.t('connection.home.description_first') }}

+

{{ locale.t('connection.home.description_second') }}

+

{{ locale.t('connection.home.description_third') }}

+
+
+ prestashop + lengow + plug +
+

{{ locale.t('connection.home.description_fourth') }}

+
+ +
+

+ {{ locale.t('connection.home.no_account') }} + + {{ locale.t('connection.home.no_account_sign_up') }} + +

+
+
diff --git a/views/templates/admin/lengow_home/helpers/view/connection_home.tpl b/views/templates/admin/lengow_home/helpers/view/connection_home.tpl deleted file mode 100644 index c4b8b00b..00000000 --- a/views/templates/admin/lengow_home/helpers/view/connection_home.tpl +++ /dev/null @@ -1,51 +0,0 @@ -{* - * Copyright 2021 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2021 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -
-
-

{$locale->t('connection.home.description_first')|escape:'htmlall':'UTF-8'}

-

{$locale->t('connection.home.description_second')|escape:'htmlall':'UTF-8'}

-

{$locale->t('connection.home.description_third')|escape:'htmlall':'UTF-8'}

-
-
- prestashop - lengow - plug -
-

{$locale->t('connection.home.description_fourth')|escape:'htmlall':'UTF-8'}

-
- -
-

- {$locale->t('connection.home.no_account')|escape:'htmlall':'UTF-8'} - - {$locale->t('connection.home.no_account_sign_up')|escape:'htmlall':'UTF-8'} - -

-
-
diff --git a/views/templates/admin/lengow_home/helpers/view/view.tpl b/views/templates/admin/lengow_home/helpers/view/view.tpl deleted file mode 100755 index 961808a0..00000000 --- a/views/templates/admin/lengow_home/helpers/view/view.tpl +++ /dev/null @@ -1,35 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - - -
-
-
- -
-
- {include file='./connection_home.tpl'} -
-
-
- - \ No newline at end of file diff --git a/views/templates/admin/lengow_home/layout.tpl b/views/templates/admin/lengow_home/layout.tpl deleted file mode 100755 index 7f23ea36..00000000 --- a/views/templates/admin/lengow_home/layout.tpl +++ /dev/null @@ -1,24 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -{include file='../header.tpl'} -{html_entity_decode($content|escape:'htmlall':'UTF-8')} -{include file='../footer.tpl'} - diff --git a/views/templates/admin/lengow_home/view.html.twig b/views/templates/admin/lengow_home/view.html.twig new file mode 100644 index 00000000..2d5df5ec --- /dev/null +++ b/views/templates/admin/lengow_home/view.html.twig @@ -0,0 +1,31 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +{% extends base_layout %} + +{% block lengow_header %} + {% include '@Modules/lengow/views/templates/admin/twig/header.html.twig' %} +{% endblock %} + +{% block lengow_content %} + +
+
+
+ +
+
+ {% include '@Modules/lengow/views/templates/admin/lengow_home/helpers/view/connection_home.html.twig' %} +
+
+
+ + +{% endblock %} + +{% block lengow_footer %} + {% include '@Modules/lengow/views/templates/admin/twig/footer.html.twig' %} +{% endblock %} diff --git a/views/templates/admin/lengow_legals/helpers/view/view.tpl b/views/templates/admin/lengow_legals/helpers/view/view.tpl deleted file mode 100755 index 940de147..00000000 --- a/views/templates/admin/lengow_legals/helpers/view/view.tpl +++ /dev/null @@ -1,55 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} -
-
- {if $debugMode} -
- {$locale->t('menu.debug_active')|escape:'htmlall':'UTF-8'} -
- {/if} -
-

SAS Lengow

- {$locale->t('legals.screen.simplified_company')|escape:'htmlall':'UTF-8'} -
- {$locale->t('legals.screen.social_capital')|escape:'htmlall':'UTF-8'} - 368 778 € -
- {$locale->t('legals.screen.cnil_declaration')|escape:'htmlall':'UTF-8'} - 1748784 v 0 -
- {$locale->t('legals.screen.company_registration_number')|escape:'htmlall':'UTF-8'} - 513 381 434 -
- {$locale->t('legals.screen.vat_identification_number')|escape:'htmlall':'UTF-8'} - FR42513381434 -

{$locale->t('legals.screen.address')|escape:'htmlall':'UTF-8'}

- 6 rue René Viviani
- 44200 Nantes -

{$locale->t('legals.screen.contact')|escape:'htmlall':'UTF-8'}

- contact@lengow.com
- +33 (0)2 85 52 64 14 -

{$locale->t('legals.screen.hosting')|escape:'htmlall':'UTF-8'}

- OXALIDE
- RCS Paris : 803 816 529
- 25 Boulevard de Strasbourg – 75010 Paris
- +33 (0)1 75 77 16 66 -
-
-
diff --git a/views/templates/admin/lengow_legals/layout.tpl b/views/templates/admin/lengow_legals/layout.tpl deleted file mode 100755 index 3b92863a..00000000 --- a/views/templates/admin/lengow_legals/layout.tpl +++ /dev/null @@ -1,23 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -{include file='../header.tpl'} -{html_entity_decode($content|escape:'htmlall':'UTF-8')} -{include file='../footer.tpl'} diff --git a/views/templates/admin/lengow_legals/view.html.twig b/views/templates/admin/lengow_legals/view.html.twig new file mode 100644 index 00000000..eb9e6ebc --- /dev/null +++ b/views/templates/admin/lengow_legals/view.html.twig @@ -0,0 +1,52 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +{% extends base_layout %} + +{% block lengow_header %} + {% include '@Modules/lengow/views/templates/admin/twig/header.html.twig' %} +{% endblock %} + +{% block lengow_content %} +
+
+ {% if debugMode %} +
+ {{ locale.t('menu.debug_active') }} +
+ {% endif %} +
+

SAS Lengow

+ {{ locale.t('legals.screen.simplified_company') }} +
+ {{ locale.t('legals.screen.social_capital') }} + 368 778 € +
+ {{ locale.t('legals.screen.cnil_declaration') }} + 1748784 v 0 +
+ {{ locale.t('legals.screen.company_registration_number') }} + 513 381 434 +
+ {{ locale.t('legals.screen.vat_identification_number') }} + FR42513381434 +

{{ locale.t('legals.screen.address') }}

+ 6 rue René Viviani
+ 44200 Nantes +

{{ locale.t('legals.screen.contact') }}

+ contact@lengow.com
+ +33 (0)2 85 52 64 14 +

{{ locale.t('legals.screen.hosting') }}

+ OXALIDE
+ RCS Paris : 803 816 529
+ 25 Boulevard de Strasbourg – 75010 Paris
+ +33 (0)1 75 77 16 66 +
+
+
+{% endblock %} + +{% block lengow_footer %} + {% include '@Modules/lengow/views/templates/admin/twig/footer.html.twig' %} +{% endblock %} diff --git a/views/templates/admin/lengow_main_setting/helpers/view/view.tpl b/views/templates/admin/lengow_main_setting/helpers/view/view.tpl deleted file mode 100755 index 72d90650..00000000 --- a/views/templates/admin/lengow_main_setting/helpers/view/view.tpl +++ /dev/null @@ -1,152 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} -
-
- {if $debugMode} -
- {$locale->t('menu.debug_active')|escape:'htmlall':'UTF-8'} -
- {/if} -
- -
-

{$locale->t('global_setting.screen.notification_alert_title')|escape:'htmlall':'UTF-8'}

- {html_entity_decode($mail_report|escape:'htmlall':'UTF-8')} -
-
-

{$locale->t('global_setting.screen.default_export_carrier_title')|escape:'htmlall':'UTF-8'}

-

{$locale->t('global_setting.screen.default_export_carrier_description')|escape:'htmlall':'UTF-8'}

- {html_entity_decode($defaultExportCarrier|escape:'htmlall':'UTF-8')} -
-
-

{$locale->t('global_setting.screen.security_title')|escape:'htmlall':'UTF-8'}

-

{$locale->t('global_setting.screen.security_description')|escape:'htmlall':'UTF-8'}

- {html_entity_decode($ipSecurity|escape:'htmlall':'UTF-8')} -
-
-

{$locale->t('global_setting.screen.shop_title')|escape:'htmlall':'UTF-8'}

-

{$locale->t('global_setting.screen.shop_description')|escape:'htmlall':'UTF-8'}

- {html_entity_decode($shopCatalog|escape:'htmlall':'UTF-8')} -
-
-

{$locale->t('global_setting.screen.debug_mode_title')|escape:'htmlall':'UTF-8'}

-

{$locale->t('global_setting.screen.debug_mode_description')|escape:'htmlall':'UTF-8'}

- {html_entity_decode($debug_report|escape:'htmlall':'UTF-8')} - -
-
-

{$locale->t('global_setting.screen.log_file_title')|escape:'htmlall':'UTF-8'}

-

{html_entity_decode($locale->t('global_setting.screen.log_file_description')|escape:'htmlall':'UTF-8')}

- - -
-
-
-
- -
- -
- - - -
- -
-
-
-
- -

{$locale->t('global_setting.screen.title_modal_uninstall')|escape:'htmlall':'UTF-8'}

-

- {$locale->t('global_setting.screen.all_data_will_be_lost')|escape:'htmlall':'UTF-8'}

- {$locale->t('global_setting.screen.you_will_find_a_backup')|escape:'htmlall':'UTF-8'} - - {$locale->t('global_setting.screen.prestashop_backup')|escape:'htmlall':'UTF-8'} - -

-
-
-
- - - - -
-
-
-
-
-
-
-
-
-
-
-
-
- diff --git a/views/templates/admin/lengow_main_setting/layout.tpl b/views/templates/admin/lengow_main_setting/layout.tpl deleted file mode 100755 index 3b92863a..00000000 --- a/views/templates/admin/lengow_main_setting/layout.tpl +++ /dev/null @@ -1,23 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -{include file='../header.tpl'} -{html_entity_decode($content|escape:'htmlall':'UTF-8')} -{include file='../footer.tpl'} diff --git a/views/templates/admin/lengow_main_setting/view.html.twig b/views/templates/admin/lengow_main_setting/view.html.twig new file mode 100644 index 00000000..af78db47 --- /dev/null +++ b/views/templates/admin/lengow_main_setting/view.html.twig @@ -0,0 +1,148 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +{% extends base_layout %} + +{% block lengow_header %} + {% include '@Modules/lengow/views/templates/admin/twig/header.html.twig' %} +{% endblock %} + +{% block lengow_content %} +
+
+ {% if debugMode %} +
+ {{ locale.t('menu.debug_active') }} +
+ {% endif %} +
+ +
+

{{ locale.t('global_setting.screen.notification_alert_title') }}

+ {{ mail_report|raw }} +
+
+

{{ locale.t('global_setting.screen.default_export_carrier_title') }}

+

{{ locale.t('global_setting.screen.default_export_carrier_description') }}

+ {{ defaultExportCarrier|raw }} +
+
+

{{ locale.t('global_setting.screen.security_title') }}

+

{{ locale.t('global_setting.screen.security_description') }}

+ {{ ipSecurity|raw }} +
+
+

{{ locale.t('global_setting.screen.shop_title') }}

+

{{ locale.t('global_setting.screen.shop_description') }}

+ {{ shopCatalog|raw }} +
+
+

{{ locale.t('global_setting.screen.debug_mode_title') }}

+

{{ locale.t('global_setting.screen.debug_mode_description') }}

+ {{ debug_report|raw }} + +
+
+

{{ locale.t('global_setting.screen.log_file_title') }}

+

{{ locale.t('global_setting.screen.log_file_description')|raw }}

+ + +
+
+
+
+ +
+
+ + + +
+ +
+
+
+
+ +

{{ locale.t('global_setting.screen.title_modal_uninstall') }}

+

+ {{ locale.t('global_setting.screen.all_data_will_be_lost') }}

+ {{ locale.t('global_setting.screen.you_will_find_a_backup') }} + + {{ locale.t('global_setting.screen.prestashop_backup') }} + +

+
+
+
+ + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+ +{% endblock %} + +{% block lengow_footer %} + {% include '@Modules/lengow/views/templates/admin/twig/footer.html.twig' %} +{% endblock %} diff --git a/views/templates/admin/lengow_order/helpers/view/last_importation.html.twig b/views/templates/admin/lengow_order/helpers/view/last_importation.html.twig new file mode 100644 index 00000000..c1fda33f --- /dev/null +++ b/views/templates/admin/lengow_order/helpers/view/last_importation.html.twig @@ -0,0 +1,18 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +{% if orderCollection is defined and orderCollection['last_import_type'] != 'none' %} +

+ {{ locale.t('order.screen.last_order_importation') }} + : {{ orderCollection['last_import_date'] }} +{% else %} + {{ locale.t('order.screen.no_order_importation') }} +{% endif %} +

+{% if reportMailEnabled is defined and reportMailEnabled %} +

+ {{ locale.t('order.screen.all_order_will_be_sent_to') }} {{ report_mail_address|join(', ') }} + ({{ locale.t('order.screen.change_this') }}) +

+{% endif %} diff --git a/views/templates/admin/lengow_order/helpers/view/last_importation.tpl b/views/templates/admin/lengow_order/helpers/view/last_importation.tpl deleted file mode 100755 index 400ebe2d..00000000 --- a/views/templates/admin/lengow_order/helpers/view/last_importation.tpl +++ /dev/null @@ -1,34 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -{if $orderCollection['last_import_type'] != 'none'} -

- {$locale->t('order.screen.last_order_importation')|escape:'htmlall':'UTF-8'} - : {$orderCollection['last_import_date']|escape:'htmlall':'UTF-8'} -{else} - {$locale->t('order.screen.no_order_importation')|escape:'htmlall':'UTF-8'} -{/if} -

-{if $reportMailEnabled } -

- {$locale->t('order.screen.all_order_will_be_sent_to')|escape:'htmlall':'UTF-8'} {', '|implode:$report_mail_address|escape:'htmlall':'UTF-8'} - ({$locale->t('order.screen.change_this')|escape:'htmlall':'UTF-8'}) -

-{/if} diff --git a/views/templates/admin/lengow_order/helpers/view/no_order.html.twig b/views/templates/admin/lengow_order/helpers/view/no_order.html.twig new file mode 100644 index 00000000..f0ab6c84 --- /dev/null +++ b/views/templates/admin/lengow_order/helpers/view/no_order.html.twig @@ -0,0 +1,10 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +
+
+

{{ locale.t('order.screen.no_order_title') }}

+

{{ locale.t('order.screen.no_order_description') }}

+
+
diff --git a/views/templates/admin/lengow_order/helpers/view/no_order.tpl b/views/templates/admin/lengow_order/helpers/view/no_order.tpl deleted file mode 100755 index 8814deca..00000000 --- a/views/templates/admin/lengow_order/helpers/view/no_order.tpl +++ /dev/null @@ -1,26 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -
-
-

{$locale->t('order.screen.no_order_title')|escape:'htmlall':'UTF-8'}

-

{$locale->t('order.screen.no_order_description')|escape:'htmlall':'UTF-8'}

-
-
\ No newline at end of file diff --git a/views/templates/admin/lengow_order/helpers/view/view.tpl b/views/templates/admin/lengow_order/helpers/view/view.tpl deleted file mode 100755 index 99d7a129..00000000 --- a/views/templates/admin/lengow_order/helpers/view/view.tpl +++ /dev/null @@ -1,66 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} -
-
- {if $debugMode} -
- {$locale->t('menu.debug_active')|escape:'htmlall':'UTF-8'} -
- {/if} -
-
- {include file='./warning_message.tpl'} -
-
-
- {include file='./last_importation.tpl'} -
- -
- - - - - -
-
- {if $nb_order_imported eq '0'} - {include file='./no_order.tpl'} - {else} - {html_entity_decode($lengow_table|escape:'htmlall':'UTF-8')} - {/if} -
- -
-
-
- diff --git a/views/templates/admin/lengow_order/helpers/view/warning_message.html.twig b/views/templates/admin/lengow_order/helpers/view/warning_message.html.twig new file mode 100644 index 00000000..237ab3a8 --- /dev/null +++ b/views/templates/admin/lengow_order/helpers/view/warning_message.html.twig @@ -0,0 +1,9 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +{% if warning_message is defined and warning_message %} +

+ {{ warning_message|raw }} +

+{% endif %} diff --git a/views/templates/admin/lengow_order/helpers/view/warning_message.tpl b/views/templates/admin/lengow_order/helpers/view/warning_message.tpl deleted file mode 100755 index 9a232913..00000000 --- a/views/templates/admin/lengow_order/helpers/view/warning_message.tpl +++ /dev/null @@ -1,25 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -{if $warning_message} -

- {html_entity_decode($warning_message|escape:'htmlall':'UTF-8')} -

-{/if} diff --git a/views/templates/admin/lengow_order/layout.tpl b/views/templates/admin/lengow_order/layout.tpl deleted file mode 100755 index 0049e1e5..00000000 --- a/views/templates/admin/lengow_order/layout.tpl +++ /dev/null @@ -1,24 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -{include file='../header.tpl'} -{include file='../header_order.tpl'} -{html_entity_decode($content|escape:'htmlall':'UTF-8')} -{include file='../footer.tpl'} diff --git a/views/templates/admin/lengow_order/view.html.twig b/views/templates/admin/lengow_order/view.html.twig new file mode 100644 index 00000000..c159bc11 --- /dev/null +++ b/views/templates/admin/lengow_order/view.html.twig @@ -0,0 +1,64 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +{% extends base_layout %} + +{% block lengow_header %} + {% include '@Modules/lengow/views/templates/admin/twig/header.html.twig' %} + {% include '@Modules/lengow/views/templates/admin/twig/header_order.html.twig' %} +{% endblock %} + +{% block lengow_content %} +
+
+ {% if debugMode %} +
+ {{ locale.t('menu.debug_active') }} +
+ {% endif %} +
+
+ {% include '@Modules/lengow/views/templates/admin/lengow_order/helpers/view/warning_message.html.twig' %} +
+
+
+ {% include '@Modules/lengow/views/templates/admin/lengow_order/helpers/view/last_importation.html.twig' %} +
+ +
+ + + + + +
+
+ {% if nb_order_imported is defined and nb_order_imported == 0 %} + {% include '@Modules/lengow/views/templates/admin/lengow_order/helpers/view/no_order.html.twig' %} + {% else %} + {{ lengow_table|raw }} + {% endif %} +
+ +
+
+
+ +{% endblock %} + +{% block lengow_footer %} + {% include '@Modules/lengow/views/templates/admin/twig/footer.html.twig' %} +{% endblock %} diff --git a/views/templates/admin/lengow_order_setting/helpers/view/country_selector.html.twig b/views/templates/admin/lengow_order_setting/helpers/view/country_selector.html.twig new file mode 100644 index 00000000..f48eb599 --- /dev/null +++ b/views/templates/admin/lengow_order_setting/helpers/view/country_selector.html.twig @@ -0,0 +1,31 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +

+ {{ locale.t('order_setting.screen.carrier_management_title') }} +

+

{{ locale.t('order_setting.screen.carrier_management_description') }}

+ diff --git a/views/templates/admin/lengow_order_setting/helpers/view/country_selector.tpl b/views/templates/admin/lengow_order_setting/helpers/view/country_selector.tpl deleted file mode 100755 index 7ae8ac49..00000000 --- a/views/templates/admin/lengow_order_setting/helpers/view/country_selector.tpl +++ /dev/null @@ -1,46 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} -

- {$locale->t('order_setting.screen.carrier_management_title')|escape:'htmlall':'UTF-8'} -

-

{$locale->t('order_setting.screen.carrier_management_description')|escape:'htmlall':'UTF-8'}

- diff --git a/views/templates/admin/lengow_order_setting/helpers/view/default_carrier.html.twig b/views/templates/admin/lengow_order_setting/helpers/view/default_carrier.html.twig new file mode 100644 index 00000000..5b5f5ed5 --- /dev/null +++ b/views/templates/admin/lengow_order_setting/helpers/view/default_carrier.html.twig @@ -0,0 +1,50 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +
+
+

+ {{ locale.t('order_setting.screen.default_carrier_prestashop') }} + * +

+ + +
+ {% if marketplace['carriers'] is defined and marketplace['carriers']|length > 0 %} +
+

+ {{ locale.t('order_setting.screen.default_carrier_marketplace', {'marketplace_name': marketplace['label']}) }} + {% if marketplace['carrier_required'] %} + * + {% endif %} +

+ + {% if marketplace['carrier_required'] %} + + {% endif %} +
+ {% endif %} +
diff --git a/views/templates/admin/lengow_order_setting/helpers/view/default_carrier.tpl b/views/templates/admin/lengow_order_setting/helpers/view/default_carrier.tpl deleted file mode 100755 index 6a3b4457..00000000 --- a/views/templates/admin/lengow_order_setting/helpers/view/default_carrier.tpl +++ /dev/null @@ -1,66 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -
-
-

- {$locale->t('order_setting.screen.default_carrier_prestashop')|escape:'htmlall':'UTF-8'} - * -

- - -
- {if isset($marketplace['carriers']) && $marketplace['carriers']|@count > 0} -
-

- {$locale->t('order_setting.screen.default_carrier_marketplace', ['marketplace_name' => $marketplace['label']])|escape:'htmlall':'UTF-8'} - {if $marketplace['carrier_required']} - * - {/if} -

- - {if $marketplace['carrier_required']} - - {/if} -
- {/if} -
diff --git a/views/templates/admin/lengow_order_setting/helpers/view/marketplace_carrier.html.twig b/views/templates/admin/lengow_order_setting/helpers/view/marketplace_carrier.html.twig new file mode 100644 index 00000000..0770d7f7 --- /dev/null +++ b/views/templates/admin/lengow_order_setting/helpers/view/marketplace_carrier.html.twig @@ -0,0 +1,37 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +
  • +
    + + {{ locale.t('order_setting.screen.matching_carrier_marketplace') }} + +
    +
  • +{% for idCarrier, carrier in carriers %} +
  • +
    +
    + {{ carrier['name'] }} +
    +
    +
    +
    +
    + +
    +
    +
  • +{% endfor %} diff --git a/views/templates/admin/lengow_order_setting/helpers/view/marketplace_carrier.tpl b/views/templates/admin/lengow_order_setting/helpers/view/marketplace_carrier.tpl deleted file mode 100755 index 5b7f42d5..00000000 --- a/views/templates/admin/lengow_order_setting/helpers/view/marketplace_carrier.tpl +++ /dev/null @@ -1,53 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -
  • -
    - - {$locale->t('order_setting.screen.matching_carrier_marketplace')|escape:'htmlall':'UTF-8'} - -
    -
  • -{foreach from=$carriers key=idCarrier item=carrier} -
  • -
    -
    - {$carrier['name']|escape:'htmlall':'UTF-8'} -
    -
    -
    -
    -
    - -
    -
    -
  • -{/foreach} diff --git a/views/templates/admin/lengow_order_setting/helpers/view/marketplace_matching.html.twig b/views/templates/admin/lengow_order_setting/helpers/view/marketplace_matching.html.twig new file mode 100644 index 00000000..d03b88eb --- /dev/null +++ b/views/templates/admin/lengow_order_setting/helpers/view/marketplace_matching.html.twig @@ -0,0 +1,76 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} + + + {{ locale.t('order_setting.screen.see_delivery_countries') }} + +

    + {{ country['name'] }} + {{ locale.t('order_setting.screen.marketplace_matching_title', {'country_name': country['name']}) }} +

    +

    + {{ locale.t('order_setting.screen.marketplace_matching_description', {'country_name': country['name']}) }} + {% if carriers is defined and carriers|length > 0 %} + {{ locale.t('order_setting.screen.country_wt_carrier') }} + + {{ locale.t('order_setting.screen.please_setup_then') }} + + {% endif %} +

    + +{% if carriers is defined and carriers|length > 0 %} +
    +
      + {% if marketplaces is defined %} + {% for marketplace in marketplaces %} +
    • +
      + {{ marketplace['label'] }} + {% if not marketplace['id_carrier'] %} + + {% endif %} + +
      + +
      +
    • + {% endfor %} + {% endif %} +
    +
    + + + {{ locale.t('order_setting.screen.button_cancel') }} + +{% else %} +
    + {{ locale.t('order_setting.screen.no_carrier_enabled', {'country_name': country['name']}) }} + + {{ locale.t('order_setting.screen.please_setup_then') }} + +
    +{% endif %} diff --git a/views/templates/admin/lengow_order_setting/helpers/view/marketplace_matching.tpl b/views/templates/admin/lengow_order_setting/helpers/view/marketplace_matching.tpl deleted file mode 100755 index c642d600..00000000 --- a/views/templates/admin/lengow_order_setting/helpers/view/marketplace_matching.tpl +++ /dev/null @@ -1,91 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - - - {$locale->t('order_setting.screen.see_delivery_countries')|escape:'htmlall':'UTF-8'} - -

    - {$country['name']|escape:'htmlall':'UTF-8'} - {$locale->t('order_setting.screen.marketplace_matching_title', ['country_name' => $country['name']])|escape:'htmlall':'UTF-8'} -

    -

    - {$locale->t('order_setting.screen.marketplace_matching_description', ['country_name' => $country['name']])|escape:'htmlall':'UTF-8'} - {if isset($carriers) && $carriers|@count > 0} - {$locale->t('order_setting.screen.country_wt_carrier')|escape:'htmlall':'UTF-8'} - - {$locale->t('order_setting.screen.please_setup_then')|escape:'htmlall':'UTF-8'} - - {/if} -

    - -{if isset($carriers) && $carriers|@count > 0} -
    -
      - {if isset($marketplaces)} - {foreach from=$marketplaces item=marketplace} -
    • -
      - {$marketplace['label']|escape:'htmlall':'UTF-8'} - {if !$marketplace['id_carrier']} - - {/if} - -
      - -
      -
    • - {/foreach} - {/if} -
    -
    - - - {$locale->t('order_setting.screen.button_cancel')|escape:'htmlall':'UTF-8'} - -{else} -
    - {$locale->t('order_setting.screen.no_carrier_enabled', ['country_name' => $country['name']])|escape:'htmlall':'UTF-8'} - - {$locale->t('order_setting.screen.please_setup_then')|escape:'htmlall':'UTF-8'} - -
    -{/if} diff --git a/views/templates/admin/lengow_order_setting/helpers/view/marketplace_method.html.twig b/views/templates/admin/lengow_order_setting/helpers/view/marketplace_method.html.twig new file mode 100644 index 00000000..3f637ff5 --- /dev/null +++ b/views/templates/admin/lengow_order_setting/helpers/view/marketplace_method.html.twig @@ -0,0 +1,37 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +
  • +
    + + {{ locale.t('order_setting.screen.matching_method_marketplace') }} + +
    +
  • +{% for method in marketplace['methods'] %} +
  • +
    +
    + {{ method['method_marketplace_label'] }} +
    +
    +
    +
    +
    + +
    +
    +
  • +{% endfor %} diff --git a/views/templates/admin/lengow_order_setting/helpers/view/marketplace_method.tpl b/views/templates/admin/lengow_order_setting/helpers/view/marketplace_method.tpl deleted file mode 100755 index 2a1ebd23..00000000 --- a/views/templates/admin/lengow_order_setting/helpers/view/marketplace_method.tpl +++ /dev/null @@ -1,52 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} -
  • -
    - - {$locale->t('order_setting.screen.matching_method_marketplace')|escape:'htmlall':'UTF-8'} - -
    -
  • -{foreach from=$marketplace['methods'] item=method} -
  • -
    -
    - {$method['method_marketplace_label']|escape:'htmlall':'UTF-8'} -
    -
    -
    -
    -
    - -
    -
    -
  • -{/foreach} diff --git a/views/templates/admin/lengow_order_setting/helpers/view/view.tpl b/views/templates/admin/lengow_order_setting/helpers/view/view.tpl deleted file mode 100755 index 9e0f4f87..00000000 --- a/views/templates/admin/lengow_order_setting/helpers/view/view.tpl +++ /dev/null @@ -1,80 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} -
    -
    - {if $debugMode} -
    - {$locale->t('menu.debug_active')|escape:'htmlall':'UTF-8'} -
    - {/if} -
    - {if $countries neq false} -
    -
    - {include file='./country_selector.tpl'} -

    {html_entity_decode($semantic_search|escape:'htmlall':'UTF-8')}

    -
    -
    - -
    - {/if} -
    - -

    {$locale->t('order_setting.screen.order_status_title')|escape:'htmlall':'UTF-8'}

    -
    -

    {$locale->t('order_setting.screen.order_status_description')|escape:'htmlall':'UTF-8'}

    -

    {html_entity_decode($matching|escape:'htmlall':'UTF-8')}

    -
    - -
    -
    -

    {$locale->t('order_setting.screen.import_setting_title')|escape:'htmlall':'UTF-8'}

    -

    {$locale->t('order_setting.screen.import_setting_description')|escape:'htmlall':'UTF-8'}

    -

    {html_entity_decode($import_params|escape:'htmlall':'UTF-8')}

    -
    -
    -

    - {$locale->t('lengow_setting.lengow_currency_conversion_title')|escape:'htmlall':'UTF-8'} -

    -

    {$locale->t('lengow_setting.lengow_currency_conversion_legend')|escape:'htmlall':'UTF-8'}

    -

    {html_entity_decode($currency_conversion|escape:'htmlall':'UTF-8')}

    -
    - -
    -
    -
    - - - diff --git a/views/templates/admin/lengow_order_setting/layout.tpl b/views/templates/admin/lengow_order_setting/layout.tpl deleted file mode 100755 index 0049e1e5..00000000 --- a/views/templates/admin/lengow_order_setting/layout.tpl +++ /dev/null @@ -1,24 +0,0 @@ -{* - * Copyright 2017 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -{include file='../header.tpl'} -{include file='../header_order.tpl'} -{html_entity_decode($content|escape:'htmlall':'UTF-8')} -{include file='../footer.tpl'} diff --git a/views/templates/admin/lengow_order_setting/view.html.twig b/views/templates/admin/lengow_order_setting/view.html.twig new file mode 100644 index 00000000..0320d3cf --- /dev/null +++ b/views/templates/admin/lengow_order_setting/view.html.twig @@ -0,0 +1,75 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +{% extends base_layout %} + +{% block lengow_header %} + {% include '@Modules/lengow/views/templates/admin/twig/header.html.twig' %} + {% include '@Modules/lengow/views/templates/admin/twig/header_order.html.twig' %} +{% endblock %} + +{% block lengow_content %} +
    +
    + {% if debugMode %} +
    + {{ locale.t('menu.debug_active') }} +
    + {% endif %} +
    + {% if countries is defined and countries %} +
    +
    + {% include '@Modules/lengow/views/templates/admin/lengow_order_setting/helpers/view/country_selector.html.twig' %} +

    {{ semantic_search|raw }}

    +
    +
    + +
    + {% endif %} +
    + +

    {{ locale.t('order_setting.screen.order_status_title') }}

    +
    +

    {{ locale.t('order_setting.screen.order_status_description') }}

    +

    {{ matching|raw }}

    +
    +
    +
    +

    {{ locale.t('order_setting.screen.import_setting_title') }}

    +

    {{ locale.t('order_setting.screen.import_setting_description') }}

    +

    {{ import_params|raw }}

    +
    +
    +

    + {{ locale.t('lengow_setting.lengow_currency_conversion_title') }} +

    +

    {{ locale.t('lengow_setting.lengow_currency_conversion_legend') }}

    +

    {{ currency_conversion|raw }}

    +
    + +
    +
    +
    + +{% endblock %} + +{% block lengow_footer %} + {% include '@Modules/lengow/views/templates/admin/twig/footer.html.twig' %} +{% endblock %} diff --git a/views/templates/admin/lengow_toolbox/helpers/view/view.tpl b/views/templates/admin/lengow_toolbox/helpers/view/view.tpl deleted file mode 100644 index 9ea1c2e3..00000000 --- a/views/templates/admin/lengow_toolbox/helpers/view/view.tpl +++ /dev/null @@ -1,108 +0,0 @@ -{* - * Copyright 2022 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2022 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} -
    -
    - {if $debugMode} -
    - {$locale->t('menu.debug_active')|escape:'htmlall':'UTF-8'} -
    - {/if} -

    - - {$locale->t('toolbox.screen.title')|escape:'htmlall':'UTF-8'} -

    -
    -
    - -
    -
    -
    -

    - - {$locale->t('toolbox.screen.checklist_information')|escape:'htmlall':'UTF-8'} -

    - {html_entity_decode($checklist|escape:'htmlall':'UTF-8')} -
    -
    -

    - - {$locale->t('toolbox.screen.plugin_information')|escape:'htmlall':'UTF-8'} -

    - {html_entity_decode($globalInformation|escape:'htmlall':'UTF-8')} -
    -
    -

    - - {$locale->t('toolbox.screen.synchronization_information')|escape:'htmlall':'UTF-8'} -

    - {html_entity_decode($synchronizationInformation|escape:'htmlall':'UTF-8')} -
    -
    -
    -
    -
    - -
    -
    -
    -

    - - {$locale->t('toolbox.screen.export_information')|escape:'htmlall':'UTF-8'} -

    - {html_entity_decode($exportInformation|escape:'htmlall':'UTF-8')} -
    -
    -

    - - {$locale->t('toolbox.screen.content_folder_media')|escape:'htmlall':'UTF-8'} -

    - {html_entity_decode($fileInformation|escape:'htmlall':'UTF-8')} -
    -
    -
    -
    -
    - -
    -
    - {html_entity_decode($checksum|escape:'htmlall':'UTF-8')} -
    -
    -
    -
    - diff --git a/views/templates/admin/lengow_toolbox/layout.tpl b/views/templates/admin/lengow_toolbox/layout.tpl deleted file mode 100644 index b499bb43..00000000 --- a/views/templates/admin/lengow_toolbox/layout.tpl +++ /dev/null @@ -1,23 +0,0 @@ -{* - * Copyright 2022 Lengow SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. You may obtain - * a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * @author Team Connector - * @copyright 2022 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - *} - -{include file='../header.tpl'} -{html_entity_decode($content|escape:'htmlall':'UTF-8')} -{include file='../footer.tpl'} diff --git a/views/templates/admin/lengow_toolbox/view.html.twig b/views/templates/admin/lengow_toolbox/view.html.twig new file mode 100644 index 00000000..c019965d --- /dev/null +++ b/views/templates/admin/lengow_toolbox/view.html.twig @@ -0,0 +1,105 @@ +{# + * Copyright 2022 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} +{% extends base_layout %} + +{% block lengow_header %} + {% include '@Modules/lengow/views/templates/admin/twig/header.html.twig' %} +{% endblock %} + +{% block lengow_content %} +
    +
    + {% if debugMode %} +
    + {{ locale.t('menu.debug_active') }} +
    + {% endif %} +

    + + {{ locale.t('toolbox.screen.title') }} +

    +
    +
    + +
    +
    +
    +

    + + {{ locale.t('toolbox.screen.checklist_information') }} +

    + {{ checklist|raw }} +
    +
    +

    + + {{ locale.t('toolbox.screen.plugin_information') }} +

    + {{ globalInformation|raw }} +
    +
    +

    + + {{ locale.t('toolbox.screen.synchronization_information') }} +

    + {{ synchronizationInformation|raw }} +
    +
    +
    +
    +
    + +
    +
    +
    +

    + + {{ locale.t('toolbox.screen.export_information') }} +

    + {{ exportInformation|raw }} +
    +
    +

    + + {{ locale.t('toolbox.screen.content_folder_media') }} +

    + {{ fileInformation|raw }} +
    +
    +
    +
    +
    + +
    +
    + {{ checksum|raw }} +
    +
    +
    +
    + +{% endblock %} + +{% block lengow_footer %} + {% include '@Modules/lengow/views/templates/admin/twig/footer.html.twig' %} +{% endblock %} diff --git a/views/templates/admin/twig/footer.html.twig b/views/templates/admin/twig/footer.html.twig new file mode 100644 index 00000000..3a7875a6 --- /dev/null +++ b/views/templates/admin/twig/footer.html.twig @@ -0,0 +1,81 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} + + diff --git a/views/templates/admin/twig/header.html.twig b/views/templates/admin/twig/header.html.twig new file mode 100644 index 00000000..b97fbf18 --- /dev/null +++ b/views/templates/admin/twig/header.html.twig @@ -0,0 +1,92 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} + + + + + + + + + + + + + + +{% if displayToolbar %} +
    + +
    +{% endif %} + + + + + + + diff --git a/views/templates/admin/twig/header_order.html.twig b/views/templates/admin/twig/header_order.html.twig new file mode 100644 index 00000000..688c5fd4 --- /dev/null +++ b/views/templates/admin/twig/header_order.html.twig @@ -0,0 +1,18 @@ +{# + * Copyright 2017 Lengow SAS. + * Licensed under the Apache License, Version 2.0 + #} + + diff --git a/views/templates/admin/twig/index.php b/views/templates/admin/twig/index.php new file mode 100644 index 00000000..cbb2c701 --- /dev/null +++ b/views/templates/admin/twig/index.php @@ -0,0 +1,34 @@ + + * @copyright 2007-2016 PrestaShop SA + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + * International Registered Trademark & Property of PrestaShop SA + */ +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; diff --git a/views/templates/admin/twig/ps8_base.html.twig b/views/templates/admin/twig/ps8_base.html.twig new file mode 100644 index 00000000..f597aeab --- /dev/null +++ b/views/templates/admin/twig/ps8_base.html.twig @@ -0,0 +1,6 @@ +{# + * Lengow PS8 base layout - standalone (no PS admin wrapper, lite_display=true) + #} +{% block lengow_header %}{% endblock %} +{% block lengow_content %}{% endblock %} +{% block lengow_footer %}{% endblock %} diff --git a/views/templates/admin/twig/ps9_base.html.twig b/views/templates/admin/twig/ps9_base.html.twig new file mode 100644 index 00000000..a0fd020e --- /dev/null +++ b/views/templates/admin/twig/ps9_base.html.twig @@ -0,0 +1,11 @@ +{# + * Lengow PS9 base layout - extends PrestaShop admin layout + #} +{% extends '@PrestaShop/Admin/layout.html.twig' %} +{% block content %} +
    + {% block lengow_header %}{% endblock %} + {% block lengow_content %}{% endblock %} + {% block lengow_footer %}{% endblock %} +
    +{% endblock %} diff --git a/views/templates/hook/order/admin_order_tab.tpl b/views/templates/hook/order/admin_order_tab.tpl new file mode 100644 index 00000000..026f1e8e --- /dev/null +++ b/views/templates/hook/order/admin_order_tab.tpl @@ -0,0 +1,192 @@ +{* + * Copyright 2021 Lengow SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + *} +
    +
    +
    + + {if $isActiveReturnTrackingNumber || $isActiveReturnCarrier} +

    Return Shipping

    +
    + {if $isActiveReturnTrackingNumber} +
    +
    + +
    + +
    + +
    +
    +
    +
    +
    + {/if} + + {if $isActiveReturnCarrier} +
    +
    + +
    + +
    + +
    +
    +
    +
    +
    + {/if} +
    + {/if} + + {if $refundReasons|@count > 0 || $refundModes|@count > 0} +

    Refund

    +
    + {if $refundReasons|@count > 0} +
    +
    + + +
    +
    + {/if} + + {if $refundModes|@count > 0} +
    +
    + + +
    +
    + {/if} +
    + {/if} + +
    +
    +
    + + diff --git a/webservice/cron.php b/webservice/cron.php deleted file mode 100755 index 09ff7c29..00000000 --- a/webservice/cron.php +++ /dev/null @@ -1,169 +0,0 @@ - - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - * List params - * string sync Data type to synchronize - * integer days Synchronization interval time - * integer limit Maximum number of new orders created - * integer shop_id Shop id to import - * string marketplace_sku Lengow marketplace order id to synchronize - * string marketplace_name Lengow marketplace name to synchronize - * string created_from Synchronization of orders since - * string created_to Synchronization of orders until - * integer delivery_address_id Lengow delivery address id to synchronize - * boolean force_product Force import product when quantity is insufficient (1) or not (0) - * boolean force_sync Force synchronization order even if there are errors (1) or not (0) - * boolean debug_mode Activate debug mode (1) or not (0) - * boolean log_output Display log messages (1) or not (0) - * boolean get_sync See synchronization parameters in json format (1) or not (0) - */ -@set_time_limit(0); -@ini_set('memory_limit', '1024M'); -header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); -$currentDirectory = str_replace('modules/lengow/webservice/', '', dirname($_SERVER['SCRIPT_FILENAME']) . '/'); -$sep = DIRECTORY_SEPARATOR; -require_once $currentDirectory . 'config' . $sep . 'config.inc.php'; -if (!defined('_PS_VERSION_')) { - exit; -} -Configuration::set('PS_SHOP_ENABLE', true); -require_once $currentDirectory . 'init.php'; -require_once $currentDirectory . 'modules' . $sep . 'lengow' . $sep . 'lengow.php'; - -LengowLog::registerShutdownFunction(); -// check if Lengow is installed and enabled -$lengow = new Lengow(); -if (!Module::isInstalled($lengow->name)) { - $errorMessage = (!Module::isEnabled($lengow->name)) - ? 'Lengow module is not active' - : 'Lengow module is not installed'; - header('HTTP/1.1 400 Bad Request'); - exit($errorMessage); -} -// check IP access and Token -$token = Tools::getIsset(LengowImport::PARAM_TOKEN) ? Tools::getValue(LengowImport::PARAM_TOKEN) : ''; -if (!LengowMain::checkWebservicesAccess($token)) { - if ((bool) LengowConfiguration::get(LengowConfiguration::AUTHORIZED_IP_ENABLED)) { - $errorMessage = 'Unauthorized access for IP: ' . $_SERVER['REMOTE_ADDR']; - } else { - $errorMessage = $token !== '' - ? 'Unauthorised access for this token: ' . $token - : 'Unauthorised access: token parameter is empty'; - } - header('HTTP/1.1 403 Forbidden'); - exit($errorMessage); -} - -if (Tools::getIsset(LengowImport::PARAM_GET_SYNC) && Tools::getValue(LengowImport::PARAM_GET_SYNC) == 1) { - echo json_encode(LengowSync::getSyncData()); -} else { - $force = Tools::getIsset(LengowImport::PARAM_FORCE) ? (bool) Tools::getValue(LengowImport::PARAM_FORCE) : false; - $logOutput = Tools::getIsset(LengowImport::PARAM_LOG_OUTPUT) - ? (bool) Tools::getValue(LengowImport::PARAM_LOG_OUTPUT) - : false; - // get sync action if exists - $sync = Tools::getIsset(LengowImport::PARAM_SYNC) ? Tools::getValue(LengowImport::PARAM_SYNC) : false; - // sync catalogs id between Lengow and PrestaShop - if (!$sync || $sync === LengowSync::SYNC_CATALOG) { - LengowSync::syncCatalog($force, $logOutput); - } - // sync marketplace and marketplace carrier between Lengow and PrestaShop - if (!$sync || $sync === LengowSync::SYNC_CARRIER) { - LengowSync::syncCarrier($force, $logOutput); - } - // sync orders between Lengow and PrestaShop - if (!$sync || $sync === LengowSync::SYNC_ORDER) { - // array of params for import order - $params = [ - LengowImport::PARAM_TYPE => LengowImport::TYPE_CRON, - LengowImport::PARAM_LOG_OUTPUT => $logOutput, - ]; - // check if the GET parameters are available - if (Tools::getIsset(LengowImport::PARAM_FORCE_PRODUCT)) { - $params[LengowImport::PARAM_FORCE_PRODUCT] = (bool) Tools::getValue(LengowImport::PARAM_FORCE_PRODUCT); - } - if (Tools::getIsset(LengowImport::PARAM_FORCE_SYNC)) { - $params[LengowImport::PARAM_FORCE_SYNC] = (bool) Tools::getValue(LengowImport::PARAM_FORCE_SYNC); - } - if (Tools::getIsset(LengowImport::PARAM_DEBUG_MODE)) { - $params[LengowImport::PARAM_DEBUG_MODE] = (bool) Tools::getValue(LengowImport::PARAM_DEBUG_MODE); - } - if (Tools::getIsset(LengowImport::PARAM_MINUTES) && is_numeric(Tools::getValue(LengowImport::PARAM_MINUTES))) { - $params[LengowImport::PARAM_MINUTES] = (float) Tools::getValue(LengowImport::PARAM_MINUTES); - } - if (Tools::getIsset(LengowImport::PARAM_DAYS) && is_numeric(Tools::getValue(LengowImport::PARAM_DAYS))) { - $params[LengowImport::PARAM_DAYS] = (float) Tools::getValue(LengowImport::PARAM_DAYS); - } - if (Tools::getIsset(LengowImport::PARAM_CREATED_FROM)) { - $params[LengowImport::PARAM_CREATED_FROM] = Tools::getValue(LengowImport::PARAM_CREATED_FROM); - } - if (Tools::getIsset(LengowImport::PARAM_CREATED_TO)) { - $params[LengowImport::PARAM_CREATED_TO] = Tools::getValue(LengowImport::PARAM_CREATED_TO); - } - if (Tools::getIsset(LengowImport::PARAM_LIMIT) && is_numeric(Tools::getValue(LengowImport::PARAM_LIMIT))) { - $params[LengowImport::PARAM_LIMIT] = (int) Tools::getValue(LengowImport::PARAM_LIMIT); - } - if (Tools::getIsset(LengowImport::PARAM_MARKETPLACE_SKU)) { - $params[LengowImport::PARAM_MARKETPLACE_SKU] = Tools::getValue(LengowImport::PARAM_MARKETPLACE_SKU); - } - if (Tools::getIsset(LengowImport::PARAM_MARKETPLACE_NAME)) { - $params[LengowImport::PARAM_MARKETPLACE_NAME] = Tools::getValue(LengowImport::PARAM_MARKETPLACE_NAME); - } - if (Tools::getIsset(LengowImport::PARAM_DELIVERY_ADDRESS_ID)) { - $params[LengowImport::PARAM_DELIVERY_ADDRESS_ID] = (int) Tools::getValue( - LengowImport::PARAM_DELIVERY_ADDRESS_ID - ); - } - if (Tools::getIsset(LengowImport::PARAM_SHOP_ID) && is_numeric(Tools::getValue(LengowImport::PARAM_SHOP_ID))) { - $params[LengowImport::PARAM_SHOP_ID] = (int) Tools::getValue(LengowImport::PARAM_SHOP_ID); - } - // import orders - $import = new LengowImport($params); - $import->exec(); - } - // sync actions between Lengow and PrestaShop - if (!$sync || $sync === LengowSync::SYNC_ACTION) { - LengowAction::checkFinishAction($logOutput); - LengowAction::checkOldAction($logOutput); - LengowAction::checkActionNotSent($logOutput); - } - // sync options between Lengow and PrestaShop - if (!$sync || $sync === LengowSync::SYNC_CMS_OPTION) { - LengowSync::setCmsOption($force, $logOutput); - } - // sync marketplaces between Lengow and PrestaShop - if ($sync === LengowSync::SYNC_MARKETPLACE) { - LengowSync::getMarketplaces($force, $logOutput); - } - // sync status account between Lengow and PrestaShop - if ($sync === LengowSync::SYNC_STATUS_ACCOUNT) { - LengowSync::getStatusAccount($force, $logOutput); - } - // sync plugin data between Lengow and PrestaShop - if ($sync === LengowSync::SYNC_PLUGIN_DATA) { - LengowSync::getPluginData($force, $logOutput); - } - // sync option is not valid - if ($sync && !in_array($sync, LengowSync::$syncActions, true)) { - header('HTTP/1.1 400 Bad Request'); - exit('Action: ' . $sync . ' is not a valid action'); - } -} diff --git a/webservice/export.php b/webservice/export.php deleted file mode 100755 index e14a8498..00000000 --- a/webservice/export.php +++ /dev/null @@ -1,230 +0,0 @@ - - * @copyright 2017 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - * List params - * string mode Number of products exported - * string format Format of exported files ('csv','yaml','xml','json') - * boolean stream Stream file (1) or generate a file on server (0) - * integer offset Offset of total product - * integer limit Limit number of exported product - * boolean selection Export product selection (1) or all products (0) - * boolean out_of_stock Export out of stock product (1) Export only product in stock (0) - * string product_ids List of product id separate with comma (1,2,3) - * boolean variation Export product Variation (1) Export parent product only (0) - * boolean inactive Export inactive product (1) or not (0) - * integer shop Export a specific shop - * string currency Convert prices with a specific currency - * string language Translate content with a specific language - * boolean legacy_fields Export feed with v2 fields (1) or v3 fields (0) - * boolean log_output See logs (1) or not (0) - * boolean update_export_date Change last export date in data base (1) or not (0) - * boolean get_params See export parameters and authorized values in json format (1) or not (0) - */ -@set_time_limit(0); -@ini_set('memory_limit', '1024M'); -header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -$currentDirectory = str_replace('modules/lengow/webservice/', '', dirname($_SERVER['SCRIPT_FILENAME']) . '/'); -$sep = DIRECTORY_SEPARATOR; -require_once $currentDirectory . 'config' . $sep . 'config.inc.php'; -if (!defined('_PS_VERSION_')) { - exit; -} -Configuration::set('PS_SHOP_ENABLE', true); -require_once $currentDirectory . 'init.php'; -require_once $currentDirectory . 'modules/lengow/lengow.php'; - -LengowLog::registerShutdownFunction(); -$lengow = new Lengow(); -// check if Lengow is installed and enabled -if (!Module::isInstalled($lengow->name)) { - $errorMessage = (!Module::isEnabled($lengow->name)) - ? 'Lengow module is not active' - : 'Lengow module is not installed'; - header('HTTP/1.1 400 Bad Request'); - exit($errorMessage); -} -// CheckIP -$token = Tools::getIsset(LengowExport::PARAM_TOKEN) ? Tools::getValue(LengowExport::PARAM_TOKEN) : ''; -if (!LengowMain::checkWebservicesAccess($token, Context::getContext()->shop->id)) { - if ((bool) LengowConfiguration::get(LengowConfiguration::AUTHORIZED_IP_ENABLED)) { - $errorMessage = 'Unauthorized access for IP: ' . $_SERVER['REMOTE_ADDR']; - } else { - $errorMessage = $token !== '' - ? 'Unauthorised access for this token: ' . $token - : 'Unauthorised access: token parameter is empty'; - } - header('HTTP/1.1 403 Forbidden'); - exit($errorMessage); -} -// get params data -$getParams = Tools::getIsset(LengowExport::PARAM_GET_PARAMS) - ? (bool) Tools::getValue(LengowExport::PARAM_GET_PARAMS) - : false; -// get mode -$mode = ( - Tools::getIsset(LengowExport::PARAM_MODE) - && (Tools::getValue(LengowExport::PARAM_MODE) === 'size' || Tools::getValue(LengowExport::PARAM_MODE) === 'total') -) ? Tools::getValue(LengowExport::PARAM_MODE) : null; -// export format (csv, yaml, xml, json) -$format = Tools::getIsset(LengowExport::PARAM_FORMAT) - ? Tools::getValue(LengowExport::PARAM_FORMAT) - : LengowConfiguration::getGlobalValue(LengowConfiguration::EXPORT_FORMAT); -// export in file or not -$stream = Tools::getIsset(LengowExport::PARAM_STREAM) - ? (bool) Tools::getValue(LengowExport::PARAM_STREAM) - : !(bool) LengowConfiguration::getGlobalValue(LengowConfiguration::EXPORT_FILE_ENABLED); -// export offset -$offset = Tools::getIsset(LengowExport::PARAM_OFFSET) ? (int) Tools::getValue(LengowExport::PARAM_OFFSET) : null; -// export limit -$limit = Tools::getIsset(LengowExport::PARAM_LIMIT) ? (int) Tools::getValue(LengowExport::PARAM_LIMIT) : null; -// export specific shop -if (Tools::getIsset(LengowExport::PARAM_SHOP)) { - $shop = new Shop((int) Tools::getValue(LengowExport::PARAM_SHOP)); - if ($shop->id) { - $shop::setContext(Shop::CONTEXT_SHOP, $shop->id); - Context::getContext()->shop = $shop; - } -} -$idShop = (int) Context::getContext()->shop->id; -// export lengow selection -$selection = Tools::getIsset(LengowExport::PARAM_LEGACY_SELECTION) - ? !(bool) Tools::getValue(LengowExport::PARAM_LEGACY_SELECTION) - : null; -if ($selection !== null || Tools::getIsset(LengowExport::PARAM_SELECTION)) { - $selection = $selection !== null ? $selection : (bool) Tools::getValue(LengowExport::PARAM_SELECTION); -} else { - $selection = (bool) LengowConfiguration::get(LengowConfiguration::SELECTION_ENABLED, null, null, $idShop); -} -// export out of stock products -$outOfStock = Tools::getIsset(LengowExport::PARAM_LEGACY_OUT_OF_STOCK) - ? (bool) Tools::getValue(LengowExport::PARAM_LEGACY_OUT_OF_STOCK) - : null; -if ($outOfStock !== null || Tools::getIsset(LengowExport::PARAM_OUT_OF_STOCK)) { - $outOfStock = $outOfStock !== null ? $outOfStock : (bool) Tools::getValue(LengowExport::PARAM_OUT_OF_STOCK); -} else { - $outOfStock = (bool) LengowConfiguration::get(LengowConfiguration::OUT_OF_STOCK_ENABLED, null, null, $idShop); -} -// export specific products -$productIds = []; -$ids = Tools::getIsset(LengowExport::PARAM_LEGACY_PRODUCT_IDS) - ? Tools::getValue(LengowExport::PARAM_LEGACY_PRODUCT_IDS) - : null; -if ($ids !== null || Tools::getIsset(LengowExport::PARAM_PRODUCT_IDS)) { - $ids = $ids !== null ? $ids : Tools::getValue(LengowExport::PARAM_PRODUCT_IDS); - if (Tools::strlen($ids) > 0) { - $ids = str_replace([';', '|', ':'], ',', $ids); - $ids = preg_replace('/[^0-9\,]/', '', $ids); - $productIds = explode(',', $ids); - } -} -// export product variation -$variation = null; -if (Tools::getIsset(LengowExport::PARAM_LEGACY_VARIATION)) { - if (Tools::getValue(LengowExport::PARAM_LEGACY_VARIATION) === 'simple') { - $variation = false; - } elseif (Tools::getValue(LengowExport::PARAM_LEGACY_VARIATION) === 'full') { - $variation = true; - } -} -if ($variation !== null || Tools::getIsset(LengowExport::PARAM_VARIATION)) { - $variation = $variation !== null ? $variation : (bool) Tools::getValue(LengowExport::PARAM_VARIATION); -} else { - $variation = (bool) LengowConfiguration::get(LengowConfiguration::VARIATION_ENABLED, null, null, $idShop); -} -// export inactive products -$inactive = null; -if (Tools::getValue(LengowExport::PARAM_LEGACY_INACTIVE)) { - if (Tools::getValue(LengowExport::PARAM_LEGACY_INACTIVE) === 'enabled') { - $inactive = false; - } elseif (Tools::getValue(LengowExport::PARAM_LEGACY_INACTIVE) === 'all') { - $inactive = true; - } -} -if ($inactive !== null || Tools::getIsset(LengowExport::PARAM_INACTIVE)) { - $inactive = $inactive !== null ? $inactive : (bool) Tools::getValue(LengowExport::PARAM_INACTIVE); -} else { - $inactive = (bool) LengowConfiguration::get(LengowConfiguration::INACTIVE_ENABLED, null, null, $idShop); -} -// convert price for a specific currency -$currency = Tools::getIsset(LengowExport::PARAM_LEGACY_CURRENCY) - ? Tools::getValue(LengowExport::PARAM_LEGACY_CURRENCY) - : null; -if ($currency !== null || Tools::getIsset(LengowExport::PARAM_CURRENCY)) { - $currency = $currency !== null ? $currency : Tools::getValue(LengowExport::PARAM_CURRENCY); - $idCurrency = (int) Currency::getIdByIsoCode($currency); - if ($idCurrency !== 0) { - Context::getContext()->currency = new Currency($idCurrency); - } -} -// define language -$language = Tools::getIsset(LengowExport::PARAM_LEGACY_LANGUAGE) - ? Tools::getValue(LengowExport::PARAM_LEGACY_LANGUAGE) - : null; -if ($language !== null || Tools::getIsset(LengowExport::PARAM_LANGUAGE)) { - $language = $language !== null ? $language : Tools::getValue(LengowExport::PARAM_LANGUAGE); - $languageId = (int) Language::getIdByIso($language); - if ($languageId === 0) { - $languageId = Context::getContext()->language->id; - } -} else { - $languageId = Context::getContext()->language->id; -} -// get legacy fields -$legacyFields = Tools::getIsset(LengowExport::PARAM_LEGACY_FIELDS) - ? (bool) Tools::getValue(LengowExport::PARAM_LEGACY_FIELDS) - : null; -// update export date -$updateExportDate = Tools::getIsset(LengowExport::PARAM_UPDATE_EXPORT_DATE) - ? (bool) Tools::getValue(LengowExport::PARAM_UPDATE_EXPORT_DATE) - : true; -// See logs or not -$logOutput = Tools::getIsset(LengowExport::PARAM_LOG_OUTPUT) - ? (bool) Tools::getValue(LengowExport::PARAM_LOG_OUTPUT) - : true; - -$export = new LengowExport( - [ - LengowExport::PARAM_FORMAT => $format, - LengowExport::PARAM_STREAM => $stream, - LengowExport::PARAM_PRODUCT_IDS => $productIds, - LengowExport::PARAM_LIMIT => $limit, - LengowExport::PARAM_OFFSET => $offset, - LengowExport::PARAM_OUT_OF_STOCK => $outOfStock, - LengowExport::PARAM_VARIATION => $variation, - LengowExport::PARAM_INACTIVE => $inactive, - LengowExport::PARAM_LEGACY_FIELDS => $legacyFields, - LengowExport::PARAM_SELECTION => $selection, - LengowExport::PARAM_LANGUAGE_ID => $languageId, - LengowExport::PARAM_UPDATE_EXPORT_DATE => $updateExportDate, - LengowExport::PARAM_LOG_OUTPUT => $logOutput, - ] -); - -if ($getParams) { - echo $export->getExportParams(); -} elseif ($mode === 'size') { - echo $export->getTotalExportProduct(); -} elseif ($mode === 'total') { - echo $export->getTotalProduct(); -} else { - $export->exec(); -} diff --git a/webservice/toolbox.php b/webservice/toolbox.php deleted file mode 100644 index eb0d4847..00000000 --- a/webservice/toolbox.php +++ /dev/null @@ -1,127 +0,0 @@ - - * @copyright 2021 Lengow SAS - * @license http://www.apache.org/licenses/LICENSE-2.0 - * List params - * string toolbox_action Toolbox specific action - * string type Type of data to display - * string created_from Synchronization of orders since - * string created_to Synchronization of orders until - * string date Log date to download - * string marketplace_name Lengow marketplace name to synchronize - * string marketplace_sku Lengow marketplace order id to synchronize - * string process Type of process for order action - * boolean force Force synchronization order even if there are errors (1) or not (0) - * integer shop_id Shop id to synchronize - * integer days Synchronization interval time - */ -@set_time_limit(0); -header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -$currentDirectory = str_replace('modules/lengow/webservice/', '', dirname($_SERVER['SCRIPT_FILENAME']) . '/'); -$sep = DIRECTORY_SEPARATOR; -require_once $currentDirectory . 'config' . $sep . 'config.inc.php'; -if (!defined('_PS_VERSION_')) { - exit; -} -Configuration::set('PS_SHOP_ENABLE', true); -require_once $currentDirectory . 'init.php'; -require_once $currentDirectory . 'modules' . $sep . 'lengow' . $sep . 'lengow.php'; - -LengowLog::registerShutdownFunction(); -// check if Lengow is installed and enabled -$lengow = new Lengow(); -if (!Module::isInstalled($lengow->name)) { - $errorMessage = (!Module::isEnabled($lengow->name)) - ? 'Lengow module is not active' - : 'Lengow module is not installed'; - header('HTTP/1.1 400 Bad Request'); - exit($errorMessage); -} -// check IP access and Token -$token = Tools::getValue(LengowToolbox::PARAM_TOKEN, ''); -if (!LengowMain::checkWebservicesAccess($token)) { - if ((bool) LengowConfiguration::get(LengowConfiguration::AUTHORIZED_IP_ENABLED)) { - $errorMessage = 'Unauthorized access for IP: ' . $_SERVER['REMOTE_ADDR']; - } else { - $errorMessage = $token !== '' - ? 'Unauthorised access for this token: ' . $token - : 'Unauthorised access: token parameter is empty'; - } - header('HTTP/1.1 403 Forbidden'); - exit($errorMessage); -} - -$action = Tools::getValue(LengowToolbox::PARAM_TOOLBOX_ACTION, LengowToolbox::ACTION_DATA); -// check if toolbox action is valid -if (!in_array($action, LengowToolbox::$toolboxActions, true)) { - header('HTTP/1.1 400 Bad Request'); - exit('Action: ' . $action . ' is not a valid action'); -} - -switch ($action) { - case LengowToolbox::ACTION_LOG: - $date = Tools::getValue(LengowToolbox::PARAM_DATE, null); - LengowToolbox::downloadLog($date); - break; - case LengowToolbox::ACTION_ORDER: - $process = Tools::getValue(LengowToolbox::PARAM_PROCESS, LengowToolbox::PROCESS_TYPE_SYNC); - $error = false; - if ($process === LengowToolbox::PROCESS_TYPE_GET_DATA) { - $result = LengowToolbox::getOrderData( - Tools::getValue(LengowToolbox::PARAM_MARKETPLACE_SKU, null), - Tools::getValue(LengowToolbox::PARAM_MARKETPLACE_NAME, null), - Tools::getValue(LengowToolbox::PARAM_TYPE, null) - ); - } else { - $result = LengowToolbox::syncOrders( - [ - LengowToolbox::PARAM_CREATED_TO => Tools::getValue(LengowToolbox::PARAM_CREATED_TO, null), - LengowToolbox::PARAM_CREATED_FROM => Tools::getValue(LengowToolbox::PARAM_CREATED_FROM, null), - LengowToolbox::PARAM_DAYS => Tools::getValue(LengowToolbox::PARAM_DAYS, null), - LengowToolbox::PARAM_FORCE => Tools::getValue(LengowToolbox::PARAM_FORCE, null), - LengowToolbox::PARAM_MARKETPLACE_NAME => Tools::getValue( - LengowToolbox::PARAM_MARKETPLACE_NAME, - null - ), - LengowToolbox::PARAM_MARKETPLACE_SKU => Tools::getValue(LengowToolbox::PARAM_MARKETPLACE_SKU, null), - LengowToolbox::PARAM_SHOP_ID => Tools::getValue(LengowToolbox::PARAM_SHOP_ID, null), - ] - ); - } - if (isset($result[LengowToolbox::ERRORS][LengowToolbox::ERROR_CODE])) { - $error = true; - if ($result[LengowToolbox::ERRORS][LengowToolbox::ERROR_CODE] === LengowConnector::CODE_404) { - header('HTTP/1.1 404 Not Found'); - } else { - header('HTTP/1.1 403 Forbidden'); - } - } - if (!$error) { - header('Content-Type: application/json'); - } - echo json_encode($result); - break; - default: - header('Content-Type: application/json'); - $type = Tools::getValue(LengowToolbox::PARAM_TYPE, null); - echo json_encode(LengowToolbox::getData($type)); - break; -}