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:
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 }
@@ -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();
+10 -3
View File
@@ -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,
]);
}
+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\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'),
+37 -8
View File
@@ -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 ?: [];
}
+45 -11
View File
@@ -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 ?: [];
}
+12 -12
View File
@@ -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
+23 -7
View File
@@ -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));
}
+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()
{
$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;