feat(main): Make FAQ and slide entities translatable

This commit is contained in:
2026-09-09 13:17:58 +02:00
parent 7cafc376b7
commit 4e7333493a
11 changed files with 358 additions and 62 deletions
+2 -4
View File
@@ -36,16 +36,14 @@ services:
websmid.customhtml.form.type.customhtml_faq: websmid.customhtml.form.type.customhtml_faq:
public: true public: true
class: 'Websmid\CustomHtml\Form\Type\CustomHtmlFaqType' class: 'Websmid\CustomHtml\Form\Type\CustomHtmlFaqType'
arguments: parent: "form.type.translatable.aware"
- '@translator'
tags: tags:
- { name: form.type } - { name: form.type }
websmid.customhtml.form.type.customhtml_slide: websmid.customhtml.form.type.customhtml_slide:
public: true public: true
class: 'Websmid\CustomHtml\Form\Type\CustomHtmlSlideType' class: 'Websmid\CustomHtml\Form\Type\CustomHtmlSlideType'
arguments: parent: "form.type.translatable.aware"
- '@translator'
tags: tags:
- { name: form.type } - { name: form.type }
@@ -146,14 +146,18 @@ final class CustomHtmlBlockDataHandler implements FormDataHandlerInterface
CustomHtmlFaq::deleteByBlockId($idBlock); CustomHtmlFaq::deleteByBlockId($idBlock);
foreach (array_values($faqs) as $position => $faqData) { 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; continue;
} }
$faq = new CustomHtmlFaq(); $faq = new CustomHtmlFaq();
$faq->id_ws_customhtml = $idBlock; $faq->id_ws_customhtml = $idBlock;
$faq->question = (string) $faqData['question']; $faq->question = $question;
$faq->answer = (string) ($faqData['answer'] ?? ''); $faq->answer = $faqData['answer'] ?? [];
$faq->ordering = $position; $faq->ordering = $position;
$faq->add(); $faq->add();
} }
@@ -181,11 +185,11 @@ final class CustomHtmlBlockDataHandler implements FormDataHandlerInterface
$slide = new CustomHtmlSlide(); $slide = new CustomHtmlSlide();
$slide->id_ws_customhtml = $idBlock; $slide->id_ws_customhtml = $idBlock;
$slide->title = (string) ($slideData['title'] ?? ''); $slide->title = $slideData['title'] ?? [];
$slide->description = (string) ($slideData['description'] ?? ''); $slide->description = $slideData['description'] ?? [];
$slide->extra_description = (string) ($slideData['extra_description'] ?? ''); $slide->extra_description = $slideData['extra_description'] ?? [];
$slide->link = (string) ($slideData['link'] ?? ''); $slide->link = $slideData['link'] ?? [];
$slide->link_text = (string) ($slideData['link_text'] ?? ''); $slide->link_text = $slideData['link_text'] ?? [];
$slide->image = $this->saveUploadedImage($slideData['image'] ?? null, $existingImage); $slide->image = $this->saveUploadedImage($slideData['image'] ?? null, $existingImage);
$slide->ordering = $position; $slide->ordering = $position;
$slide->add(); $slide->add();
+10 -3
View File
@@ -6,26 +6,33 @@ use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use PrestaShopBundle\Form\Admin\Type\TranslatableType;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
class CustomHtmlFaqType extends AbstractType class CustomHtmlFaqType extends AbstractType
{ {
private $translator; private $translator;
private $locales;
public function __construct(TranslatorInterface $translator) public function __construct(TranslatorInterface $translator, array $locales)
{ {
$this->translator = $translator; $this->translator = $translator;
$this->locales = $locales;
} }
public function buildForm(FormBuilderInterface $formBuilder, array $options): void public function buildForm(FormBuilderInterface $formBuilder, array $options): void
{ {
$formBuilder $formBuilder
->add('question', TextType::class, [ ->add('question', TranslatableType::class, [
'type' => TextType::class,
'label' => $this->translator->trans('Question', [], 'Modules.Wscustomhtml.Admin'), 'label' => $this->translator->trans('Question', [], 'Modules.Wscustomhtml.Admin'),
'locales' => $this->locales,
'required' => false, 'required' => false,
]) ])
->add('answer', TextareaType::class, [ ->add('answer', TranslatableType::class, [
'type' => TextareaType::class,
'label' => $this->translator->trans('Answer', [], 'Modules.Wscustomhtml.Admin'), 'label' => $this->translator->trans('Answer', [], 'Modules.Wscustomhtml.Admin'),
'locales' => $this->locales,
'required' => false, 'required' => false,
]); ]);
} }
+21 -8
View File
@@ -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\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use PrestaShopBundle\Form\Admin\Type\TranslatableType;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
class CustomHtmlSlideType extends AbstractType class CustomHtmlSlideType extends AbstractType
{ {
private $translator; private $translator;
private $locales;
public function __construct(TranslatorInterface $translator) public function __construct(TranslatorInterface $translator, array $locales)
{ {
$this->translator = $translator; $this->translator = $translator;
$this->locales = $locales;
} }
public function buildForm(FormBuilderInterface $formBuilder, array $options): void public function buildForm(FormBuilderInterface $formBuilder, array $options): void
@@ -25,27 +28,37 @@ class CustomHtmlSlideType extends AbstractType
->add('id', HiddenType::class, [ ->add('id', HiddenType::class, [
'required' => false, 'required' => false,
]) ])
->add('title', TextType::class, [ ->add('title', TranslatableType::class, [
'type' => TextType::class,
'label' => $this->translator->trans('Title', [], 'Modules.Wscustomhtml.Admin'), 'label' => $this->translator->trans('Title', [], 'Modules.Wscustomhtml.Admin'),
'locales' => $this->locales,
'required' => false, 'required' => false,
]) ])
->add('description', TextareaType::class, [ ->add('description', TranslatableType::class, [
'type' => TextareaType::class,
'label' => $this->translator->trans('Description', [], 'Modules.Wscustomhtml.Admin'), 'label' => $this->translator->trans('Description', [], 'Modules.Wscustomhtml.Admin'),
'locales' => $this->locales,
'required' => false, 'required' => false,
]) ])
->add('extra_description', TextareaType::class, [ ->add('extra_description', TranslatableType::class, [
'type' => TextareaType::class,
'label' => $this->translator->trans('Extra description', [], 'Modules.Wscustomhtml.Admin'), 'label' => $this->translator->trans('Extra description', [], 'Modules.Wscustomhtml.Admin'),
'locales' => $this->locales,
'required' => false, 'required' => false,
]) ])
->add('link', TextType::class, [ ->add('link', TranslatableType::class, [
'type' => TextType::class,
'label' => $this->translator->trans('Link URL', [], 'Modules.Wscustomhtml.Admin'), 'label' => $this->translator->trans('Link URL', [], 'Modules.Wscustomhtml.Admin'),
'locales' => $this->locales,
'required' => false, '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'), 'label' => $this->translator->trans('Link text', [], 'Modules.Wscustomhtml.Admin'),
'locales' => $this->locales,
'required' => false, 'required' => false,
'attr' => ['placeholder' => 'Learn more'], 'options' => ['attr' => ['placeholder' => 'Learn more']],
]) ])
->add('image', FileType::class, [ ->add('image', FileType::class, [
'label' => $this->translator->trans('Image', [], 'Modules.Wscustomhtml.Admin'), 'label' => $this->translator->trans('Image', [], 'Modules.Wscustomhtml.Admin'),
+37 -8
View File
@@ -29,27 +29,56 @@ class CustomHtmlFaq extends ObjectModel
public $date_upd; public $date_upd;
public static $definition = [ public static $definition = [
'table' => 'ws_customhtml_faq', 'table' => 'ws_customhtml_faq',
'primary' => 'id_ws_customhtml_faq', 'primary' => 'id_ws_customhtml_faq',
'fields' => [ 'multilang' => true,
'fields' => [
'id_ws_customhtml' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true], 'id_ws_customhtml' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true],
'question' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 512], 'question' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 512, 'lang' => true],
'answer' => ['type' => self::TYPE_HTML, 'validate' => 'isCleanHtml'], 'answer' => ['type' => self::TYPE_HTML, 'validate' => 'isCleanHtml', 'lang' => true],
'ordering' => ['type' => self::TYPE_INT, 'validate' => 'isInt'], 'ordering' => ['type' => self::TYPE_INT, 'validate' => 'isInt'],
'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'], 'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'],
'date_upd' => ['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 public static function getByBlockId(int $idBlock): array
{ {
$result = Db::getInstance()->executeS( $ids = Db::getInstance()->executeS(
'SELECT `id_ws_customhtml_faq`, `question`, `answer`, `ordering` 'SELECT `id_ws_customhtml_faq` FROM `' . _DB_PREFIX_ . 'ws_customhtml_faq`
FROM `' . _DB_PREFIX_ . 'ws_customhtml_faq`
WHERE `id_ws_customhtml` = ' . (int) $idBlock . ' WHERE `id_ws_customhtml` = ' . (int) $idBlock . '
ORDER BY `ordering` ASC' 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 ?: []; return $result ?: [];
} }
+45 -11
View File
@@ -41,15 +41,16 @@ class CustomHtmlSlide extends ObjectModel
public $date_upd; public $date_upd;
public static $definition = [ public static $definition = [
'table' => 'ws_customhtml_slide', 'table' => 'ws_customhtml_slide',
'primary' => 'id_ws_customhtml_slide', 'primary' => 'id_ws_customhtml_slide',
'fields' => [ 'multilang' => true,
'fields' => [
'id_ws_customhtml' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true], 'id_ws_customhtml' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true],
'title' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 256], 'title' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 256, 'lang' => true],
'description' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 1024], '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], '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], '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], '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], 'image' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => false, 'size' => 255],
'ordering' => ['type' => self::TYPE_INT, 'validate' => 'isInt'], 'ordering' => ['type' => self::TYPE_INT, 'validate' => 'isInt'],
'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'], '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 public static function getByBlockId(int $idBlock): array
{ {
$result = Db::getInstance()->executeS( $ids = Db::getInstance()->executeS(
'SELECT `id_ws_customhtml_slide`, `title`, `description`, `extra_description`, `link`, `link_text`, `image`, `ordering` 'SELECT `id_ws_customhtml_slide` FROM `' . _DB_PREFIX_ . 'ws_customhtml_slide`
FROM `' . _DB_PREFIX_ . 'ws_customhtml_slide`
WHERE `id_ws_customhtml` = ' . (int) $idBlock . ' WHERE `id_ws_customhtml` = ' . (int) $idBlock . '
ORDER BY `ordering` ASC' 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 ?: []; return $result ?: [];
} }
+12 -12
View File
@@ -71,9 +71,9 @@ trait DisplayHooks
} }
$blocksByGroup = CustomHtmlBlock::getActiveByGroupIds(array_column($groups, 'id_ws_customhtml_group'), $idLang); $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->attachImageUrls($blocksByGroup);
$blocksByGroup = $this->attachSlidesToBlocks($blocksByGroup); $blocksByGroup = $this->attachSlidesToBlocks($blocksByGroup, $idLang);
$groups = array_map(static function (array $group) use ($blocksByGroup) { $groups = array_map(static function (array $group) use ($blocksByGroup) {
$group['blocks'] = $blocksByGroup[(int) $group['id_ws_customhtml_group']] ?? []; $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 $blocks) use ($idLang) {
return array_map(static function (array $block) { return array_map(static function (array $block) use ($idLang) {
if ($block['type'] === 'faq') { 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; return $block;
@@ -112,12 +112,12 @@ trait DisplayHooks
}, $blocksByGroup); }, $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 $blocks) use ($idLang) {
return array_map(function (array $block) { return array_map(function (array $block) use ($idLang) {
if ($block['type'] === 'slider') { 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_config'] = $this->buildSliderConfig($block);
$block['slider_desktop_column_width'] = $this->buildSliderDesktopColumnWidth($block); $block['slider_desktop_column_width'] = $this->buildSliderDesktopColumnWidth($block);
} }
@@ -127,14 +127,14 @@ trait DisplayHooks
}, $blocksByGroup); }, $blocksByGroup);
} }
private function loadSlidesForBlock(int $idBlock): array private function loadSlidesForBlock(int $idBlock, int $idLang): array
{ {
return array_map(static function (array $slide) { return array_map(static function (array $slide) {
$slide['image_url'] = CustomHtmlBlock::getBannerImageUrl($slide['image']); $slide['image_url'] = CustomHtmlBlock::getBannerImageUrl($slide['image']);
$slide['show_title'] = true; $slide['show_title'] = true;
return $slide; return $slide;
}, CustomHtmlSlide::getByBlockId($idBlock)); }, CustomHtmlSlide::getByBlockIdForLang($idBlock, $idLang));
} }
private function buildSliderConfig(array $block): string private function buildSliderConfig(array $block): string
+23 -7
View File
@@ -108,8 +108,6 @@ trait Install
CREATE TABLE IF NOT EXISTS ' . _DB_PREFIX_ . 'ws_customhtml_faq ( 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_faq` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`id_ws_customhtml` INT(11) NOT NULL, `id_ws_customhtml` INT(11) NOT NULL,
`question` VARCHAR(512) NOT NULL DEFAULT \'\',
`answer` TEXT,
`ordering` INT(11) NOT NULL DEFAULT 0, `ordering` INT(11) NOT NULL DEFAULT 0,
`date_add` DATETIME NOT NULL, `date_add` DATETIME NOT NULL,
`date_upd` 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[] = ' $sqlToExec[] = '
CREATE TABLE IF NOT EXISTS ' . _DB_PREFIX_ . 'ws_customhtml_slide ( 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_slide` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`id_ws_customhtml` INT(11) NOT NULL, `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 \'\', `image` VARCHAR(255) NOT NULL DEFAULT \'\',
`ordering` INT(11) NOT NULL DEFAULT 0, `ordering` INT(11) NOT NULL DEFAULT 0,
`date_add` DATETIME NOT NULL, `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) { foreach ($sqlToExec as $sqlBlock) {
Db::getInstance()->execute(trim($sqlBlock)); Db::getInstance()->execute(trim($sqlBlock));
} }
+102
View File
@@ -0,0 +1,102 @@
<?php
if (!defined('_PS_VERSION_')) {
exit;
}
function upgrade_module_1_23_0($module)
{
if (!createSlideLangTable()) {
return false;
}
if (!migrateSlideFieldsToLangTable()) {
return false;
}
return dropSlideLangColumns();
}
function createSlideLangTable(): bool
{
return Db::getInstance()->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`'
);
}
+93
View File
@@ -0,0 +1,93 @@
<?php
if (!defined('_PS_VERSION_')) {
exit;
}
function upgrade_module_1_24_0($module)
{
if (!createFaqLangTable()) {
return false;
}
if (!migrateFaqFieldsToLangTable()) {
return false;
}
return dropFaqLangColumns();
}
function createFaqLangTable(): bool
{
return Db::getInstance()->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`'
);
}
+1 -1
View File
@@ -29,7 +29,7 @@ class Ws_CustomHtml extends Module implements WidgetInterface
public function __construct() public function __construct()
{ {
$this->name = 'ws_customhtml'; $this->name = 'ws_customhtml';
$this->version = '1.22.0'; $this->version = '1.24.0';
$this->author = 'Isabelle Oving-Anno | De Websmid BV'; $this->author = 'Isabelle Oving-Anno | De Websmid BV';
$this->need_instance = 0; $this->need_instance = 0;
$this->bootstrap = true; $this->bootstrap = true;