From 5194b3d64473463d91eb2032bcdaa2cf7cfb4ca6 Mon Sep 17 00:00:00 2001 From: Prestasafe Date: Fri, 26 Jan 2024 18:15:55 +0100 Subject: [PATCH 01/68] add bouton to edit page on listing (product / category and CMS) --- config/routes.yml | 12 +++- prettyblocks.php | 26 +++++++- .../AdminThemeManagerController.php | 35 ++++++++++ views/js/back.js | 64 +++++++++++++++++++ 4 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 views/js/back.js diff --git a/config/routes.yml b/config/routes.yml index d9d7120f..153482fb 100644 --- a/config/routes.yml +++ b/config/routes.yml @@ -5,6 +5,15 @@ admin_prettyblocks: _controller: 'PrestaSafe\PrettyBlocks\Controller\AdminThemeManagerController::indexAction' _legacy_controller: AdminThemeManagerController _legacy_link: AdminThemeManagerController +# route generator (for opening custom page in prettyblocks) + +prettyblocks_route_generator: + path: prettyblocks/route_generator/ + methods: [GET,POST] + defaults: + _controller: 'PrestaSafe\PrettyBlocks\Controller\AdminThemeManagerController::routeGeneratorAction' + _legacy_controller: AdminThemeManagerControllerRouteGenerator + _legacy_link: AdminThemeManagerControllerRouteGenerator prettyblocks_block_render: path: prettyblocks/block/ @@ -88,4 +97,5 @@ prettyblocks_theme_settings: defaults: _controller: 'PrestaSafe\PrettyBlocks\Controller\AdminThemeManagerController::getSettingsAction' _legacy_controller: AdminThemeManagerController - _legacy_link: AdminThemeManagerController \ No newline at end of file + _legacy_link: AdminThemeManagerController + diff --git a/prettyblocks.php b/prettyblocks.php index c9e4aa36..98ee1ac2 100755 --- a/prettyblocks.php +++ b/prettyblocks.php @@ -19,6 +19,8 @@ */ use PrestaSafe\PrettyBlocks\Core\Components\Title; use PrestaShop\PrestaShop\Core\Module\WidgetInterface; +use PrestaShop\PrestaShop\Adapter\SymfonyContainer; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; if (!defined('_PS_VERSION_')) { exit; @@ -53,6 +55,7 @@ class PrettyBlocks extends Module implements WidgetInterface 'actionDispatcher', 'actionFrontControllerSetVariables', 'ActionRegisterThemeSettings', + 'displayBackOfficeHeader', ]; public function __construct() @@ -150,14 +153,21 @@ private function removeDb() } public function getContent() + { + return Tools::redirect($this->getPrettyBlocksUrl()); + } + + private function getPrettyBlocksUrl() { $domain = Tools::getShopDomainSsl(true); - $symfonyUrl = $domain . Link::getUrlSmarty([ + + return $domain . Link::getUrlSmarty([ 'entity' => 'sf', 'route' => 'admin_prettyblocks', + ]); + - return Tools::redirect($symfonyUrl); } private function loadDefault() @@ -165,6 +175,18 @@ private function loadDefault() return Configuration::updateGlobalValue('_PRETTYBLOCKS_TOKEN_', Tools::passwdGen(25)); } + public function hookdisplayBackOfficeHeader($params) + { + $route = (new \Link())->getAdminLink('AdminThemeManagerControllerRouteGenerator'); + Media::addJsDef([ + 'prettyblocks_route_generator' => $route, + 'prettyblocks_logo' => HelperBuilder::pathFormattedToUrl('$/modules/prettyblocks/logo.png'), + ]); + + $this->context->controller->addJS($this->_path.'views/js/back.js'); + } + + public function install() { return parent::install() diff --git a/src/Controller/AdminThemeManagerController.php b/src/Controller/AdminThemeManagerController.php index 0b86fb5a..c3933192 100644 --- a/src/Controller/AdminThemeManagerController.php +++ b/src/Controller/AdminThemeManagerController.php @@ -208,6 +208,21 @@ public function indexAction() // url to load at startup : provided url or shop home page $startup_url = \Tools::getValue('startup_url', $shop_url); + if(\Tools::getValue('endpoint')){ + switch(\Tools::getValue('endpoint')) + { + case 'product': + $startup_url = $link->getProductLink((int)\Tools::getValue('id')); + break; + case 'category': + $startup_url = $link->getCategoryLink((int)\Tools::getValue('id')); + break; + case 'cms': + $startup_url = $link->getCMSLink((int)\Tools::getValue('id')); + break; + } + } + return $this->render('@Modules/prettyblocks/views/templates/admin/index.html.twig', [ 'css_back_custom' => $uri, 'base_url' => $link->getBaseLink(), @@ -615,4 +630,24 @@ protected function getLangLink($idLang = null, \Context $context = null, $idShop return \Language::getIsoById($idLang) . '/'; } + + + public function routeGeneratorAction(Request $request) + { + $posts = json_decode($request->getContent(), true); + $endpoint = $posts['endpoint']; + $id = (int)$posts['id']; + + $router = $this->get('router'); + $url = $router->generate('admin_prettyblocks', [ + 'endpoint' => $endpoint, + 'id' => $id, + ]); + return (new JsonResponse())->setData([ + 'url' => $url, + ]); + + + } + } diff --git a/views/js/back.js b/views/js/back.js new file mode 100644 index 00000000..cf02b657 --- /dev/null +++ b/views/js/back.js @@ -0,0 +1,64 @@ + +const addPrettyButton = (btnGroupClass = '.btn-group-action', endpoint, idEndpointTarget) => { + let btnGroups = document.querySelectorAll(btnGroupClass); + btnGroups.forEach(btnGroup => { + let id_cms = parseInt(btnGroup.closest('tr').querySelector(idEndpointTarget).textContent); + + // Début de la sélection + let newElement = document.createElement('a'); + newElement.innerHTML = "edit in prettyblocks"; + newElement.dataset.endpoint = endpoint; + newElement.dataset.idEndpoint = id_cms; + newElement.dataset.action = "open_in_prettyblocks"; + // Fin de la sélection + btnGroup.prepend(newElement); + }); +} + +document.addEventListener('DOMContentLoaded', function() { + +// CMS LIST Button +if (document.body.classList.contains('admincmscontent')) { + addPrettyButton('.btn-group-action', 'cms', '.column-id_cms'); +} + +// Product LIST Button +if (document.body.classList.contains('adminproducts')) { + addPrettyButton('.btn-group-action', 'product', '.column-id_product'); +} +if (document.body.classList.contains('admincategories')) { + addPrettyButton('.btn-group-action', 'category', '.column-id_category'); +} + + +// Début de la sélection +let prettyBlocksButtons = document.querySelectorAll('[data-action="open_in_prettyblocks"]'); +// Fin de la sélection +prettyBlocksButtons.forEach(button => { + button.addEventListener('click', function(event) { + event.preventDefault(); + // Ajoutez ici le code à exécuter lors du clic sur le bouton + let endpoint = button.dataset.endpoint; + let idEndpoint = button.dataset.idEndpoint; + let action = button.dataset.action; + let url = prettyblocks_route_generator; + + // Début de la sélection + fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + endpoint: endpoint, + id: idEndpoint, + }), + }) + .then(response => response.json()) + .then(data => window.open(data.url, '_self')); + // Fin de la sélection + }); +}); + + +}) \ No newline at end of file From 69ea18beee90c1f93a2b2ebf212d4435e7bf9e4b Mon Sep 17 00:00:00 2001 From: Prestasafe Date: Fri, 26 Jan 2024 18:16:31 +0100 Subject: [PATCH 02/68] php-cs-fixer --- prettyblocks.php | 14 ++++------- .../AdminThemeManagerController.php | 24 ++++++++----------- 2 files changed, 14 insertions(+), 24 deletions(-) diff --git a/prettyblocks.php b/prettyblocks.php index 98ee1ac2..794fbd20 100755 --- a/prettyblocks.php +++ b/prettyblocks.php @@ -19,8 +19,6 @@ */ use PrestaSafe\PrettyBlocks\Core\Components\Title; use PrestaShop\PrestaShop\Core\Module\WidgetInterface; -use PrestaShop\PrestaShop\Adapter\SymfonyContainer; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; if (!defined('_PS_VERSION_')) { exit; @@ -160,14 +158,11 @@ public function getContent() private function getPrettyBlocksUrl() { $domain = Tools::getShopDomainSsl(true); - + return $domain . Link::getUrlSmarty([ 'entity' => 'sf', 'route' => 'admin_prettyblocks', - ]); - - } private function loadDefault() @@ -177,15 +172,14 @@ private function loadDefault() public function hookdisplayBackOfficeHeader($params) { - $route = (new \Link())->getAdminLink('AdminThemeManagerControllerRouteGenerator'); + $route = (new Link())->getAdminLink('AdminThemeManagerControllerRouteGenerator'); Media::addJsDef([ 'prettyblocks_route_generator' => $route, 'prettyblocks_logo' => HelperBuilder::pathFormattedToUrl('$/modules/prettyblocks/logo.png'), ]); - - $this->context->controller->addJS($this->_path.'views/js/back.js'); - } + $this->context->controller->addJS($this->_path . 'views/js/back.js'); + } public function install() { diff --git a/src/Controller/AdminThemeManagerController.php b/src/Controller/AdminThemeManagerController.php index c3933192..c15a5b38 100644 --- a/src/Controller/AdminThemeManagerController.php +++ b/src/Controller/AdminThemeManagerController.php @@ -208,18 +208,17 @@ public function indexAction() // url to load at startup : provided url or shop home page $startup_url = \Tools::getValue('startup_url', $shop_url); - if(\Tools::getValue('endpoint')){ - switch(\Tools::getValue('endpoint')) - { + if (\Tools::getValue('endpoint')) { + switch (\Tools::getValue('endpoint')) { case 'product': - $startup_url = $link->getProductLink((int)\Tools::getValue('id')); - break; + $startup_url = $link->getProductLink((int) \Tools::getValue('id')); + break; case 'category': - $startup_url = $link->getCategoryLink((int)\Tools::getValue('id')); - break; + $startup_url = $link->getCategoryLink((int) \Tools::getValue('id')); + break; case 'cms': - $startup_url = $link->getCMSLink((int)\Tools::getValue('id')); - break; + $startup_url = $link->getCMSLink((int) \Tools::getValue('id')); + break; } } @@ -631,23 +630,20 @@ protected function getLangLink($idLang = null, \Context $context = null, $idShop return \Language::getIsoById($idLang) . '/'; } - public function routeGeneratorAction(Request $request) { $posts = json_decode($request->getContent(), true); $endpoint = $posts['endpoint']; - $id = (int)$posts['id']; + $id = (int) $posts['id']; $router = $this->get('router'); $url = $router->generate('admin_prettyblocks', [ 'endpoint' => $endpoint, 'id' => $id, ]); + return (new JsonResponse())->setData([ 'url' => $url, ]); - - } - } From fc471e962b68fe1b3a515d8a0cb9808dedc92757 Mon Sep 17 00:00:00 2001 From: Prestasafe Date: Mon, 19 Feb 2024 18:45:18 +0100 Subject: [PATCH 03/68] add updates Updates: Add btn to categories / product / cms. Add Dynamic Zones Add .env files Add .avif support Add Zone priority Add alias zone Fix: getSubselectKey if empty --- .env.exemple | 2 + .gitignore | 3 +- _dev/package-lock.json | 12 +- _dev/src/components/Iframe.vue | 2 +- _dev/src/components/form/ZoneSelect.vue | 78 ++++- _dev/src/scripts/block.js | 12 +- _dev/src/scripts/helper.js | 7 + _dev/src/scripts/iframe.js | 7 +- _dev/src/store/currentBlock.js | 3 + _dev/yarn.lock | 88 +++--- classes/HelperBuilder.php | 21 +- classes/prettyblocks/blocks/SmartyRender.php | 60 ++++ composer.lock | 297 ++++++++++-------- prettyblocks.php | 48 ++- .../AdminThemeManagerController.php | 13 + upgrade/upgrade-3.1.0.php | 37 +++ views/js/build.js | 4 +- views/js/iframe.css | 230 +++++++------- views/js/prettyblocks.js | 11 +- views/templates/admin/index.html.twig | 2 +- views/templates/blocks/smarty_render.tpl | 1 + views/templates/front/zone.tpl | 4 +- 22 files changed, 601 insertions(+), 341 deletions(-) create mode 100644 .env.exemple create mode 100644 _dev/src/scripts/helper.js create mode 100644 classes/prettyblocks/blocks/SmartyRender.php create mode 100644 upgrade/upgrade-3.1.0.php create mode 100644 views/templates/blocks/smarty_render.tpl diff --git a/.env.exemple b/.env.exemple new file mode 100644 index 00000000..bd306abc --- /dev/null +++ b/.env.exemple @@ -0,0 +1,2 @@ +# VITE JS +PRETTYBLOCKS_VITE_DEV=false \ No newline at end of file diff --git a/.gitignore b/.gitignore index ada453cc..6b8231da 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ views/images/* **.DS_Store** test.php .php-cs-fixer.cache -_dev/yarn.lock \ No newline at end of file +_dev/yarn.lock +.env \ No newline at end of file diff --git a/_dev/package-lock.json b/_dev/package-lock.json index 87e1341b..db271167 100644 --- a/_dev/package-lock.json +++ b/_dev/package-lock.json @@ -1932,9 +1932,9 @@ "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" }, "node_modules/tinymce": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-6.7.1.tgz", - "integrity": "sha512-SIGJgWk2d/X59VbO+i81QfNx2EP1P5t+sza2/1So3OLGtmMBhEJMag7sN/Mo8sq4s0niwb65Z51yLju32jP11g==" + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-6.8.2.tgz", + "integrity": "sha512-Lho79o2Y1Yn+XdlTEkHTEkEmzwYWTXz7IUsvPwxJF3VTtgHUIAAuBab29kik+f2KED3rZvQavr9D7sHVMJ9x4A==" }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -2005,9 +2005,9 @@ } }, "node_modules/vite": { - "version": "2.9.16", - "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.16.tgz", - "integrity": "sha512-X+6q8KPyeuBvTQV8AVSnKDvXoBMnTx8zxh54sOwmmuOdxkjMmEJXH2UEchA+vTMps1xw9vL64uwJOWryULg7nA==", + "version": "2.9.17", + "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.17.tgz", + "integrity": "sha512-XxcRzra6d7xrKXH66jZUgb+srThoPu+TLJc06GifUyKq9JmjHkc1Numc8ra0h56rju2jfVWw3B3fs5l3OFMvUw==", "dependencies": { "esbuild": "^0.14.27", "postcss": "^8.4.13", diff --git a/_dev/src/components/Iframe.vue b/_dev/src/components/Iframe.vue index af5f830a..c79f1cd5 100644 --- a/_dev/src/components/Iframe.vue +++ b/_dev/src/components/Iframe.vue @@ -41,7 +41,7 @@ onUnmounted(() => { const reloadIframe = () => { iframe.reloadIframe() } -emitter.on('reloadIframe', async (id_prettyblocks) => { +emitter.on('reloadIframe', async () => { let context = contextShop() iframe.setUrl(context.href) iframe.reloadIframe() diff --git a/_dev/src/components/form/ZoneSelect.vue b/_dev/src/components/form/ZoneSelect.vue index 88ed7e3f..cbc05c3f 100644 --- a/_dev/src/components/form/ZoneSelect.vue +++ b/_dev/src/components/form/ZoneSelect.vue @@ -11,22 +11,53 @@ defineComponent({ ChevronUpDownIcon }) let items = ref([]); - +let current_zone = currentZone() emitter.on('loadZones', (zonesState) => { - items.value = zonesState if (zonesState.indexOf(currentZone().name) == -1) { - currentZone().$patch({ - name: zonesState[0] - }) + let priorityZone = zonesState[0] + + // if prettyblocks already init (when reloading a simple page) + let isPresent = zonesState.find(zone => { + return zone.name === current_zone.zoneToFocus + }) || false + + if(current_zone.zoneToFocus !== '' && isPresent) + { + priorityZone = current_zone + } else { + + current_zone.$patch({ + name: zonesState[0].name, + alias: zonesState[0].alias, + priority: zonesState[0].priority, + zoneToFocus: zonesState[0].name, + }) + + priorityZone = zonesState[0] + + + // check if there is a priority zone + for (let zone of zonesState) { + if (zone.priority === true) { + priorityZone = zone; + break; + } + } + } - props.modelValue.name = zonesState[0] - onInput(zonesState[0]) + + props.modelValue.name = priorityZone.name + props.modelValue.alias = priorityZone.alias + props.modelValue.priority = priorityZone.priority + props.modelValue.zoneToFocus = priorityZone.name + + onInput(priorityZone) } }) emitter.on('selectZone' , (zone) => { - props.modelValue.name = zone + props.modelValue = zone onInput(zone) }) @@ -36,26 +67,39 @@ const props = defineProps({ modelValue: { type: Object, default: { - name: 'displayHome' + name: 'displayHome', + alias: '', + priority: false } } }) const changetItem = (item) => { - props.modelValue.name = item + props.modelValue.name = item.name + props.modelValue.alias = item.alias + // force reload on the last zone + props.modelValue.priority = true } const emit = defineEmits(['update:modelValue']) -function onInput(value) { +function onInput(zone) { let current_zone = currentZone() - current_zone.$patch({ name: value }) - emit('update:modelValue.name', value) + current_zone.$patch({ + name: zone.name, + alias: zone.alias, + priority: zone.priority, + zoneToFocus: zone.name, + }) + + emit('update:modelValue.name', zone.name) + emit('update:modelValue.alias', zone.alias) + emit('update:modelValue.priority', zone.priority) - emitter.emit('focusOnZone', value) + emitter.emit('focusOnZone', zone.name) } @@ -68,9 +112,9 @@ watch(() => props.modelValue, onInput)
- + - {{ trans('current_zone') }}: {{ props.modelValue.name }} + {{ trans('current_zone') }}: {{ props.modelValue.alias !== '' ? props.modelValue.alias : props.modelValue.name }}