From 4e7333493a1a8c65db4f8b2b43b49b764d9ce900 Mon Sep 17 00:00:00 2001 From: Isabelle Date: Wed, 9 Sep 2026 13:17:58 +0200 Subject: [PATCH] feat(main): Make FAQ and slide entities translatable --- config/form.yml | 6 +- .../CustomHtmlBlockDataHandler.php | 20 ++-- src/Form/Type/CustomHtmlFaqType.php | 13 ++- src/Form/Type/CustomHtmlSlideType.php | 29 +++-- src/Model/CustomHtmlFaq.php | 45 ++++++-- src/Model/CustomHtmlSlide.php | 56 ++++++++-- src/Module/DisplayHooks.php | 24 ++--- src/Module/Install.php | 30 ++++-- upgrade/upgrade-1.23.0.php | 102 ++++++++++++++++++ upgrade/upgrade-1.24.0.php | 93 ++++++++++++++++ ws_customhtml.php | 2 +- 11 files changed, 358 insertions(+), 62 deletions(-) create mode 100644 upgrade/upgrade-1.23.0.php create mode 100644 upgrade/upgrade-1.24.0.php diff --git a/config/form.yml b/config/form.yml index 031f3ca..e813247 100644 --- a/config/form.yml +++ b/config/form.yml @@ -36,16 +36,14 @@ services: websmid.customhtml.form.type.customhtml_faq: public: true class: 'Websmid\CustomHtml\Form\Type\CustomHtmlFaqType' - arguments: - - '@translator' + parent: "form.type.translatable.aware" tags: - { name: form.type } websmid.customhtml.form.type.customhtml_slide: public: true class: 'Websmid\CustomHtml\Form\Type\CustomHtmlSlideType' - arguments: - - '@translator' + parent: "form.type.translatable.aware" tags: - { name: form.type } diff --git a/src/Form/DataHandler/CustomHtmlBlockDataHandler.php b/src/Form/DataHandler/CustomHtmlBlockDataHandler.php index dcae45f..fc97efc 100644 --- a/src/Form/DataHandler/CustomHtmlBlockDataHandler.php +++ b/src/Form/DataHandler/CustomHtmlBlockDataHandler.php @@ -146,14 +146,18 @@ final class CustomHtmlBlockDataHandler implements FormDataHandlerInterface CustomHtmlFaq::deleteByBlockId($idBlock); foreach (array_values($faqs) as $position => $faqData) { - if (empty($faqData['question'])) { + $question = $faqData['question'] ?? []; + + if (empty(array_filter($question, static function ($value) { + return trim((string) $value) !== ''; + }))) { continue; } $faq = new CustomHtmlFaq(); $faq->id_ws_customhtml = $idBlock; - $faq->question = (string) $faqData['question']; - $faq->answer = (string) ($faqData['answer'] ?? ''); + $faq->question = $question; + $faq->answer = $faqData['answer'] ?? []; $faq->ordering = $position; $faq->add(); } @@ -181,11 +185,11 @@ final class CustomHtmlBlockDataHandler implements FormDataHandlerInterface $slide = new CustomHtmlSlide(); $slide->id_ws_customhtml = $idBlock; - $slide->title = (string) ($slideData['title'] ?? ''); - $slide->description = (string) ($slideData['description'] ?? ''); - $slide->extra_description = (string) ($slideData['extra_description'] ?? ''); - $slide->link = (string) ($slideData['link'] ?? ''); - $slide->link_text = (string) ($slideData['link_text'] ?? ''); + $slide->title = $slideData['title'] ?? []; + $slide->description = $slideData['description'] ?? []; + $slide->extra_description = $slideData['extra_description'] ?? []; + $slide->link = $slideData['link'] ?? []; + $slide->link_text = $slideData['link_text'] ?? []; $slide->image = $this->saveUploadedImage($slideData['image'] ?? null, $existingImage); $slide->ordering = $position; $slide->add(); diff --git a/src/Form/Type/CustomHtmlFaqType.php b/src/Form/Type/CustomHtmlFaqType.php index bd952f9..a249a64 100644 --- a/src/Form/Type/CustomHtmlFaqType.php +++ b/src/Form/Type/CustomHtmlFaqType.php @@ -6,26 +6,33 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; +use PrestaShopBundle\Form\Admin\Type\TranslatableType; use Symfony\Contracts\Translation\TranslatorInterface; class CustomHtmlFaqType 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('question', TextType::class, [ + ->add('question', TranslatableType::class, [ + 'type' => TextType::class, 'label' => $this->translator->trans('Question', [], 'Modules.Wscustomhtml.Admin'), + 'locales' => $this->locales, 'required' => false, ]) - ->add('answer', TextareaType::class, [ + ->add('answer', TranslatableType::class, [ + 'type' => TextareaType::class, 'label' => $this->translator->trans('Answer', [], 'Modules.Wscustomhtml.Admin'), + 'locales' => $this->locales, 'required' => false, ]); } diff --git a/src/Form/Type/CustomHtmlSlideType.php b/src/Form/Type/CustomHtmlSlideType.php index d0763c3..7ad4e05 100644 --- a/src/Form/Type/CustomHtmlSlideType.php +++ b/src/Form/Type/CustomHtmlSlideType.php @@ -8,15 +8,18 @@ use Symfony\Component\Form\Extension\Core\Type\FileType; use Symfony\Component\Form\Extension\Core\Type\HiddenType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; +use PrestaShopBundle\Form\Admin\Type\TranslatableType; use Symfony\Contracts\Translation\TranslatorInterface; class CustomHtmlSlideType 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 @@ -25,27 +28,37 @@ class CustomHtmlSlideType extends AbstractType ->add('id', HiddenType::class, [ 'required' => false, ]) - ->add('title', TextType::class, [ + ->add('title', TranslatableType::class, [ + 'type' => TextType::class, 'label' => $this->translator->trans('Title', [], 'Modules.Wscustomhtml.Admin'), + 'locales' => $this->locales, 'required' => false, ]) - ->add('description', TextareaType::class, [ + ->add('description', TranslatableType::class, [ + 'type' => TextareaType::class, 'label' => $this->translator->trans('Description', [], 'Modules.Wscustomhtml.Admin'), + 'locales' => $this->locales, 'required' => false, ]) - ->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, ]) - ->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'], + 'options' => ['attr' => ['placeholder' => 'https://example.com or /internal-page']], ]) - ->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']], ]) ->add('image', FileType::class, [ 'label' => $this->translator->trans('Image', [], 'Modules.Wscustomhtml.Admin'), diff --git a/src/Model/CustomHtmlFaq.php b/src/Model/CustomHtmlFaq.php index fd4a30b..2fe281d 100644 --- a/src/Model/CustomHtmlFaq.php +++ b/src/Model/CustomHtmlFaq.php @@ -29,27 +29,56 @@ class CustomHtmlFaq extends ObjectModel public $date_upd; public static $definition = [ - 'table' => 'ws_customhtml_faq', - 'primary' => 'id_ws_customhtml_faq', - 'fields' => [ + 'table' => 'ws_customhtml_faq', + 'primary' => 'id_ws_customhtml_faq', + 'multilang' => true, + 'fields' => [ 'id_ws_customhtml' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true], - 'question' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 512], - 'answer' => ['type' => self::TYPE_HTML, 'validate' => 'isCleanHtml'], + 'question' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 512, 'lang' => true], + 'answer' => ['type' => self::TYPE_HTML, 'validate' => 'isCleanHtml', 'lang' => true], 'ordering' => ['type' => self::TYPE_INT, 'validate' => 'isInt'], 'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'], 'date_upd' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'], ], ]; + /** + * Admin use — loads every language into lang fields as [id_lang => value] arrays. + */ public static function getByBlockId(int $idBlock): array { - $result = Db::getInstance()->executeS( - 'SELECT `id_ws_customhtml_faq`, `question`, `answer`, `ordering` - FROM `' . _DB_PREFIX_ . 'ws_customhtml_faq` + $ids = Db::getInstance()->executeS( + 'SELECT `id_ws_customhtml_faq` FROM `' . _DB_PREFIX_ . 'ws_customhtml_faq` WHERE `id_ws_customhtml` = ' . (int) $idBlock . ' ORDER BY `ordering` ASC' ); + return array_map(static function (array $row) { + $faq = new self((int) $row['id_ws_customhtml_faq']); + + return [ + 'id_ws_customhtml_faq' => (int) $faq->id, + 'question' => $faq->question, + 'answer' => $faq->answer, + 'ordering' => (int) $faq->ordering, + ]; + }, $ids ?: []); + } + + /** + * Front-end use — resolves lang fields to plain strings for one language. + */ + public static function getByBlockIdForLang(int $idBlock, int $idLang): array + { + $result = Db::getInstance()->executeS( + 'SELECT wcf.`id_ws_customhtml_faq`, wcfl.`question`, wcfl.`answer`, wcf.`ordering` + FROM `' . _DB_PREFIX_ . 'ws_customhtml_faq` wcf + LEFT JOIN `' . _DB_PREFIX_ . 'ws_customhtml_faq_lang` wcfl + ON wcfl.`id_ws_customhtml_faq` = wcf.`id_ws_customhtml_faq` AND wcfl.`id_lang` = ' . (int) $idLang . ' + WHERE wcf.`id_ws_customhtml` = ' . (int) $idBlock . ' + ORDER BY wcf.`ordering` ASC' + ); + return $result ?: []; } diff --git a/src/Model/CustomHtmlSlide.php b/src/Model/CustomHtmlSlide.php index e7f32e0..a1a6571 100644 --- a/src/Model/CustomHtmlSlide.php +++ b/src/Model/CustomHtmlSlide.php @@ -41,15 +41,16 @@ class CustomHtmlSlide extends ObjectModel public $date_upd; public static $definition = [ - 'table' => 'ws_customhtml_slide', - 'primary' => 'id_ws_customhtml_slide', - 'fields' => [ + 'table' => 'ws_customhtml_slide', + 'primary' => 'id_ws_customhtml_slide', + 'multilang' => true, + 'fields' => [ 'id_ws_customhtml' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true], - 'title' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 256], - '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], + 'title' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 256, 'lang' => true], + '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], 'ordering' => ['type' => self::TYPE_INT, 'validate' => 'isInt'], 'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'], @@ -57,15 +58,48 @@ class CustomHtmlSlide extends ObjectModel ], ]; + /** + * Admin use — loads every language into lang fields as [id_lang => value] arrays. + */ public static function getByBlockId(int $idBlock): array { - $result = Db::getInstance()->executeS( - 'SELECT `id_ws_customhtml_slide`, `title`, `description`, `extra_description`, `link`, `link_text`, `image`, `ordering` - FROM `' . _DB_PREFIX_ . 'ws_customhtml_slide` + $ids = Db::getInstance()->executeS( + 'SELECT `id_ws_customhtml_slide` FROM `' . _DB_PREFIX_ . 'ws_customhtml_slide` WHERE `id_ws_customhtml` = ' . (int) $idBlock . ' ORDER BY `ordering` ASC' ); + return array_map(static function (array $row) { + $slide = new self((int) $row['id_ws_customhtml_slide']); + + return [ + 'id_ws_customhtml_slide' => (int) $slide->id, + 'title' => $slide->title, + 'description' => $slide->description, + 'extra_description' => $slide->extra_description, + 'link' => $slide->link, + 'link_text' => $slide->link_text, + 'image' => $slide->image, + 'ordering' => (int) $slide->ordering, + ]; + }, $ids ?: []); + } + + /** + * Front-end use — resolves lang fields to plain strings for one language. + */ + public static function getByBlockIdForLang(int $idBlock, int $idLang): array + { + $result = Db::getInstance()->executeS( + 'SELECT wcs.`id_ws_customhtml_slide`, wcsl.`title`, wcsl.`description`, wcsl.`extra_description`, + wcsl.`link`, wcsl.`link_text`, wcs.`image`, wcs.`ordering` + FROM `' . _DB_PREFIX_ . 'ws_customhtml_slide` wcs + LEFT JOIN `' . _DB_PREFIX_ . 'ws_customhtml_slide_lang` wcsl + ON wcsl.`id_ws_customhtml_slide` = wcs.`id_ws_customhtml_slide` AND wcsl.`id_lang` = ' . (int) $idLang . ' + WHERE wcs.`id_ws_customhtml` = ' . (int) $idBlock . ' + ORDER BY wcs.`ordering` ASC' + ); + return $result ?: []; } diff --git a/src/Module/DisplayHooks.php b/src/Module/DisplayHooks.php index 921ae5d..a183163 100644 --- a/src/Module/DisplayHooks.php +++ b/src/Module/DisplayHooks.php @@ -71,9 +71,9 @@ trait DisplayHooks } $blocksByGroup = CustomHtmlBlock::getActiveByGroupIds(array_column($groups, 'id_ws_customhtml_group'), $idLang); - $blocksByGroup = $this->attachFaqsToBlocks($blocksByGroup); + $blocksByGroup = $this->attachFaqsToBlocks($blocksByGroup, $idLang); $blocksByGroup = $this->attachImageUrls($blocksByGroup); - $blocksByGroup = $this->attachSlidesToBlocks($blocksByGroup); + $blocksByGroup = $this->attachSlidesToBlocks($blocksByGroup, $idLang); $groups = array_map(static function (array $group) use ($blocksByGroup) { $group['blocks'] = $blocksByGroup[(int) $group['id_ws_customhtml_group']] ?? []; @@ -86,12 +86,12 @@ trait DisplayHooks })); } - private function attachFaqsToBlocks(array $blocksByGroup): array + private function attachFaqsToBlocks(array $blocksByGroup, int $idLang): array { - return array_map(static function (array $blocks) { - return array_map(static function (array $block) { + return array_map(static function (array $blocks) use ($idLang) { + return array_map(static function (array $block) use ($idLang) { if ($block['type'] === 'faq') { - $block['faqs'] = CustomHtmlFaq::getByBlockId((int) $block['id_ws_customhtml']); + $block['faqs'] = CustomHtmlFaq::getByBlockIdForLang((int) $block['id_ws_customhtml'], $idLang); } return $block; @@ -112,12 +112,12 @@ trait DisplayHooks }, $blocksByGroup); } - private function attachSlidesToBlocks(array $blocksByGroup): array + private function attachSlidesToBlocks(array $blocksByGroup, int $idLang): array { - return array_map(function (array $blocks) { - return array_map(function (array $block) { + return array_map(function (array $blocks) use ($idLang) { + return array_map(function (array $block) use ($idLang) { if ($block['type'] === 'slider') { - $block['slides'] = $this->loadSlidesForBlock((int) $block['id_ws_customhtml']); + $block['slides'] = $this->loadSlidesForBlock((int) $block['id_ws_customhtml'], $idLang); $block['slider_config'] = $this->buildSliderConfig($block); $block['slider_desktop_column_width'] = $this->buildSliderDesktopColumnWidth($block); } @@ -127,14 +127,14 @@ trait DisplayHooks }, $blocksByGroup); } - private function loadSlidesForBlock(int $idBlock): array + private function loadSlidesForBlock(int $idBlock, int $idLang): array { return array_map(static function (array $slide) { $slide['image_url'] = CustomHtmlBlock::getBannerImageUrl($slide['image']); $slide['show_title'] = true; return $slide; - }, CustomHtmlSlide::getByBlockId($idBlock)); + }, CustomHtmlSlide::getByBlockIdForLang($idBlock, $idLang)); } private function buildSliderConfig(array $block): string diff --git a/src/Module/Install.php b/src/Module/Install.php index 0068ea8..0f85511 100644 --- a/src/Module/Install.php +++ b/src/Module/Install.php @@ -108,8 +108,6 @@ trait Install CREATE TABLE IF NOT EXISTS ' . _DB_PREFIX_ . 'ws_customhtml_faq ( `id_ws_customhtml_faq` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `id_ws_customhtml` INT(11) NOT NULL, - `question` VARCHAR(512) NOT NULL DEFAULT \'\', - `answer` TEXT, `ordering` INT(11) NOT NULL DEFAULT 0, `date_add` DATETIME NOT NULL, `date_upd` DATETIME NOT NULL, @@ -117,15 +115,20 @@ trait Install ); '; + $sqlToExec[] = ' + CREATE TABLE IF NOT EXISTS ' . _DB_PREFIX_ . 'ws_customhtml_faq_lang ( + `id_ws_customhtml_faq` INT(11) NOT NULL, + `id_lang` INT(11) NOT NULL, + `question` VARCHAR(512) NOT NULL DEFAULT \'\', + `answer` TEXT, + PRIMARY KEY (`id_ws_customhtml_faq`, `id_lang`) + ); + '; + $sqlToExec[] = ' CREATE TABLE IF NOT EXISTS ' . _DB_PREFIX_ . 'ws_customhtml_slide ( `id_ws_customhtml_slide` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `id_ws_customhtml` INT(11) NOT NULL, - `title` VARCHAR(256) 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 \'\', `ordering` INT(11) NOT NULL DEFAULT 0, `date_add` DATETIME NOT NULL, @@ -134,6 +137,19 @@ trait Install ); '; + $sqlToExec[] = ' + CREATE TABLE IF NOT EXISTS ' . _DB_PREFIX_ . 'ws_customhtml_slide_lang ( + `id_ws_customhtml_slide` INT(11) NOT NULL, + `id_lang` INT(11) NOT NULL, + `title` VARCHAR(256) NOT NULL DEFAULT \'\', + `description` TEXT, + `extra_description` TEXT, + `link` VARCHAR(512) NOT NULL DEFAULT \'\', + `link_text` VARCHAR(128) NOT NULL DEFAULT \'\', + PRIMARY KEY (`id_ws_customhtml_slide`, `id_lang`) + ); + '; + foreach ($sqlToExec as $sqlBlock) { Db::getInstance()->execute(trim($sqlBlock)); } diff --git a/upgrade/upgrade-1.23.0.php b/upgrade/upgrade-1.23.0.php new file mode 100644 index 0000000..f247d59 --- /dev/null +++ b/upgrade/upgrade-1.23.0.php @@ -0,0 +1,102 @@ +execute( + 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'ws_customhtml_slide_lang` ( + `id_ws_customhtml_slide` INT(11) NOT NULL, + `id_lang` INT(11) NOT NULL, + `title` VARCHAR(256) NOT NULL DEFAULT \'\', + `description` TEXT, + `extra_description` TEXT, + `link` VARCHAR(512) NOT NULL DEFAULT \'\', + `link_text` VARCHAR(128) NOT NULL DEFAULT \'\', + PRIMARY KEY (`id_ws_customhtml_slide`, `id_lang`) + );' + ); +} + +function migrateSlideFieldsToLangTable(): bool +{ + $columns = Db::getInstance()->executeS( + 'SHOW COLUMNS FROM `' . _DB_PREFIX_ . 'ws_customhtml_slide` LIKE \'title\'' + ); + + if (empty($columns)) { + // Already migrated in a previous run of this upgrade. + return true; + } + + $slides = Db::getInstance()->executeS( + 'SELECT `id_ws_customhtml_slide`, `title`, `description`, `extra_description`, `link`, `link_text` + FROM `' . _DB_PREFIX_ . 'ws_customhtml_slide`' + ); + $languages = Language::getLanguages(false); + + foreach ($slides as $slide) { + foreach ($languages as $language) { + $existing = Db::getInstance()->executeS( + 'SELECT 1 FROM `' . _DB_PREFIX_ . 'ws_customhtml_slide_lang` + WHERE `id_ws_customhtml_slide` = ' . (int) $slide['id_ws_customhtml_slide'] . ' + AND `id_lang` = ' . (int) $language['id_lang'] + ); + + if (!empty($existing)) { + continue; + } + + $result = Db::getInstance()->insert('ws_customhtml_slide_lang', [ + 'id_ws_customhtml_slide' => (int) $slide['id_ws_customhtml_slide'], + 'id_lang' => (int) $language['id_lang'], + 'title' => pSQL($slide['title']), + 'description' => pSQL($slide['description']), + 'extra_description' => pSQL($slide['extra_description']), + 'link' => pSQL($slide['link']), + 'link_text' => pSQL($slide['link_text']), + ]); + + if (!$result) { + return false; + } + } + } + + return true; +} + +function dropSlideLangColumns(): bool +{ + $columns = Db::getInstance()->executeS( + 'SHOW COLUMNS FROM `' . _DB_PREFIX_ . 'ws_customhtml_slide` LIKE \'title\'' + ); + + if (empty($columns)) { + return true; + } + + return Db::getInstance()->execute( + 'ALTER TABLE `' . _DB_PREFIX_ . 'ws_customhtml_slide` + DROP COLUMN `title`, + DROP COLUMN `description`, + DROP COLUMN `extra_description`, + DROP COLUMN `link`, + DROP COLUMN `link_text`' + ); +} diff --git a/upgrade/upgrade-1.24.0.php b/upgrade/upgrade-1.24.0.php new file mode 100644 index 0000000..6ca3600 --- /dev/null +++ b/upgrade/upgrade-1.24.0.php @@ -0,0 +1,93 @@ +execute( + 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'ws_customhtml_faq_lang` ( + `id_ws_customhtml_faq` INT(11) NOT NULL, + `id_lang` INT(11) NOT NULL, + `question` VARCHAR(512) NOT NULL DEFAULT \'\', + `answer` TEXT, + PRIMARY KEY (`id_ws_customhtml_faq`, `id_lang`) + );' + ); +} + +function migrateFaqFieldsToLangTable(): bool +{ + $columns = Db::getInstance()->executeS( + 'SHOW COLUMNS FROM `' . _DB_PREFIX_ . 'ws_customhtml_faq` LIKE \'question\'' + ); + + if (empty($columns)) { + // Already migrated in a previous run of this upgrade. + return true; + } + + $faqs = Db::getInstance()->executeS( + 'SELECT `id_ws_customhtml_faq`, `question`, `answer` + FROM `' . _DB_PREFIX_ . 'ws_customhtml_faq`' + ); + $languages = Language::getLanguages(false); + + foreach ($faqs as $faq) { + foreach ($languages as $language) { + $existing = Db::getInstance()->executeS( + 'SELECT 1 FROM `' . _DB_PREFIX_ . 'ws_customhtml_faq_lang` + WHERE `id_ws_customhtml_faq` = ' . (int) $faq['id_ws_customhtml_faq'] . ' + AND `id_lang` = ' . (int) $language['id_lang'] + ); + + if (!empty($existing)) { + continue; + } + + $result = Db::getInstance()->insert('ws_customhtml_faq_lang', [ + 'id_ws_customhtml_faq' => (int) $faq['id_ws_customhtml_faq'], + 'id_lang' => (int) $language['id_lang'], + 'question' => pSQL($faq['question']), + 'answer' => pSQL($faq['answer'], true), + ]); + + if (!$result) { + return false; + } + } + } + + return true; +} + +function dropFaqLangColumns(): bool +{ + $columns = Db::getInstance()->executeS( + 'SHOW COLUMNS FROM `' . _DB_PREFIX_ . 'ws_customhtml_faq` LIKE \'question\'' + ); + + if (empty($columns)) { + return true; + } + + return Db::getInstance()->execute( + 'ALTER TABLE `' . _DB_PREFIX_ . 'ws_customhtml_faq` + DROP COLUMN `question`, + DROP COLUMN `answer`' + ); +} diff --git a/ws_customhtml.php b/ws_customhtml.php index ccd2c4d..c566448 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.22.0'; + $this->version = '1.24.0'; $this->author = 'Isabelle Oving-Anno | De Websmid BV'; $this->need_instance = 0; $this->bootstrap = true;