diff --git a/config/form.yml b/config/form.yml index 1d634eb..031f3ca 100644 --- a/config/form.yml +++ b/config/form.yml @@ -2,8 +2,7 @@ services: websmid.customhtml.form.type.customhtml_group: public: true class: 'Websmid\CustomHtml\Form\Type\CustomHtmlGroupType' - arguments: - - '@translator' + parent: "form.type.translatable.aware" tags: - { name: form.type } @@ -53,8 +52,8 @@ services: websmid.customhtml.form.type.customhtml_block: public: true class: 'Websmid\CustomHtml\Form\Type\CustomHtmlBlockType' + parent: "form.type.translatable.aware" arguments: - - '@translator' - '@websmid.customhtml.form.choice_provider.customhtml_group_choice_provider' tags: - { name: form.type } diff --git a/src/Form/ChoiceProvider/CustomHtmlGroupChoiceProvider.php b/src/Form/ChoiceProvider/CustomHtmlGroupChoiceProvider.php index 1f12272..177c146 100644 --- a/src/Form/ChoiceProvider/CustomHtmlGroupChoiceProvider.php +++ b/src/Form/ChoiceProvider/CustomHtmlGroupChoiceProvider.php @@ -5,6 +5,7 @@ namespace Websmid\CustomHtml\Form\ChoiceProvider; use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; use PrestaShop\PrestaShop\Core\Form\FormChoiceAttributeProviderInterface; use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; +use Context; use Db; final class CustomHtmlGroupChoiceProvider implements @@ -38,10 +39,14 @@ final class CustomHtmlGroupChoiceProvider implements private function getGroupsWithLabels(): array { + $idLang = (int) Context::getContext()->language->id; + $groups = Db::getInstance()->executeS( - 'SELECT `id_ws_customhtml_group`, `title`, `default_block_class` - FROM `' . _DB_PREFIX_ . 'ws_customhtml_group` - ORDER BY `title` ASC' + 'SELECT g.`id_ws_customhtml_group`, gl.`title`, g.`default_block_class` + FROM `' . _DB_PREFIX_ . 'ws_customhtml_group` g + LEFT JOIN `' . _DB_PREFIX_ . 'ws_customhtml_group_lang` gl + ON gl.`id_ws_customhtml_group` = g.`id_ws_customhtml_group` AND gl.`id_lang` = ' . $idLang . ' + ORDER BY gl.`title` ASC' ); $titleCounts = array_count_values(array_column($groups, 'title')); diff --git a/src/Form/DataHandler/CustomHtmlBlockDataHandler.php b/src/Form/DataHandler/CustomHtmlBlockDataHandler.php index 9fbbcfd..dcae45f 100644 --- a/src/Form/DataHandler/CustomHtmlBlockDataHandler.php +++ b/src/Form/DataHandler/CustomHtmlBlockDataHandler.php @@ -20,15 +20,15 @@ final class CustomHtmlBlockDataHandler implements FormDataHandlerInterface $block = new CustomHtmlBlock(); $block->id_ws_customhtml_group = $idGroup; - $block->title = (string) $formData['title']; + $block->title = $formData['title']; $block->type = (string) $formData['type']; $block->show_title = (int) $formData['show_title']; $block->custom_class = (string) ($formData['custom_class'] ?? ''); - $block->content = (string) $formData['content']; - $block->description = (string) ($formData['description'] ?? ''); - $block->extra_description = (string) ($formData['extra_description'] ?? ''); - $block->link = (string) ($formData['link'] ?? ''); - $block->link_text = (string) ($formData['link_text'] ?? ''); + $block->content = $formData['content']; + $block->description = $formData['description'] ?? []; + $block->extra_description = $formData['extra_description'] ?? []; + $block->link = $formData['link'] ?? []; + $block->link_text = $formData['link_text'] ?? []; $block->alert_type = (string) ($formData['alert_type'] ?? 'info'); $block->timeout = (int) ($formData['timeout'] ?? 0); $block->slider_mode = (string) ($formData['slider_mode'] ?? Config::SLIDER_DEFAULT_MODE); @@ -59,15 +59,15 @@ final class CustomHtmlBlockDataHandler implements FormDataHandlerInterface } $block->id_ws_customhtml_group = (int) $formData['id_ws_customhtml_group']; - $block->title = (string) $formData['title']; + $block->title = $formData['title']; $block->type = (string) $formData['type']; $block->show_title = (int) $formData['show_title']; $block->custom_class = (string) ($formData['custom_class'] ?? ''); - $block->content = (string) $formData['content']; - $block->description = (string) ($formData['description'] ?? ''); - $block->extra_description = (string) ($formData['extra_description'] ?? ''); - $block->link = (string) ($formData['link'] ?? ''); - $block->link_text = (string) ($formData['link_text'] ?? ''); + $block->content = $formData['content']; + $block->description = $formData['description'] ?? []; + $block->extra_description = $formData['extra_description'] ?? []; + $block->link = $formData['link'] ?? []; + $block->link_text = $formData['link_text'] ?? []; $block->alert_type = (string) ($formData['alert_type'] ?? 'info'); $block->timeout = (int) ($formData['timeout'] ?? 0); $block->slider_mode = (string) ($formData['slider_mode'] ?? Config::SLIDER_DEFAULT_MODE); diff --git a/src/Form/DataHandler/CustomHtmlGroupDataHandler.php b/src/Form/DataHandler/CustomHtmlGroupDataHandler.php index 48adb87..e74a5ae 100644 --- a/src/Form/DataHandler/CustomHtmlGroupDataHandler.php +++ b/src/Form/DataHandler/CustomHtmlGroupDataHandler.php @@ -15,7 +15,7 @@ final class CustomHtmlGroupDataHandler implements FormDataHandlerInterface public function create(array $formData) { $group = new CustomHtmlGroup(); - $group->title = (string) $formData['title']; + $group->title = $formData['title']; $group->hook_name = (string) $formData['hook_name']; $group->custom_class = (string) ($formData['custom_class'] ?? ''); $group->default_block_class = (string) ($formData['default_block_class'] ?? ''); @@ -48,7 +48,7 @@ final class CustomHtmlGroupDataHandler implements FormDataHandlerInterface return false; } - $group->title = (string) $formData['title']; + $group->title = $formData['title']; $group->hook_name = (string) $formData['hook_name']; $group->custom_class = (string) ($formData['custom_class'] ?? ''); $group->default_block_class = (string) ($formData['default_block_class'] ?? ''); diff --git a/src/Form/DataProvider/CustomHtmlBlockDataProvider.php b/src/Form/DataProvider/CustomHtmlBlockDataProvider.php index 493c2d1..93d0204 100644 --- a/src/Form/DataProvider/CustomHtmlBlockDataProvider.php +++ b/src/Form/DataProvider/CustomHtmlBlockDataProvider.php @@ -48,16 +48,16 @@ final class CustomHtmlBlockDataProvider implements FormDataProviderInterface { return [ 'id_ws_customhtml_group' => 0, - 'title' => '', + 'title' => [], 'type' => 'html', 'show_title' => false, 'custom_class' => '', - 'content' => '', + 'content' => [], 'image' => null, - 'description' => '', - 'extra_description' => '', - 'link' => '', - 'link_text' => '', + 'description' => [], + 'extra_description' => [], + 'link' => [], + 'link_text' => [], 'alert_type' => 'info', 'timeout' => 0, 'slider_mode' => Config::SLIDER_DEFAULT_MODE, diff --git a/src/Form/DataProvider/CustomHtmlGroupDataProvider.php b/src/Form/DataProvider/CustomHtmlGroupDataProvider.php index c0eea0f..8e12a5a 100644 --- a/src/Form/DataProvider/CustomHtmlGroupDataProvider.php +++ b/src/Form/DataProvider/CustomHtmlGroupDataProvider.php @@ -28,7 +28,7 @@ final class CustomHtmlGroupDataProvider implements FormDataProviderInterface public function getDefaultData() { return [ - 'title' => '', + 'title' => [], 'hook_name' => '', 'custom_class' => '', 'default_block_class' => '', diff --git a/src/Form/Type/CustomHtmlBlockType.php b/src/Form/Type/CustomHtmlBlockType.php index bd657f2..bbdf9da 100644 --- a/src/Form/Type/CustomHtmlBlockType.php +++ b/src/Form/Type/CustomHtmlBlockType.php @@ -12,20 +12,25 @@ use Symfony\Component\Form\Extension\Core\Type\NumberType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; +use PrestaShopBundle\Form\Admin\Type\FormattedTextareaType; use PrestaShopBundle\Form\Admin\Type\SwitchType; +use PrestaShopBundle\Form\Admin\Type\TranslatableType; use Symfony\Contracts\Translation\TranslatorInterface; use Websmid\CustomHtml\Config\Config; class CustomHtmlBlockType extends AbstractType { private $translator; + private $locales; private $groupChoiceProvider; public function __construct( TranslatorInterface $translator, + array $locales, ConfigurableFormChoiceProviderInterface $groupChoiceProvider ) { $this->translator = $translator; + $this->locales = $locales; $this->groupChoiceProvider = $groupChoiceProvider; } @@ -43,8 +48,10 @@ class CustomHtmlBlockType extends AbstractType 'choices' => array_flip(Config::BLOCK_TYPES), 'required' => true, ]) - ->add('title', TextType::class, [ + ->add('title', TranslatableType::class, [ + 'type' => TextType::class, 'label' => $this->translator->trans('Title', [], 'Modules.Wscustomhtml.Admin'), + 'locales' => $this->locales, 'required' => true, 'row_attr' => ['class' => 'col-8'], ]) @@ -53,10 +60,11 @@ class CustomHtmlBlockType extends AbstractType 'required' => false, 'row_attr' => ['class' => 'col-3'], ]) - ->add('content', TextareaType::class, [ + ->add('content', TranslatableType::class, [ + 'type' => FormattedTextareaType::class, 'label' => $this->translator->trans('Content', [], 'Modules.Wscustomhtml.Admin'), + 'locales' => $this->locales, 'required' => false, - 'attr' => ['class' => 'autoload_rte'], 'row_attr' => ['class' => 'customhtmlblock-type-field customhtmlblock-type-html'], ]) ->add('image', FileType::class, [ @@ -129,26 +137,34 @@ class CustomHtmlBlockType extends AbstractType 'help' => $this->translator->trans('0 means the alert never auto-dismisses; visitors can still close it manually.', [], 'Modules.Wscustomhtml.Admin'), 'row_attr' => ['class' => 'customhtmlblock-type-field customhtmlblock-type-alert'], ]) - ->add('description', TextareaType::class, [ + ->add('description', TranslatableType::class, [ + 'type' => TextareaType::class, 'label' => $this->translator->trans('Description', [], 'Modules.Wscustomhtml.Admin'), + 'locales' => $this->locales, 'required' => false, 'row_attr' => ['class' => 'customhtmlblock-type-field customhtmlblock-type-banner customhtmlblock-type-alert customhtmlblock-type-usp'], ]) - ->add('extra_description', TextareaType::class, [ + ->add('extra_description', TranslatableType::class, [ + 'type' => TextareaType::class, 'label' => $this->translator->trans('Extra description', [], 'Modules.Wscustomhtml.Admin'), + 'locales' => $this->locales, 'required' => false, 'row_attr' => ['class' => 'customhtmlblock-type-field customhtmlblock-type-banner'], ]) - ->add('link', TextType::class, [ + ->add('link', TranslatableType::class, [ + 'type' => TextType::class, 'label' => $this->translator->trans('Link URL', [], 'Modules.Wscustomhtml.Admin'), + 'locales' => $this->locales, 'required' => false, - 'attr' => ['placeholder' => 'https://example.com or /internal-page'], - 'row_attr' => ['class' => 'customhtmlblock-type-field customhtmlblock-type-banner customhtmlblock-type-usp customhtmlblock-type-alert col-6'], + 'options' => ['attr' => ['placeholder' => 'https://example.com or /internal-page']], + 'row_attr' => ['class' => 'customhtmlblock-type-field customhtmlblock-type-banner customhtmlblock-type-usp customhtmlblock-type-alert'], ]) - ->add('link_text', TextType::class, [ + ->add('link_text', TranslatableType::class, [ + 'type' => TextType::class, 'label' => $this->translator->trans('Link text', [], 'Modules.Wscustomhtml.Admin'), + 'locales' => $this->locales, 'required' => false, - 'attr' => ['placeholder' => 'Learn more'], + 'options' => ['attr' => ['placeholder' => 'Learn more']], 'row_attr' => ['class' => 'customhtmlblock-type-field customhtmlblock-type-alert col-6'], ]) ->add('custom_class', TextType::class, [ diff --git a/src/Form/Type/CustomHtmlGroupType.php b/src/Form/Type/CustomHtmlGroupType.php index 08ee1a3..1d073a3 100644 --- a/src/Form/Type/CustomHtmlGroupType.php +++ b/src/Form/Type/CustomHtmlGroupType.php @@ -6,22 +6,27 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Core\Type\TextType; use PrestaShopBundle\Form\Admin\Type\SwitchType; +use PrestaShopBundle\Form\Admin\Type\TranslatableType; use Symfony\Contracts\Translation\TranslatorInterface; class CustomHtmlGroupType extends AbstractType { private $translator; + private $locales; - public function __construct(TranslatorInterface $translator) + public function __construct(TranslatorInterface $translator, array $locales) { $this->translator = $translator; + $this->locales = $locales; } public function buildForm(FormBuilderInterface $formBuilder, array $options): void { $formBuilder - ->add('title', TextType::class, [ + ->add('title', TranslatableType::class, [ + 'type' => TextType::class, 'label' => $this->translator->trans('Title', [], 'Modules.Wscustomhtml.Admin'), + 'locales' => $this->locales, 'required' => true, ]) ->add('hook_name', TextType::class, [ diff --git a/src/Grid/Query/CustomHtmlBlockQueryBuilder.php b/src/Grid/Query/CustomHtmlBlockQueryBuilder.php index 371470f..fb6825a 100644 --- a/src/Grid/Query/CustomHtmlBlockQueryBuilder.php +++ b/src/Grid/Query/CustomHtmlBlockQueryBuilder.php @@ -11,6 +11,8 @@ use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; final class CustomHtmlBlockQueryBuilder extends AbstractDoctrineQueryBuilder { + private $contextLanguageId; + public function __construct( Connection $connection, string $dbPrefix, @@ -22,6 +24,8 @@ final class CustomHtmlBlockQueryBuilder extends AbstractDoctrineQueryBuilder Configuration $configuration ) { parent::__construct($connection, $dbPrefix); + + $this->contextLanguageId = $contextLanguageId; } public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) @@ -31,8 +35,8 @@ final class CustomHtmlBlockQueryBuilder extends AbstractDoctrineQueryBuilder $qb->select( 'wchb.`id_ws_customhtml`', 'wchb.`id_ws_customhtml_group`', - 'wchb.`title`', - 'wchg.`title` AS group_title', + 'wchbl.`title`', + 'wchgl.`title` AS group_title', 'wchb.`type`', 'wchb.`active`', 'wchb.`ordering`', @@ -71,6 +75,18 @@ final class CustomHtmlBlockQueryBuilder extends AbstractDoctrineQueryBuilder $this->dbPrefix . 'ws_customhtml_group', 'wchg', 'wchg.`id_ws_customhtml_group` = wchb.`id_ws_customhtml_group`' + ) + ->leftJoin( + 'wchb', + $this->dbPrefix . 'ws_customhtml_group_lang', + 'wchgl', + 'wchgl.`id_ws_customhtml_group` = wchb.`id_ws_customhtml_group` AND wchgl.`id_lang` = ' . (int) $this->contextLanguageId + ) + ->leftJoin( + 'wchb', + $this->dbPrefix . 'ws_customhtml_lang', + 'wchbl', + 'wchbl.`id_ws_customhtml` = wchb.`id_ws_customhtml` AND wchbl.`id_lang` = ' . (int) $this->contextLanguageId ); } @@ -93,8 +109,14 @@ final class CustomHtmlBlockQueryBuilder extends AbstractDoctrineQueryBuilder continue; } + if ($filterName === 'title') { + $qb->andWhere('wchbl.`title` LIKE :title') + ->setParameter('title', '%' . pSQL($filterValue) . '%'); + continue; + } + if ($filterName === 'group_title') { - $qb->andWhere('wchg.`title` LIKE :group_title') + $qb->andWhere('wchgl.`title` LIKE :group_title') ->setParameter('group_title', '%' . pSQL($filterValue) . '%'); continue; } diff --git a/src/Grid/Query/CustomHtmlGroupQueryBuilder.php b/src/Grid/Query/CustomHtmlGroupQueryBuilder.php index 8f59875..4315245 100644 --- a/src/Grid/Query/CustomHtmlGroupQueryBuilder.php +++ b/src/Grid/Query/CustomHtmlGroupQueryBuilder.php @@ -11,6 +11,8 @@ use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; final class CustomHtmlGroupQueryBuilder extends AbstractDoctrineQueryBuilder { + private $contextLanguageId; + public function __construct( Connection $connection, string $dbPrefix, @@ -22,6 +24,8 @@ final class CustomHtmlGroupQueryBuilder extends AbstractDoctrineQueryBuilder Configuration $configuration ) { parent::__construct($connection, $dbPrefix); + + $this->contextLanguageId = $contextLanguageId; } public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) @@ -30,7 +34,7 @@ final class CustomHtmlGroupQueryBuilder extends AbstractDoctrineQueryBuilder $qb->select( 'wchg.`id_ws_customhtml_group`', - 'wchg.`title`', + 'wchgl.`title`', 'wchg.`hook_name`', 'wchg.`custom_class`', 'wchg.`active`', @@ -66,7 +70,13 @@ final class CustomHtmlGroupQueryBuilder extends AbstractDoctrineQueryBuilder { return $this->connection ->createQueryBuilder() - ->from($this->dbPrefix . 'ws_customhtml_group', 'wchg'); + ->from($this->dbPrefix . 'ws_customhtml_group', 'wchg') + ->leftJoin( + 'wchg', + $this->dbPrefix . 'ws_customhtml_group_lang', + 'wchgl', + 'wchgl.`id_ws_customhtml_group` = wchg.`id_ws_customhtml_group` AND wchgl.`id_lang` = ' . (int) $this->contextLanguageId + ); } private function applyFilters($qb, SearchCriteriaInterface $searchCriteria): void @@ -82,6 +92,12 @@ final class CustomHtmlGroupQueryBuilder extends AbstractDoctrineQueryBuilder continue; } + if ($filterName === 'title') { + $qb->andWhere('wchgl.`title` LIKE :title') + ->setParameter('title', '%' . pSQL($filterValue) . '%'); + continue; + } + $qb->andWhere('wchg.`' . $filterName . '` LIKE :' . $filterName) ->setParameter($filterName, '%' . pSQL($filterValue) . '%'); } diff --git a/src/Model/CustomHtmlBlock.php b/src/Model/CustomHtmlBlock.php index ce3b9dd..dbfae19 100644 --- a/src/Model/CustomHtmlBlock.php +++ b/src/Model/CustomHtmlBlock.php @@ -77,18 +77,19 @@ class CustomHtmlBlock extends ObjectModel public $date_upd; public static $definition = [ - 'table' => 'ws_customhtml', - 'primary' => 'id_ws_customhtml', - 'fields' => [ + 'table' => 'ws_customhtml', + 'primary' => 'id_ws_customhtml', + 'multilang' => true, + 'fields' => [ 'id_ws_customhtml_group' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true], - 'title' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 256], + 'title' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 256, 'lang' => true], 'type' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 32], - 'content' => ['type' => self::TYPE_HTML, 'validate' => 'isCleanHtml'], + 'content' => ['type' => self::TYPE_HTML, 'validate' => 'isCleanHtml', 'lang' => true], 'custom_class' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 128], - 'description' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 1024], - 'extra_description' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 1024], - 'link' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 512], - 'link_text' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 128], + 'description' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 1024, 'lang' => true], + 'extra_description' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 1024, 'lang' => true], + 'link' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 512, 'lang' => true], + 'link_text' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 128, 'lang' => true], 'image' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 255], 'alert_type' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 16], 'timeout' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedInt', 'required' => false], @@ -119,7 +120,7 @@ class CustomHtmlBlock extends ObjectModel return _MODULE_DIR_ . 'ws_customhtml/views/img/banners/' . $filename; } - public static function getActiveByGroupIds(array $groupIds): array + public static function getActiveByGroupIds(array $groupIds, int $idLang): array { $groupIds = array_map('intval', $groupIds); @@ -128,14 +129,16 @@ class CustomHtmlBlock extends ObjectModel } $result = Db::getInstance()->executeS( - 'SELECT `id_ws_customhtml`, `id_ws_customhtml_group`, `title`, `type`, `content`, `custom_class`, - `description`, `extra_description`, `link`, `link_text`, `image`, `alert_type`, `timeout`, - `slider_mode`, `slides_per_view_mobile`, `slides_per_view_tablet`, `slides_per_view_desktop`, `autoplay_delay`, - `active`, `show_title`, `ordering` - FROM `' . _DB_PREFIX_ . 'ws_customhtml` - WHERE `id_ws_customhtml_group` IN (' . implode(',', $groupIds) . ') - AND `active` = 1 - ORDER BY `ordering` ASC' + 'SELECT wch.`id_ws_customhtml`, wch.`id_ws_customhtml_group`, wchl.`title`, wch.`type`, wchl.`content`, wch.`custom_class`, + wchl.`description`, wchl.`extra_description`, wchl.`link`, wchl.`link_text`, wch.`image`, wch.`alert_type`, wch.`timeout`, + wch.`slider_mode`, wch.`slides_per_view_mobile`, wch.`slides_per_view_tablet`, wch.`slides_per_view_desktop`, wch.`autoplay_delay`, + wch.`active`, wch.`show_title`, wch.`ordering` + FROM `' . _DB_PREFIX_ . 'ws_customhtml` wch + LEFT JOIN `' . _DB_PREFIX_ . 'ws_customhtml_lang` wchl + ON wchl.`id_ws_customhtml` = wch.`id_ws_customhtml` AND wchl.`id_lang` = ' . (int) $idLang . ' + WHERE wch.`id_ws_customhtml_group` IN (' . implode(',', $groupIds) . ') + AND wch.`active` = 1 + ORDER BY wch.`ordering` ASC' ); $blocksByGroup = []; diff --git a/src/Model/CustomHtmlGroup.php b/src/Model/CustomHtmlGroup.php index 831d8ed..d9851a6 100644 --- a/src/Model/CustomHtmlGroup.php +++ b/src/Model/CustomHtmlGroup.php @@ -35,11 +35,12 @@ class CustomHtmlGroup extends ObjectModel public $date_upd; public static $definition = [ - 'table' => 'ws_customhtml_group', - 'primary' => 'id_ws_customhtml_group', - 'fields' => [ + 'table' => 'ws_customhtml_group', + 'primary' => 'id_ws_customhtml_group', + 'multilang' => true, + 'fields' => [ 'hook_name' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 64], - 'title' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 256], + 'title' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 256, 'lang' => true], 'custom_class' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 128], 'default_block_class' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 128], 'active' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'], @@ -52,7 +53,7 @@ class CustomHtmlGroup extends ObjectModel public static function getActiveByHookName(string $hookName): array { $result = Db::getInstance()->executeS( - 'SELECT `id_ws_customhtml_group`, `title`, `active`, `custom_class`, `default_block_class`, `ordering` + 'SELECT `id_ws_customhtml_group`, `active`, `custom_class`, `default_block_class`, `ordering` FROM `' . _DB_PREFIX_ . 'ws_customhtml_group` WHERE `hook_name` = \'' . pSQL($hookName) . '\' AND `active` = 1 diff --git a/src/Module/DisplayHooks.php b/src/Module/DisplayHooks.php index 0a82a85..921ae5d 100644 --- a/src/Module/DisplayHooks.php +++ b/src/Module/DisplayHooks.php @@ -49,7 +49,8 @@ trait DisplayHooks public function getWidgetVariables($hookName = null, array $configuration = []) { - $groupList = $this->loadActiveGroupsWithBlocks((string) $hookName); + $idLang = (int) Context::getContext()->language->id; + $groupList = $this->loadActiveGroupsWithBlocks((string) $hookName, $idLang); if (empty($groupList)) { return []; @@ -61,7 +62,7 @@ trait DisplayHooks ]; } - private function loadActiveGroupsWithBlocks(string $hookName): array + private function loadActiveGroupsWithBlocks(string $hookName, int $idLang): array { $groups = CustomHtmlGroup::getActiveByHookName($hookName); @@ -69,7 +70,7 @@ trait DisplayHooks return []; } - $blocksByGroup = CustomHtmlBlock::getActiveByGroupIds(array_column($groups, 'id_ws_customhtml_group')); + $blocksByGroup = CustomHtmlBlock::getActiveByGroupIds(array_column($groups, 'id_ws_customhtml_group'), $idLang); $blocksByGroup = $this->attachFaqsToBlocks($blocksByGroup); $blocksByGroup = $this->attachImageUrls($blocksByGroup); $blocksByGroup = $this->attachSlidesToBlocks($blocksByGroup); diff --git a/src/Module/Install.php b/src/Module/Install.php index 736e8c6..0068ea8 100644 --- a/src/Module/Install.php +++ b/src/Module/Install.php @@ -49,7 +49,6 @@ trait Install CREATE TABLE IF NOT EXISTS ' . _DB_PREFIX_ . 'ws_customhtml_group ( `id_ws_customhtml_group` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `hook_name` VARCHAR(64) NOT NULL, - `title` VARCHAR(256) NOT NULL DEFAULT \'\', `custom_class` VARCHAR(128) NOT NULL DEFAULT \'\', `default_block_class` VARCHAR(128) NOT NULL DEFAULT \'\', `active` TINYINT(1) NOT NULL DEFAULT 1, @@ -59,18 +58,21 @@ trait Install ); '; + $sqlToExec[] = ' + CREATE TABLE IF NOT EXISTS ' . _DB_PREFIX_ . 'ws_customhtml_group_lang ( + `id_ws_customhtml_group` INT(11) NOT NULL, + `id_lang` INT(11) NOT NULL, + `title` VARCHAR(256) NOT NULL DEFAULT \'\', + PRIMARY KEY (`id_ws_customhtml_group`, `id_lang`) + ); + '; + $sqlToExec[] = ' CREATE TABLE IF NOT EXISTS ' . _DB_PREFIX_ . 'ws_customhtml ( `id_ws_customhtml` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `id_ws_customhtml_group` INT(11) NOT NULL, - `title` VARCHAR(256) NOT NULL DEFAULT \'\', `type` VARCHAR(32) NOT NULL DEFAULT \'html\', - `content` LONGTEXT, `custom_class` VARCHAR(128) NOT NULL DEFAULT \'\', - `description` TEXT, - `extra_description` TEXT, - `link` VARCHAR(512) NOT NULL DEFAULT \'\', - `link_text` VARCHAR(128) NOT NULL DEFAULT \'\', `image` VARCHAR(255) NOT NULL DEFAULT \'\', `alert_type` VARCHAR(16) NOT NULL DEFAULT \'info\', `timeout` INT(11) NOT NULL DEFAULT 0, @@ -88,6 +90,20 @@ trait Install ); '; + $sqlToExec[] = ' + CREATE TABLE IF NOT EXISTS ' . _DB_PREFIX_ . 'ws_customhtml_lang ( + `id_ws_customhtml` INT(11) NOT NULL, + `id_lang` INT(11) NOT NULL, + `title` VARCHAR(256) NOT NULL DEFAULT \'\', + `content` LONGTEXT, + `description` TEXT, + `extra_description` TEXT, + `link` VARCHAR(512) NOT NULL DEFAULT \'\', + `link_text` VARCHAR(128) NOT NULL DEFAULT \'\', + PRIMARY KEY (`id_ws_customhtml`, `id_lang`) + ); + '; + $sqlToExec[] = ' CREATE TABLE IF NOT EXISTS ' . _DB_PREFIX_ . 'ws_customhtml_faq ( `id_ws_customhtml_faq` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, diff --git a/upgrade/upgrade-1.20.0.php b/upgrade/upgrade-1.20.0.php new file mode 100644 index 0000000..91fbcff --- /dev/null +++ b/upgrade/upgrade-1.20.0.php @@ -0,0 +1,88 @@ +execute( + 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'ws_customhtml_group_lang` ( + `id_ws_customhtml_group` INT(11) NOT NULL, + `id_lang` INT(11) NOT NULL, + `title` VARCHAR(256) NOT NULL DEFAULT \'\', + PRIMARY KEY (`id_ws_customhtml_group`, `id_lang`) + );' + ); +} + +function migrateGroupTitlesToLangTable(): bool +{ + $groupColumns = Db::getInstance()->executeS( + 'SHOW COLUMNS FROM `' . _DB_PREFIX_ . 'ws_customhtml_group` LIKE \'title\'' + ); + + if (empty($groupColumns)) { + // Already migrated in a previous run of this upgrade. + return true; + } + + $groups = Db::getInstance()->executeS( + 'SELECT `id_ws_customhtml_group`, `title` FROM `' . _DB_PREFIX_ . 'ws_customhtml_group`' + ); + $languages = Language::getLanguages(false); + + foreach ($groups as $group) { + foreach ($languages as $language) { + $existing = Db::getInstance()->executeS( + 'SELECT 1 FROM `' . _DB_PREFIX_ . 'ws_customhtml_group_lang` + WHERE `id_ws_customhtml_group` = ' . (int) $group['id_ws_customhtml_group'] . ' + AND `id_lang` = ' . (int) $language['id_lang'] + ); + + if (!empty($existing)) { + continue; + } + + $result = Db::getInstance()->insert('ws_customhtml_group_lang', [ + 'id_ws_customhtml_group' => (int) $group['id_ws_customhtml_group'], + 'id_lang' => (int) $language['id_lang'], + 'title' => pSQL($group['title']), + ]); + + if (!$result) { + return false; + } + } + } + + return true; +} + +function dropGroupTitleColumn(): bool +{ + $groupColumns = Db::getInstance()->executeS( + 'SHOW COLUMNS FROM `' . _DB_PREFIX_ . 'ws_customhtml_group` LIKE \'title\'' + ); + + if (empty($groupColumns)) { + return true; + } + + return Db::getInstance()->execute( + 'ALTER TABLE `' . _DB_PREFIX_ . 'ws_customhtml_group` DROP COLUMN `title`' + ); +} diff --git a/upgrade/upgrade-1.21.0.php b/upgrade/upgrade-1.21.0.php new file mode 100644 index 0000000..900b057 --- /dev/null +++ b/upgrade/upgrade-1.21.0.php @@ -0,0 +1,102 @@ +execute( + 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'ws_customhtml_lang` ( + `id_ws_customhtml` INT(11) NOT NULL, + `id_lang` INT(11) NOT NULL, + `title` VARCHAR(256) NOT NULL DEFAULT \'\', + `content` LONGTEXT, + `description` TEXT, + `extra_description` TEXT, + `link_text` VARCHAR(128) NOT NULL DEFAULT \'\', + PRIMARY KEY (`id_ws_customhtml`, `id_lang`) + );' + ); +} + +function migrateBlockFieldsToLangTable(): bool +{ + $columns = Db::getInstance()->executeS( + 'SHOW COLUMNS FROM `' . _DB_PREFIX_ . 'ws_customhtml` LIKE \'title\'' + ); + + if (empty($columns)) { + // Already migrated in a previous run of this upgrade. + return true; + } + + $blocks = Db::getInstance()->executeS( + 'SELECT `id_ws_customhtml`, `title`, `content`, `description`, `extra_description`, `link_text` + FROM `' . _DB_PREFIX_ . 'ws_customhtml`' + ); + $languages = Language::getLanguages(false); + + foreach ($blocks as $block) { + foreach ($languages as $language) { + $existing = Db::getInstance()->executeS( + 'SELECT 1 FROM `' . _DB_PREFIX_ . 'ws_customhtml_lang` + WHERE `id_ws_customhtml` = ' . (int) $block['id_ws_customhtml'] . ' + AND `id_lang` = ' . (int) $language['id_lang'] + ); + + if (!empty($existing)) { + continue; + } + + $result = Db::getInstance()->insert('ws_customhtml_lang', [ + 'id_ws_customhtml' => (int) $block['id_ws_customhtml'], + 'id_lang' => (int) $language['id_lang'], + 'title' => pSQL($block['title']), + 'content' => pSQL($block['content'], true), + 'description' => pSQL($block['description']), + 'extra_description' => pSQL($block['extra_description']), + 'link_text' => pSQL($block['link_text']), + ]); + + if (!$result) { + return false; + } + } + } + + return true; +} + +function dropBlockLangColumns(): bool +{ + $columns = Db::getInstance()->executeS( + 'SHOW COLUMNS FROM `' . _DB_PREFIX_ . 'ws_customhtml` LIKE \'title\'' + ); + + if (empty($columns)) { + return true; + } + + return Db::getInstance()->execute( + 'ALTER TABLE `' . _DB_PREFIX_ . 'ws_customhtml` + DROP COLUMN `title`, + DROP COLUMN `content`, + DROP COLUMN `description`, + DROP COLUMN `extra_description`, + DROP COLUMN `link_text`' + ); +} diff --git a/upgrade/upgrade-1.22.0.php b/upgrade/upgrade-1.22.0.php new file mode 100644 index 0000000..e61832e --- /dev/null +++ b/upgrade/upgrade-1.22.0.php @@ -0,0 +1,79 @@ +executeS( + 'SHOW COLUMNS FROM `' . _DB_PREFIX_ . 'ws_customhtml_lang` LIKE \'link\'' + ); + + if (!empty($existing)) { + return true; + } + + return Db::getInstance()->execute( + 'ALTER TABLE `' . _DB_PREFIX_ . 'ws_customhtml_lang` + ADD COLUMN `link` VARCHAR(512) NOT NULL DEFAULT \'\' AFTER `extra_description`' + ); +} + +function migrateBlockLinkToLangTable(): bool +{ + $columns = Db::getInstance()->executeS( + 'SHOW COLUMNS FROM `' . _DB_PREFIX_ . 'ws_customhtml` LIKE \'link\'' + ); + + if (empty($columns)) { + // Already migrated in a previous run of this upgrade. + return true; + } + + $blocks = Db::getInstance()->executeS( + 'SELECT `id_ws_customhtml`, `link` FROM `' . _DB_PREFIX_ . 'ws_customhtml`' + ); + + foreach ($blocks as $block) { + $result = Db::getInstance()->update( + 'ws_customhtml_lang', + ['link' => pSQL($block['link'])], + '`id_ws_customhtml` = ' . (int) $block['id_ws_customhtml'] + ); + + if (!$result) { + return false; + } + } + + return true; +} + +function dropBlockLinkColumn(): bool +{ + $columns = Db::getInstance()->executeS( + 'SHOW COLUMNS FROM `' . _DB_PREFIX_ . 'ws_customhtml` LIKE \'link\'' + ); + + if (empty($columns)) { + return true; + } + + return Db::getInstance()->execute( + 'ALTER TABLE `' . _DB_PREFIX_ . 'ws_customhtml` DROP COLUMN `link`' + ); +} diff --git a/views/js/admin/customhtmlblock_form.js b/views/js/admin/customhtmlblock_form.js index 6a4d428..8beb283 100644 --- a/views/js/admin/customhtmlblock_form.js +++ b/views/js/admin/customhtmlblock_form.js @@ -1,6 +1,8 @@ $(document).ready(function () { window.prestashop.component.initComponents([ 'TinyMCEEditor', + 'TranslatableField', + 'TranslatableInput', ]); function toggleBlockTypeFields() { diff --git a/views/js/admin/customhtmlgroup_form.js b/views/js/admin/customhtmlgroup_form.js new file mode 100644 index 0000000..ecfc7c3 --- /dev/null +++ b/views/js/admin/customhtmlgroup_form.js @@ -0,0 +1,6 @@ +$(document).ready(function () { + window.prestashop.component.initComponents([ + 'TranslatableField', + 'TranslatableInput', + ]); +}); diff --git a/views/templates/admin/form/blocks/block_form.html.twig b/views/templates/admin/form/blocks/block_form.html.twig index 490d092..46e2d19 100644 --- a/views/templates/admin/form/blocks/block_form.html.twig +++ b/views/templates/admin/form/blocks/block_form.html.twig @@ -109,10 +109,8 @@ {{ form_row(customHtmlBlockForm.timeout) }} {{ form_row(customHtmlBlockForm.description) }} {{ form_row(customHtmlBlockForm.extra_description) }} -
+{% endblock %} diff --git a/views/templates/admin/form/customhtmlgroup_edit.html.twig b/views/templates/admin/form/customhtmlgroup_edit.html.twig index 891ca22..8f27b91 100644 --- a/views/templates/admin/form/customhtmlgroup_edit.html.twig +++ b/views/templates/admin/form/customhtmlgroup_edit.html.twig @@ -5,3 +5,8 @@ {% include '@Modules/ws_customhtml/views/templates/admin/form/blocks/group_form.html.twig' %} {% endblock %} {% endblock %} + +{% block javascripts %} + {{ parent() }} + +{% endblock %} diff --git a/ws_customhtml.php b/ws_customhtml.php index a7c8a86..ccd2c4d 100644 --- a/ws_customhtml.php +++ b/ws_customhtml.php @@ -29,7 +29,7 @@ class Ws_CustomHtml extends Module implements WidgetInterface public function __construct() { $this->name = 'ws_customhtml'; - $this->version = '1.19.0'; + $this->version = '1.22.0'; $this->author = 'Isabelle Oving-Anno | De Websmid BV'; $this->need_instance = 0; $this->bootstrap = true;