* * @throws PrestaShopDatabaseException * @throws PrestaShopException */ public function useDisplayDashboardTopExtraOperations(): void { $hookName = 'actionMboRecommendedModules'; $id_hook = Hook::getIdByName($hookName, false); if (!$id_hook) { $new_hook = new Hook(); $new_hook->name = pSQL($hookName); $new_hook->title = ''; $new_hook->position = true; $new_hook->add(); } } /** * Insert a block on the top of the configuration with a link to addons * * @param string $moduleName * * @return string */ protected function displayPushOnConfigurationPage(string $moduleName): string { switch ($moduleName) { case 'contactform': $this->smarty->assign([ 'catchPhrase' => $this->trans( 'For even more security on your website forms, consult our Security & Access modules category on the', [], 'Modules.Mbo.Global' ), 'linkTarget' => $this->trans( 'https://addons.prestashop.com/en/429-website-security-access?utm_source=back-office&utm_medium=native-contactform&utm_campaign=back-office-EN&utm_content=security', [], 'Modules.Mbo.Links' ), 'linkText' => $this->trans('PrestaShop Addons Marketplace', [], 'Modules.Mbo.Global'), ]); break; case 'blockreassurance': $this->smarty->assign([ 'catchPhrase' => $this->trans( 'Discover more modules to improve your shop on', [], 'Modules.Mbo.Global' ), 'linkTarget' => $this->trans( 'https://addons.prestashop.com/en/517-blocks-tabs-banners?utm_source=back-office&utm_medium=modules&utm_campaign=back-office-EN', [], 'Modules.Mbo.Links' ), 'linkText' => $this->trans('PrestaShop Addons Marketplace', [], 'Modules.Mbo.Global'), ]); break; default: $this->smarty->assign([ 'catchPhrase' => $this->trans( 'Discover more modules to improve your shop on', [], 'Modules.Mbo.Global' ), 'linkTarget' => $this->trans( 'https://addons.prestashop.com/?utm_source=back-office&utm_medium=modules&utm_campaign=back-office-EN', [], 'Modules.Mbo.Links' ), 'linkText' => $this->trans('PrestaShop Addons Marketplace', [], 'Modules.Mbo.Global'), ]); } return $this->fetch('module:ps_mbo/views/templates/hook/push-configuration.tpl'); } private function displayFailedApiUser(): string { try { /** @var \Twig\Environment $twig */ $twig = $this->get('twig'); /** @var Router $router*/ $router = $this->get('router'); if (null === $twig || null === $router) { throw new ExpectedServiceNotFoundException( 'Some services not found in UseDisplayDashboardTop' ); } return $twig->render( '@Modules/ps_mbo/views/templates/hook/twig/failed-api-user.html.twig', [ 'module_manager_link' => $router->generate('admin_module_manage'), ] ); } catch (Exception $e) { ErrorHelper::reportError($e); return ''; } } /** * Compute & include data with recommended modules when needed * * @throws Exception */ protected function displayRecommendedModules(string $controller): string { $recommendedModulesDisplayed = true; // Ask to modules if recommended modules should be displayed in this context Hook::exec('actionMboRecommendedModules', [ 'recommendedModulesDisplayed' => &$recommendedModulesDisplayed, 'controller' => $controller, ]); $afterContentType = TabInterface::RECOMMENDED_AFTER_CONTENT_TYPE; $recommendedButtonType = TabInterface::RECOMMENDED_BUTTON_TYPE; // We want to "hide" recommended modules from this controller if (!$recommendedModulesDisplayed) { // If we are trying to display as button, hide the button if ( in_array( $controller, $this->controllersWithRecommendedModules[$recommendedButtonType] ) ) { return ''; } elseif ( in_array( $controller, $this->controllersWithRecommendedModules[$afterContentType] ) ) { // We are trying to display after content, so move them to button adn remove from after content foreach ($this->controllersWithRecommendedModules[$afterContentType] as $k => $afterContentController) { if ($afterContentController === $controller) { unset($this->controllersWithRecommendedModules[$afterContentType][$k]); break; } } $this->controllersWithRecommendedModules[TabInterface::RECOMMENDED_BUTTON_TYPE][] = $controller; } } $shouldAttachRecommendedModulesAfterContent = $this->shouldAttachRecommendedModules($afterContentType); $shouldAttachRecommendedModulesButton = $this->shouldAttachRecommendedModules($recommendedButtonType); if (!$shouldAttachRecommendedModulesAfterContent && !$shouldAttachRecommendedModulesButton) { return ''; } try { /** @var UrlGeneratorInterface $router */ $router = $this->get('router'); if (null === $router) { throw new ExpectedServiceNotFoundException( 'Some services not found in UseDisplayDashboardTop' ); } $recommendedModulesUrl = $router->generate( 'admin_mbo_recommended_modules', [ 'tabClassName' => Tools::getValue('controller'), 'recommendation_format' => $shouldAttachRecommendedModulesButton ? 'modal' : 'card', ] ); } catch (Exception $exception) { // Avoid fatal errors on ServiceNotFoundException ErrorHelper::reportError($exception); return ''; } $this->smarty->assign([ 'shouldAttachRecommendedModulesAfterContent' => $shouldAttachRecommendedModulesAfterContent, 'shouldAttachRecommendedModulesButton' => $shouldAttachRecommendedModulesButton, 'shouldUseLegacyTheme' => $this->isAdminLegacyContext(), 'recommendedModulesCloseTranslated' => $this->trans('Close', [], 'Admin.Actions'), 'recommendedModulesUrl' => $recommendedModulesUrl, 'recommendedModulesTitleTranslated' => $this->getRecommendedModulesButtonTitle($controller), ]); return $this->fetch('module:ps_mbo/views/templates/hook/recommended-modules.tpl'); } /** * Indicates if the recommended modules should be attached * * @param string $type If we want `afterContent` or `button` related modules * * @return bool */ protected function shouldAttachRecommendedModules(string $type): bool { if ($type === TabInterface::RECOMMENDED_BUTTON_TYPE) { $modules = $this->controllersWithRecommendedModules[TabInterface::RECOMMENDED_BUTTON_TYPE]; } elseif ($type === TabInterface::RECOMMENDED_AFTER_CONTENT_TYPE) { $modules = $this->controllersWithRecommendedModules[TabInterface::RECOMMENDED_AFTER_CONTENT_TYPE]; } else { return false; } return in_array(Tools::getValue('controller'), $modules, true); } /** * Add JS and CSS file * * @return void * * @see \PrestaShop\Module\Mbo\Traits\Hooks\UseActionAdminControllerSetMedia */ protected function loadMediaForDashboardTop(): void { // has to be loaded in header to prevent flash of content $this->context->controller->addJs($this->getPathUri() . 'views/js/recommended-modules.js?v=' . $this->version); if ( $this->shouldAttachRecommendedModules(TabInterface::RECOMMENDED_BUTTON_TYPE) || $this->shouldAttachRecommendedModules(TabInterface::RECOMMENDED_AFTER_CONTENT_TYPE) ) { $this->context->controller->addCSS($this->getPathUri() . 'views/css/recommended-modules.css'); } } /** * Customize title button recommended modules */ private function getRecommendedModulesButtonTitle(string $controller): string { switch ($controller) { case 'AdminEmails': $title = $this->trans('Automate emails', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; case 'AdminOrders': $title = $this->trans('Boost sales', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; case 'AdminCartRules': case 'AdminSpecificPriceRule': $title = $this->trans('Create a discount strategy', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; case 'AdminCmsContent': $title = $this->trans('Customize pages', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; case 'AdminContacts': case 'AdminCustomers': case 'AdminCustomerThreads': $title = $this->trans('Improve customer experience', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; case 'AdminGroups': $title = $this->trans('Improve customer targeting', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; case 'AdminStats': $title = $this->trans('Improve data strategy', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; case 'AdminMeta': case 'AdminSearchConf': $title = $this->trans('Improve SEO', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; case 'AdminShipping': $title = $this->trans('Improve shipping', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; case 'AdminPayment': $title = $this->trans( 'Improve the checkout experience', [], 'Modules.Mbo.Recommendedmodulesandservices' ); break; case 'AdminImages': $title = $this->trans('Improve visuals', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; case 'AdminDeliverySlip': $title = $this->trans('Make shipping easier', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; case 'AdminCarriers': $title = $this->trans('Make your deliveries easier', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; case 'AdminStatuses': $title = $this->trans('Optimize order management', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; case 'AdminProducts': $title = $this->trans('Optimize product catalog', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; case 'AdminFeatures': $title = $this->trans('Optimize product creation', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; case 'AdminManufacturers': $title = $this->trans('Promote brands', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; case 'AdminInvoices': case 'AdminSlip': $title = $this->trans('Simplify accounting', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; case 'AdminAdminPreferences': $title = $this->trans('Simplify store management', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; default: $title = $this->trans('Recommended modules', [], 'Modules.Mbo.Recommendedmodulesandservices'); break; } return $title; } }