first commit

This commit is contained in:
2024-10-28 22:14:22 +01:00
commit b65352c452
40581 changed files with 5712079 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
drwxr-xr-x 9 30094 users 15 Oct 6 10:16 .
drwxr-xr-x 115 30094 users 117 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 991 Aug 31 2021 Readme.md
drwxr-xr-x 4 30094 users 9 Oct 6 10:16 classes
-rw-r--r-- 1 30094 users 519 Aug 31 2021 config.xml
-rw-rw-r-- 1 30094 users 519 Aug 31 2021 config_pl.xml
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 controllers
drwxr-xr-x 3 30094 users 8 Oct 6 10:16 default
drwxr-xr-x 2 30094 users 75 Oct 6 10:16 extracontent
-rw-r--r-- 1 30094 users 919 Aug 31 2021 index.php
-rw-r--r-- 1 30094 users 110207 Aug 31 2021 jxmegalayout.php
-rw-r--r-- 1 30094 users 19569 Aug 31 2021 logo.png
drwxr-xr-x 2 30094 users 5 Oct 6 10:16 sql
drwxr-xr-x 2 30094 users 9 Oct 6 10:16 translations
drwxr-xr-x 6 30094 users 7 Oct 6 10:16 views

View File

@@ -0,0 +1,32 @@
# JX Mega Layout
v 1.5.4
FIX:
- fixed cancel buttons duplication in extra-content forms (BO)
- fixed color picker icons and backgrounds (BO)
- fixed an issue with extra-content video preview if a video isn't added yet (BO)
- improved verification of layouts archives before import (BO)
v 1.5.3
FIX: fixed an issue with extra-content when one of the available languages is't active
v 1.5.2
FIX: fixed an issue when admin panel active layout has no inner items
v 1.5.1
FIX: added a condition to check if a module exists before add it to an admin part. Needed because some issues started to appear in some servers
v 1.4.1
FIX: added check if a JX Blog module is installed and enabled to post.tpl file which is responding for custom content posts displaying.
v 1.4.0
UPD: added opportunities to import/export extra content
v 1.3.3
FIX: fixed an issue with extra-content sorting
v 1.3.2
UPD: added hook name to module front blocks
v 1.3.1
FIX: small fixes with front-end columns' classes

View File

@@ -0,0 +1,9 @@
drwxr-xr-x 4 30094 users 9 Oct 6 10:16 .
drwxr-xr-x 9 30094 users 15 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 13399 Aug 31 2021 JXMegaLayoutExport.php
-rw-r--r-- 1 30094 users 14263 Aug 31 2021 JXMegaLayoutImport.php
-rw-r--r-- 1 30094 users 5799 Aug 31 2021 JXMegaLayoutItems.php
-rw-r--r-- 1 30094 users 11344 Aug 31 2021 JXMegaLayoutLayouts.php
-rw-r--r-- 1 30094 users 10798 Aug 31 2021 JXMegaLayoutOptimize.php
drwxr-xr-x 2 30094 users 8 Oct 6 10:16 extra
drwxr-xr-x 2 30094 users 3 Oct 6 10:16 themebuilder

View File

@@ -0,0 +1,392 @@
<?php
/**
* 2017-2019 Zemez
*
* JX Mega Layout
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul & Alexander Pervakov)
* @copyright 2017-2019 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class JXMegalayoutExport
{
/**
* Generate layout settings and write it
*
* @param int $id_layout
* @param string $path Export folder
* @return string Layout name
*/
protected function writeLayoutSettings($id_layout, $path)
{
//create or rewrite settings file
$file = fopen($path . 'settings.json', 'w');
$layout = new JXMegaLayoutLayouts($id_layout);
$jxmegalayout = new Jxmegalayout();
//generate array of layout settings
$settings = array(
'hook' => $layout->hook_name,
'layout_name' => $layout->layout_name,
'layout_file' => 'grid.json',
'status' => $layout->status
);
if (!$pages = $layout->getAllLayoutPages()) {
$pages = array();
}
$settings['pages'] = $pages;
$settings['version'] = $jxmegalayout->version;
//write settings in JSON format
fwrite($file, Tools::jsonEncode($settings));
fclose($file);
return $layout->layout_name;
}
/**
* Prepare layout for export, and copy custom styles for layout items
*
* @param array $map Genereted by Jxmegalayout::generateLayoutMap
* @param string $path Module folder
* @param int $level
* @param array $positions
* @return array or bool Layout array or False if $map is empty
*/
protected function prepareLayoutGrid($map, $path, $level = null, $positions = array())
{
//get level if it's null
if (is_null($level)) {
$level = count($map) - 1;
//if map empty, $level == -1
if ($level < 0) {
return false;
}
}
//level
foreach ($map[$level] as $id_parent => $layouts) {
//layouts
foreach ($layouts as $layout) {
//check layout children
if (isset($positions[$layout['id_item']])) {
$layout['child'] = $positions[$layout['id_item']];
} else {
$layout['child'] = false;
}
$this->writeLayoutStyle($layout['id_unique'], $path);
$this->writeLayoutExtraCss($layout['id_unique'], $path);
//check layout type
switch ($layout['type']) {
case 'module':
$positions[$id_parent][] = array(
'type' => $layout['type'],
'sort_order' => $layout['sort_order'],
'specific_class' => $layout['specific_class'],
'module_name' => $layout['module_name'],
'id_unique' => $layout['id_unique'],
'origin_hook' => $layout['origin_hook'],
'extra_css' => $layout['extra_css'],
'child' => $layout['child']
);
break;
case 'wrapper':
$positions[$id_parent][] = array(
'type' => $layout['type'],
'sort_order' => $layout['sort_order'],
'specific_class' => $layout['specific_class'],
'id_unique' => $layout['id_unique'],
'child' => $layout['child']
);
break;
case 'row':
$positions[$id_parent][] = array(
'type' => $layout['type'],
'sort_order' => $layout['sort_order'],
'specific_class' => $layout['specific_class'],
'id_unique' => $layout['id_unique'],
'child' => $layout['child']
);
break;
case 'col':
$positions[$id_parent][] = array(
'type' => $layout['type'],
'sort_order' => $layout['sort_order'],
'specific_class' => $layout['specific_class'],
'col' => $layout['col'],
'col_xs' => $layout['col_xs'],
'col_sm' => $layout['col_sm'],
'col_md' => $layout['col_md'],
'col_lg' => $layout['col_lg'],
'col_xl' => $layout['col_xl'],
'col_xxl' => $layout['col_xxl'],
'id_unique' => $layout['id_unique'],
'child' => $layout['child']
);
break;
case 'block':
$positions[$id_parent][] = array(
'type' => $layout['type'],
'sort_order' => $layout['sort_order'],
'specific_class' => $layout['specific_class'],
'module_name' => $layout['module_name'],
'id_unique' => $layout['id_unique'],
'child' => $layout['child']
);
break;
case 'content':
$positions[$id_parent][] = array(
'type' => $layout['type'],
'sort_order' => $layout['sort_order'],
'specific_class' => $layout['specific_class'],
'module_name' => $layout['module_name'],
'id_unique' => $layout['id_unique'],
'child' => $layout['child']
);
break;
default:
continue;
}
}
}
$level--;
if ($level >= 0) {
$export_layout = $this->prepareLayoutGrid($map, $path, $level, $positions);
} else {
$export_layout = $positions[0];
}
return $export_layout;
}
/**
* Write 'grid.json' file
*
* @param int $id_layout
* @param string $path Module folder
*/
protected function writeLayoutGrid($id_layout, $path)
{
//write or rewrite grid file
$file = fopen($path . 'grid.json', 'w');
$map_obj = new Jxmegalayout();
//get layouts from database
$layout_array = $map_obj->getLayoutItems($id_layout);
//generate map for layouts
$map = $map_obj->generateLayoutMap($layout_array);
//get layouts in export format
$items = $this->prepareLayoutGrid($map, $path);
//write layouts file in JSON format
fwrite($file, Tools::jsonEncode($items));
fclose($file);
}
/**
* Write layout styles for export
*
* @param type $id_unique Style id
* @param type $path Module folder
* @return boolean
*/
protected function writeLayoutStyle($id_unique, $path)
{
$obj = new Jxmegalayout();
if ($obj->checkUniqueStylesExists($id_unique)) {
if (!file_exists($path . 'styles')) {
mkdir($path . 'styles', 0777);
}
if ($background_url = $obj->getItemImageUrl($id_unique)) {
$background_image = explode('url(../../../../../img/', str_replace(')', '', $background_url));
$this->writeLayoutImage($path, $background_image[1]);
}
copy($obj->style_path . $id_unique . '.css', $path . 'styles/' . $id_unique . '.css');
}
return true;
}
/**
* Copy layouts' extra css files if exists
*
* @param type $id_unique Style id
* @param type $path Module folder
* @return boolean
*/
protected function writeLayoutExtraCss($id_unique, $path)
{
$obj = new Jxmegalayout();
if (is_dir($obj->style_path.'modules/'.$id_unique.'/')) {
if (!$files = Tools::scandir($obj->style_path.'modules/'.$id_unique.'/', 'css')) {
return;
}
if (!file_exists($path.'files')) {
mkdir($path.'files', 0777);
}
if (!file_exists($path.'files/modules')) {
mkdir($path.'files/modules', 0777);
}
if (!file_exists($path.'files/modules/'.$id_unique)) {
mkdir($path.'files/modules/'.$id_unique, 0777);
}
foreach ($files as $file) {
copy($obj->style_path.'modules/'.$id_unique.'/'.$file, $path.'files/modules/'.$id_unique.'/'.$file);
}
}
return true;
}
/**
* Write layout js and css files
*
* @param string $name
* @param string $path
* @return bool
*/
protected function writeLayoutFiles($name, $path)
{
$jxmegalayout = new Jxmegalayout();
if (!file_exists($path . 'files')) {
mkdir($path . 'files', 0777);
}
$result = true;
$result &= copy($jxmegalayout->css_layouts_path . $name . '.css', $path . 'files/' . $name . '.css');
$result &= copy($jxmegalayout->js_layouts_path . $name . '.js', $path . 'files/' . $name . '.js');
return $result;
}
/**
* @param $path
* @param $image_path
*
* @return bool
*/
protected function writeLayoutImage($path, $image_path)
{
if (!file_exists(_PS_IMG_DIR_ . $image_path)) {
return false;
}
if (!file_exists($path . 'images')) {
mkdir($path . 'images', 0777);
}
$this->createPath($path . 'images/', $image_path);
copy(_PS_IMG_DIR_ . $image_path, $path . 'images/' . $image_path);
return true;
}
protected function createPath($parent_path, $create_path)
{
$folders = explode('/', $create_path);
$new_path = $parent_path;
foreach ($folders as $folder) {
if (strstr($folder, '.')) {
continue;
}
if (!file_exists($new_path . $folder)) {
mkdir($new_path . $folder, 0777);
}
$new_path .= $folder . '/';
}
}
protected function archiveFolders($path, $ZipArchiveObj, $zip_path = '')
{
$files = scandir($path);
foreach ($files as $file) {
if ($file != '.' && $file != '..') {
if (is_dir($path . $file)) {
$ZipArchiveObj->addEmptyDir($zip_path . $file);
$new_zip_path = $zip_path . $file . '/';
$new_path = $path . $file . '/';
$this->archiveFolders($new_path, $ZipArchiveObj, $new_zip_path);
} else {
$ZipArchiveObj->addFile($path . $file, $zip_path . $file);
}
}
}
}
/**
* Make export archive
*
* @param string $path
* @param string $web_path
* @param string $file_name
* @return string path to export archive
*/
protected function writeLayoutZip($path, $temp_path, $web_path, $file_name)
{
$file_name = $file_name . '.zip';
if (file_exists($path . $file_name)) {
unlink($path . $file_name);
}
$zip = new ZipArchive();
if ($zip->open($path . $file_name, ZipArchive::OVERWRITE | ZipArchive::CREATE) !== true) {
$this->errors = $this->displayError(sprintf($this->l('cannot open %s'), $file_name));
}
$this->archiveFolders($temp_path, $zip);
$zip->close();
return $web_path . $file_name;
}
/**
* Generate archive to export by $id_layout
*
* @param int $id_layout
* @return string Path to export archive
*/
public function init($id_layout)
{
$obj = new Jxmegalayout();
$local_path = $obj->getLocalPath() . 'export/';
Jxmegalayout::cleanFolder($local_path);
$web_path = $obj->getWebPath() . 'export/';
$id_shop = $obj->getIdShop();
$temp_path = JXMegaLayoutImport::checkTempFolder($local_path);
$layout_name = $this->writeLayoutSettings($id_layout, $temp_path);
$this->writeLayoutGrid($id_layout, $temp_path, $id_shop);
$this->writeLayoutFiles($layout_name, $temp_path);
$export_zip = $this->writeLayoutZip($local_path, $temp_path, $web_path, $layout_name);
Jxmegalayout::cleanFolder($temp_path);
return $export_zip;
}
}

View File

@@ -0,0 +1,388 @@
<?php
/**
* 2017-2019 Zemez
*
* JX Mega Layout
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul & Alexander Pervakov)
* @copyright 2017-2019 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class JXMegaLayoutImport
{
protected $id_layout;
public static function checkTempFolder($path)
{
$temp_folder = $path . 'temp/';
if (!file_exists($temp_folder)) {
mkdir($temp_folder, 0777);
} else {
Jxmegalayout::cleanFolder($temp_folder);
}
return $temp_folder;
}
public static function isZip($file)
{
$file_extension = pathinfo($file, PATHINFO_EXTENSION);
if ($file_extension != 'zip') {
return false;
}
return true;
}
public function readSettings($path, $file_name = 'settings.json')
{
$file = $path . $file_name;
if (!file_exists($file)) {
return false;
}
$settings_json = Tools::file_get_contents($file);
return Tools::jsonDecode($settings_json, true);
}
/**
* Generate layout from getting data
*
* @param array $settings layout data info
* @param bool $def is one of default layouts(from folder "default")
* @param bool $new_name_layout new layout name if old was already existed
*
* @return int new layout id
*/
protected function createLayout($settings, $def = false, $new_name_layout = false)
{
$obj = new Jxmegalayout();
$id_shop = $obj->getIdShop();
$status = 0;
if ($def && (int)$settings['status'] == 1) {
$status = 1;
}
$layout = new JXMegaLayoutLayouts();
$layout->id_shop = $id_shop;
$layout->hook_name = $settings['hook'];
if (!$new_name_layout) {
$layout->layout_name = $settings['layout_name'];
} else {
$layout->layout_name = $new_name_layout;
}
$layout->status = $status;
$layout->save();
// assign layout to pages
if (isset($settings['pages']) && !Tools::isEmpty($settings['pages'])) {
$new_layout = new JXMegaLayoutLayouts($layout->id);
$new_layout->assignLayoutToPages($new_layout->hook_name, $settings['pages']);
}
return $layout->id;
}
protected function createLayoutItems($layout_items, $id_parent = null, $styles = array())
{
foreach ($layout_items as $item) {
if (!isset($id_parent)) {
$id_parent = 0;
}
$layout = new JXMegaLayoutItems();
$layout->id_parent = $id_parent;
$layout->id_layout = $this->id_layout;
$id_unique = 'it_' . Tools::passwdGen(12, 'NO_NUMERIC');
switch ($item['type']) {
case 'module':
$layout->type = $item['type'];
$layout->module_name = $item['module_name'];
$layout->specific_class = $item['specific_class'];
$layout->sort_order = $item['sort_order'];
$layout->id_unique = $id_unique;
$layout->extra_css = $item['extra_css'];
$layout->origin_hook = $item['origin_hook'];
break;
case 'wrapper':
$layout->type = $item['type'];
$layout->sort_order = $item['sort_order'];
$layout->specific_class = $item['specific_class'];
$layout->id_unique = $id_unique;
break;
case 'row':
$layout->type = $item['type'];
$layout->sort_order = $item['sort_order'];
$layout->specific_class = $item['specific_class'];
$layout->id_unique = $id_unique;
break;
case 'col':
$layout->type = $item['type'];
$layout->sort_order = $item['sort_order'];
$layout->specific_class = $item['specific_class'];
$layout->col = $item['col'];
$layout->col_xs = $item['col_xs'];
$layout->col_sm = $item['col_sm'];
$layout->col_md = $item['col_md'];
$layout->col_lg = $item['col_lg'];
$layout->col_xl = $item['col_xl'];
$layout->col_xxl = $item['col_xxl'];
$layout->id_unique = $id_unique;
break;
case 'block':
$layout->type = $item['type'];
$layout->module_name = $item['module_name'];
$layout->specific_class = $item['specific_class'];
$layout->sort_order = $item['sort_order'];
$layout->id_unique = $id_unique;
break;
case 'content':
$layout->type = $item['type'];
$layout->module_name = $item['module_name'];
$layout->specific_class = $item['specific_class'];
$layout->sort_order = $item['sort_order'];
$layout->id_unique = $id_unique;
break;
}
$styles[$id_unique] = $item['id_unique'];
$layout->add();
if ($item['child']) {
$styles = $this->createLayoutItems($item['child'], $layout->id, $styles);
}
}
return $styles;
}
protected function restoreLayoutMap($import_layouts, $map = array(), $id_parent = 0, $level = 0)
{
if (!$import_layouts) {
return $map;
}
foreach ($import_layouts as $layout) {
$layout['id_item'] = rand(1, 100000);
$child_layouts = $layout['child'];
$map[$level][$id_parent][] = $layout;
$map = $this->restoreLayoutMap($child_layouts, $map, $layout['id_item'], $level + 1);
}
return $map;
}
protected function getLayoutStyles($path, $styles)
{
if (count($styles) > 0) {
$style_obj = new Jxmegalayout();
$style_folder = $path . 'styles/';
$img_folder = $path . 'images/';
if (file_exists($style_folder)) {
foreach ($styles as $new_id => $old_id) {
if ($style_obj->checkUniqueStylesExists($old_id, $style_folder)) {
$style_content = $style_obj->getStylesContent($old_id, $style_folder);
$styles_enc = $style_obj->encodeStyles($style_content);
$style_obj->saveItemStyles($new_id, $styles_enc, $style_folder, true);
copy($style_folder . $new_id . '.css', $style_obj->style_path . $new_id . '.css');
}
}
}
$style_obj->combineAllItemsStyles();
if (file_exists($img_folder)) {
Jxmegalayout::recurseCopy($img_folder, _PS_IMG_DIR_);
}
}
}
protected function importModuleExtraCss($path, $unique_ids)
{
$obj = new Jxmegalayout();
foreach ($unique_ids as $new_id => $old_id) {
if (!is_dir($path.'files/modules/')) {
return true;
}
if (is_dir($path.'files/modules/'.$old_id) && $css = Tools::scandir($path.'files/modules/'.$old_id, 'css')) {
$css_path = $obj->localPath().'views/css/items/modules/';
if (!file_exists($css_path)) {
mkdir($css_path, 0777);
}
if (!file_exists($css_path.$new_id)) {
mkdir($css_path.$new_id, 0777);
}
foreach ($css as $file) {
copy($path.'files/modules/'.$old_id.'/'.$file, $css_path.'/'.$new_id.'/'.$file);
}
}
}
}
public function layoutPreview($path, $file_name, $rawData = false)
{
$lang = new Jxmegalayout();
$errors = null;
if (JXMegaLayoutImport::isZip($path . $file_name)) {
$temp_folder = $this->checkTempFolder($path);
$zip = new ZipArchive();
$zip->open($path . $file_name);
$zip->extractTo($temp_folder);
if (!$layout_items = $this->readSettings($temp_folder, 'grid.json')) {
$errors = $lang->displayError($lang->l('Grid file is missing'));
}
$map = $this->restoreLayoutMap($layout_items);
$render = new Jxmegalayout();
if (!$layout_settings = $this->readSettings($temp_folder)) {
$errors .= $lang->displayError($lang->l('Settings file is missing'));
}
if ($errors != null) {
if ($rawData) {
return array('errors' => $errors);
}
Context::getContext()->smarty->assign(array(
'error' => $errors
));
} else {
if (!isset($layout_settings['version'])) {
$version = false;
} else {
$version = $layout_settings['version'];
}
Context::getContext()->smarty->assign(array(
'layout_preview' => $render->renderLayoutAdmin($map, true),
'layout_name' => $layout_settings['layout_name'],
'hook_name' => $layout_settings['hook'],
'pages' => implode(', ', array_keys($layout_settings['pages'])),
'compatibility' => $this->checkCompatibility($version)
));
if ((bool)JXMegaLayoutLayouts::getLayoutByName($layout_settings['layout_name'])) {
Context::getContext()->smarty->assign(array(
'check_name' => false,
));
}
if ($rawData) {
return array(
'layout_preview' => $render->renderLayoutAdmin($map, true),
'layout_name' => $layout_settings['layout_name'],
'hook_name' => $layout_settings['hook'],
'pages' => implode(', ', array_keys($layout_settings['pages'])),
'compatibility' => $this->checkCompatibility($version),
'check_name' => !(bool)JXMegaLayoutLayouts::getLayoutByName($layout_settings['layout_name']),
'errors' => $errors
);
}
}
return $lang->display($lang->getLocalPath(), 'views/templates/admin/tools/import-preview.tpl');
} else {
Context::getContext()->smarty->assign(array(
'error' => $lang->displayError($lang->l('Layout archive must have zip format'))
));
return $lang->display($lang->getLocalPath(), 'views/templates/admin/tools/import-preview.tpl');
}
}
/**
* Write layout js and css files
*
* @param string $old_name
* @param string $name
* @param string $path
* @return bool
*/
protected function writeLayoutFiles($old_name, $name, $path)
{
$obj = new Jxmegalayout();
if (!file_exists($obj->css_layouts_path)) {
mkdir($obj->css_layouts_path, 0777);
}
if (!file_exists($obj->js_layouts_path)) {
mkdir($obj->js_layouts_path, 0777);
}
$result = true;
$result &= copy($path . 'files/' . $old_name . '.css', $obj->css_layouts_path . $name . '.css');
$result &= copy($path . 'files/' . $old_name . '.js', $obj->js_layouts_path . $name . '.js');
return $result;
}
/**
* @param string $path path to import
* @param string $file_name name of the archive
* @param bool $def is this layout default(from "default" folder)
* @param string $name_layout layout name
*
* @return bool|string result
*/
public function importLayout($path, $file_name, $def = false, $name_layout = false)
{
$temp_folder = JXMegaLayoutImport::checkTempFolder($path);
$lang = new Jxmegalayout();
if (JXMegaLayoutImport::isZip($path . $file_name)) {
$zip = new ZipArchive();
$zip->open($path . $file_name);
$zip->extractTo($temp_folder);
if (!$settings = $this->readSettings($temp_folder)) {
return false;
}
if (!$name_layout) {
$name_layout = $settings['layout_name'];
}
if (!$this->id_layout = $this->createLayout($settings, $def, $name_layout)) {
return false;
}
$layout_items = $this->readSettings($temp_folder, 'grid.json');
$styles = $this->createLayoutItems($layout_items);
$this->writeLayoutFiles($settings['layout_name'], $name_layout, $temp_folder);
$this->getLayoutStyles($temp_folder, $styles);
$this->importModuleExtraCss($temp_folder, $styles);
Jxmegalayout::cleanFolder($temp_folder);
return true;
} elseif ($def) {
return true;
} else {
return $lang->displayError($lang->l('Layout archive must have zip format'));
}
}
protected function checkCompatibility($version)
{
$jxmegalayout = new Jxmegalayout();
if (!$version || Tools::version_compare($version, '1.0', '<')) {
return $jxmegalayout->displayError($jxmegalayout->l('This layout archive is not supported'));
}
return false;
}
}

View File

@@ -0,0 +1,168 @@
<?php
/**
* 2017-2019 Zemez
*
* JX Mega Layout
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul & Alexander Pervakov)
* @copyright 2017-2019 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class JXMegaLayoutItems extends ObjectModel
{
public $id_item;
public $id_layout;
public $id_parent;
public $type;
public $sort_order;
public $col;
public $col_xs;
public $col_sm;
public $col_md;
public $col_lg;
public $col_xl;
public $col_xxl;
public $module_name;
public $specific_class;
public $id_unique;
public $origin_hook;
public $extra_css;
public static $definition = array(
'table' => 'jxmegalayout_items',
'primary' => 'id_item',
'multilang' => false,
'fields' => array(
'id_layout' => array('type' => self::TYPE_INT, 'required' => true, 'validate' => 'isunsignedInt'),
'id_parent' => array('type' => self::TYPE_INT, 'required' => true, 'validate' => 'isunsignedInt'),
'sort_order' => array('type' => self::TYPE_INT, 'required' => true, 'validate' => 'isunsignedInt'),
'type' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 128),
'col' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 128),
'col_xs' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 128),
'col_sm' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 128),
'col_md' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 128),
'col_lg' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 128),
'col_xl' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 128),
'col_xxl' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 128),
'module_name' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 128),
'specific_class' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 128),
'id_unique' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 128),
'origin_hook' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 128),
'extra_css' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 128)
),
);
public function delete()
{
$res = true;
$jxmegalayout = new Jxmegalayout();
$res &= $jxmegalayout->deleteItemStyles($this->id_unique, true);
if ($res) {
$res &= parent::delete();
}
return $res;
}
/**
* Get all items for layout
*
* @param int $id_layout
* @return array items ids or false
*/
public static function getItems($id_layout)
{
$sql = 'SELECT *
FROM ' . _DB_PREFIX_ . 'jxmegalayout_items
WHERE `id_layout` = ' . (int)$id_layout;
if (!$result = Db::getInstance()->executeS($sql)) {
return false;
}
return $result;
}
/**
* Get all items unique IDs related to current shop
*
* @return $ids array of all ids
*/
public static function getShopItemsStyles()
{
$ids = array();
$sql = 'SELECT tl.`id_unique`, tl.`id_item`
FROM ' . _DB_PREFIX_ . 'jxmegalayout_items tl
JOIN ' . _DB_PREFIX_ . 'jxmegalayout t
ON(t.`id_layout`=tl.`id_layout`)
LEFT JOIN ' . _DB_PREFIX_ . 'jxmegalayout_pages tp
ON(t.`id_layout`=tp.`id_layout`)
WHERE t.`id_shop` = '.Context::getContext()->shop->id.'
AND (t.`status` = 1 OR tp.`status` = 1)';
if (!$unique_ids = Db::getInstance()->executeS($sql)) {
return false;
}
foreach ($unique_ids as $id_unique) {
$ids[$id_unique['id_item']] = $id_unique['id_unique'];
}
return $ids;
}
/**
* Get modules list used in layout.
* UPD: v 1.3.1: added origin_hook to allow duplicating modules in one abstract position
* in order to use the same module with different content
*
* @param int $id_layout
*
*@return array|bool
*/
public static function checkModuleInLayout($id_layout)
{
$list = array();
$sql = 'SELECT `module_name`, `origin_hook`
FROM ' . _DB_PREFIX_ . 'jxmegalayout_items
WHERE `id_layout` =' . $id_layout;
if (!$result = Db::getInstance()->executeS($sql)) {
return false;
}
foreach ($result as $module_name) {
if (!Tools::isEmpty($module_name['module_name'])) {
$list[] = $module_name['module_name'].'-'.$module_name['origin_hook'];
}
}
return $list;
}
public static function getItemCssByUniqueId($unique_id)
{
$sql = 'SELECT `extra_css`
FROM '._DB_PREFIX_.'jxmegalayout_items
WHERE `id_unique` = "'.pSql($unique_id).'"';
return Db::getInstance()->getValue($sql);
}
}

View File

@@ -0,0 +1,372 @@
<?php
/**
* 2017-2019 Zemez
*
* JX Mega Layout
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul & Alexander Pervakov)
* @copyright 2017-2019 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class JXMegaLayoutLayouts extends ObjectModel
{
public $id_layout;
public $hook_name;
public $id_shop;
public $status;
public $layout_name;
public static $definition = array(
'table' => 'jxmegalayout',
'primary' => 'id_layout',
'multilang' => false,
'fields' => array(
'hook_name' => array('type' => self::TYPE_STRING, 'required' => true, 'validate' => 'isGenericName'),
'id_shop' => array('type' => self::TYPE_INT, 'required' => true, 'validate' => 'isunsignedInt'),
'layout_name' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 128),
'status' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
),
);
/**
* Get active layout id
*
* @param int $id_hook
* @param int $id_shop
* @return (int) layout id or false
*/
public static function getActiveLayoutId($hook_name, $id_shop)
{
$sql = 'SELECT *
FROM ' . _DB_PREFIX_ . 'jxmegalayout
WHERE `hook_name` = "' . pSql($hook_name) .'"
AND `id_shop` ='. (int)$id_shop.'
AND `status` = 1';
if (!$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql)) {
return false;
}
return $result;
}
/**
* Get all hook's layouts
*
* @param int $id_hook
* @param int $id_shop
* @return array layouts id or false
*/
public static function getLayoutsForHook($hook_name, $id_shop)
{
$sql = 'SELECT *
FROM ' . _DB_PREFIX_ . 'jxmegalayout
WHERE `hook_name` = "' . pSql($hook_name) . '"
AND `id_shop` ='. (int)$id_shop;
if (!$layouts = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql)) {
return false;
}
foreach ($layouts as $key => $layout) {
if ($subPages = Db::getInstance()->executeS('SELECT `page_name` FROM '._DB_PREFIX_.'jxmegalayout_pages WHERE `id_layout` = '.(int)$layout['id_layout'])) {
$layouts[$key]['subpages'] = $subPages;
} else {
$layouts[$key]['subpages'] = false;
}
}
return $layouts;
}
/**
* Get layout info by name,
* check if layout already exists with same name
*
* @param string $layout_name
* @return bool|array layout info or false
*/
public static function getLayoutByName($layout_name)
{
$sql = 'SELECT *
FROM ' . _DB_PREFIX_ . 'jxmegalayout
WHERE `layout_name` = "'.pSql($layout_name).'"';
if (!$result = Db::getInstance()->executeS($sql)) {
return false;
}
return $result;
}
/**
* Get active layout name
*
* @return array active layout name
*/
public static function getActiveLayouts()
{
$list = array();
$sql = 'SELECT `id_layout`, `layout_name`, `hook_name`, `status`
FROM ' . _DB_PREFIX_ . 'jxmegalayout
WHERE `id_shop` = '.(int)Context::getContext()->shop->id;
foreach (Db::getInstance()->executeS($sql) as $layout) {
$list[$layout['layout_name']]['hook_name'] = $layout['hook_name'];
if ($layout['status']) {
$list[$layout['layout_name']]['status'] = 1;
$list[$layout['layout_name']]['pages'] = '';
} else {
$list[$layout['layout_name']]['status'] = 0;
$list[$layout['layout_name']]['pages'] = false;
$sql1 = 'SELECT `page_name`
FROM '._DB_PREFIX_.'jxmegalayout_pages
WHERE `id_layout` = '.(int)$layout['id_layout'].'
AND `status` = 1';
if ($pages = Db::getInstance()->executeS($sql1)) {
foreach ($pages as $page) {
$list[$layout['layout_name']]['pages'][] = $page['page_name'];
}
}
}
}
return $list;
}
/**
* Get layout name
*
* @param int $id_layout
* @return array layout name
*/
public static function getLayoutName($id_layout)
{
$sql = 'SELECT `layout_name`
FROM ' . _DB_PREFIX_ . 'jxmegalayout
WHERE `id_layout` = '.(int)$id_layout;
if (!$result = Db::getInstance()->getValue($sql)) {
return false;
}
return $result;
}
/**
* Get all layouts for shop
*
* @return array shop layouts id or false
*/
public static function getShopLayoutsIds()
{
$sql = 'SELECT `id_layout`
FROM '._DB_PREFIX_.'jxmegalayout
WHERE `id_shop` = '.(int)Context::getContext()->shop->id;
if (!$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql)) {
return false;
}
return $result;
}
/**
* Activate layout for different pages
* @param array $pages pages name
* @param string $hook_name related hook name
* @param int $status status of layout for this pages
* @return bool result
*/
public function setLayoutToPage($pages, $hook_name, $status = 0)
{
if ($this->dropLayoutFromPages()) {
foreach ($pages as $page_name) {
$this->addLayoutToPage($page_name, $hook_name, $status);
}
}
}
/**
* Add layout to page
* @param $page_name string name of the page
* @param string $hook_name related hook name
* @param int $status status of layout for this pages
* @return bool result
*/
protected function addLayoutToPage($page_name, $hook_name, $status = 0)
{
if ($status) {
$this->dropActivePageLayout($page_name, $hook_name);
}
return Db::getInstance()->insert(
'jxmegalayout_pages',
array(
'id_layout' => (int)$this->id,
'id_shop'=> (int)$this->id_shop,
'page_name'=> pSql($page_name),
'status' => (int)$status
)
);
}
/**
* Remove layout from all pages
* @return bool
*/
public function dropLayoutFromPages()
{
return Db::getInstance()->delete(
'jxmegalayout_pages',
'`id_shop` = '.(int)$this->id_shop.' AND `id_layout` = '.(int)$this->id
);
}
/**
* Drop active page layout
* because can't be two active layouts
* and maybe this page related with another layout
* which is steel active
* @param $page_name
* @param string $hook_name related hook name
*
* @return bool
*/
protected function dropActivePageLayout($page_name, $hook_name)
{
// get related hook's ids to know which ones to drop
$related_hooks_layouts = $this->getLayoutsForHook($hook_name, $this->id_shop);
$related_hooks_layouts_ids = array();
foreach ($related_hooks_layouts as $layout) {
$related_hooks_layouts_ids[] = $layout['id_layout'];
}
return Db::getInstance()->delete(
'jxmegalayout_pages',
'`page_name` = "'.pSql($page_name).'"
AND `id_layout` IN ('.implode(', ', $related_hooks_layouts_ids).')
AND `status` = 1'
);
}
/**
* Disable this layout for all available pages
* @return bool
*/
public function disableLayoutForAllPages()
{
return Db::getInstance()->update(
'jxmegalayout_pages',
array('status' => 0),
'`id_layout` = '.(int)$this->id.' AND `id_shop` = '.(int)$this->id_shop
);
}
/**
* Get pages that are assigned this layout
* @param bool $active only active items
* @return array $list
* @throws PrestaShopDatabaseException
*/
public function getAssignedPages($active = false)
{
$query = '';
if ($active) {
$query = ' AND `status` = 1';
}
$list = array();
$sql = 'SELECT `page_name`
FROM '._DB_PREFIX_.'jxmegalayout_pages
WHERE `id_layout` = '.(int)$this->id.'
AND `id_shop` = '.(int)$this->id_shop.$query;
foreach (Db::getInstance()->executeS($sql) as $page) {
$list[] = $page['page_name'];
}
return $list;
}
/**
* Get all layout pages for export
* @return array|false
*/
public function getAllLayoutPages()
{
$list = array();
$sql = 'SELECT `page_name`, `status`
FROM '._DB_PREFIX_.'jxmegalayout_pages
WHERE `id_layout` = '.(int)$this->id.'
AND `id_shop` = '.(int)$this->id_shop;
if ($result = Db::getInstance()->executeS($sql)) {
foreach ($result as $page) {
$list[$page['page_name']] = $page['status'];
}
return $list;
}
return false;
}
/**
* Get active layout for current page if assigned
* @param $hook_name
* @param $page_name
* @param $id_shop
* @return false|null|string
*/
public static function getPageActiveLayoutId($hook_name, $page_name, $id_shop)
{
$sql = 'SELECT jxl.`id_layout`
FROM '._DB_PREFIX_.'jxmegalayout jxl
LEFT JOIN '._DB_PREFIX_.'jxmegalayout_pages jxlp
ON(jxl.`id_layout` = jxlp.`id_layout`)
WHERE jxlp.`page_name` = "'.pSql($page_name).'"
AND jxl.`id_shop` = '.(int)$id_shop.'
AND jxl.`hook_name` = "'.pSql($hook_name).'"
AND jxlp.`status` = 1';
return Db::getInstance()->getValue($sql);
}
public static function getActiveSubpageId($hook_name, $id_shop)
{
$sql = 'SELECT jxl.`id_layout`
FROM '._DB_PREFIX_.'jxmegalayout_pages jxlp
LEFT JOIN '._DB_PREFIX_.'jxmegalayout jxl
ON(jxlp.`id_layout` = jxl.`id_layout`)
AND jxl.`id_shop` = '.(int)$id_shop.'
AND jxl.`hook_name` = "'.pSql($hook_name).'"
AND jxlp.`status` = 1
ORDER BY jxl.`id_layout`';
return Db::getInstance()->getValue($sql);
}
public function assignLayoutToPages($hook_name, $pages)
{
if ($pages) {
foreach ($pages as $name => $status) {
$this->addLayoutToPage($name, $hook_name, $status);
}
}
}
}

View File

@@ -0,0 +1,381 @@
<?php
/**
* 2017-2019 Zemez
*
* JX Mega Layout
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul & Alexander Pervakov)
* @copyright 2017-2019 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class JXMegaLayoutOptimize
{
/**
* @var Jxmegalayout
*/
protected $jxmegalayout;
/**
* @var int
*/
protected $id_shop;
/**
* @var array
*/
protected $origin_hooks;
/**
* JXMegaLayoutOptimize constructor.
*/
public function __construct()
{
$this->jxmegalayout = new Jxmegalayout();
$this->id_shop = $this->jxmegalayout->getIdShop();
$this->origin_hooks = $this->getOriginHooks();
}
/**
* @return array result
*/
protected function getOriginHooks()
{
$origin_hooks = array();
foreach ($this->jxmegalayout->defLayoutHooks as $hook) {
if (isset($hook['hooks']) && $hook['hooks']) {
foreach ($hook['hooks'] as $origin_hook) {
$origin_hooks[] = $origin_hook;
}
}
}
return $origin_hooks;
}
/**
* Optimize styles and scripts
*/
public function optimize()
{
$this->deoptimize();
$modules = $this->getAllModules();
$id_header = Hook::getIdByName('displayHeader');
foreach ($modules as $module) {
$module_obj = Module::getInstanceById($module['id_module']);
if (!$this->checkModuleInFrontHooks($module_obj)) {
$pages = $this->checkModuleInLayouts($module_obj);
if (count($pages) > 0) {
$this->editExceptions($module_obj, $id_header, $this->id_shop, $pages);
}
}
}
}
/**
* Deoptimize styles and scripts
*/
public function deoptimize()
{
$this->unregisterExceptions();
}
/**
* Get all modules for hooks
*
* @return array All modules
*/
protected function getAllModules()
{
return Hook::getHookModuleExecList('displayHeader');
}
/**
* Get all front controllers
*
* @return array All front controllers
*/
protected function getMainControllers()
{
$controllers = array();
$front_controllers = Dispatcher::getControllers(_PS_FRONT_CONTROLLER_DIR_);
$controllers['subpages'] = 'subpages';
foreach (array_keys($front_controllers) as $key) {
$controllers[$key] = $key;
}
return $controllers;
}
/**
* Register ner module excepts
*
* @param object $module Module object
* @param int $id_hook Hook id
* @param int $id_shop Shop id
* @param array $excepts Module excepts
*
* @return bool result
* @throws PrestaShopDatabaseException
*/
protected function registerExceptions($module, $id_hook, $id_shop, $excepts)
{
foreach ($excepts as $except) {
if (!$except) {
continue;
}
$sql = 'SELECT * FROM '. _DB_PREFIX_ .'hook_module_exceptions
WHERE `id_shop` = '.(int)$id_shop.'
AND `id_module` = '.(int)$module->id.'
AND `id_hook` = '.(int)$id_hook.'
AND `file_name` = "'.pSQL($except).'"';
if (!Db::getInstance()->executeS($sql)) {
$insert_exception = array(
'id_module' => (int)$module->id,
'id_hook' => (int)$id_hook,
'id_shop' => (int)$id_shop,
'file_name' => pSQL($except),
);
if (Db::getInstance()->insert('hook_module_exceptions', $insert_exception)) {
$insert_exception = array(
'id_exceptions' => (int)Db::getInstance()->Insert_ID(),
);
if (!Db::getInstance()->insert('jxmegalayout_hook_module_exceptions', $insert_exception)) {
return false;
}
}
}
}
return true;
}
/**
* Unregister module excepts
*
* @return bool result
*/
protected function unregisterExceptions()
{
$sql = 'DELETE he.*, jx.*
FROM '. _DB_PREFIX_ .'jxmegalayout_hook_module_exceptions AS jx
INNER JOIN '. _DB_PREFIX_ .'hook_module_exceptions AS he
ON he.id_hook_module_exceptions=jx.id_exceptions
WHERE he.id_shop='.$this->id_shop;
if (!Db::getInstance()->query($sql)) {
return false;
}
return true;
}
/**
* @param object $module Module object
* @param int $id_hook Hook id
* @param int $id_shop Shop id
* @param array $excepts Module excepts
*
* @return bool result
*/
protected function editExceptions($module, $id_hook, $id_shop, $excepts)
{
$result = true;
$result &= $this->registerExceptions($module, $id_hook, $id_shop, $excepts);
return $result;
}
/**
* Check module in front hooks
* @param object $module Module object
*
* @return bool
*/
protected function checkModuleInFrontHooks($module)
{
$hooks = $module->getPossibleHooksList();
foreach ($hooks as $key => $hook) {
if ((string)stripos($hook['name'], 'action') != '0' && !$this->checkHookDif($this->origin_hooks, $hook['name']) && $hook['name'] != 'Header') {
if (count(Hook::getModulesFromHook($hook['id_hook'], $module->id)) == 0) {
unset($hooks[$key]);
}
} else {
unset($hooks[$key]);
}
}
if (count($hooks) == 0) {
return false;
}
return true;
}
/**
* Check module on page
*
* @param object $module Module object
*
* @return array Return pages
*/
protected function checkModuleInLayouts($module)
{
$result = array();
$hooks = $this->getModuleOriginHooks($module);
$controllers = $this->getMainControllers();
if ($this->checkModuleInAllPages($module, $hooks)) {
return array();
} else {
foreach ($controllers as $page) {
if ($this->checkModuleOnPage($module, $page, $hooks)) {
if ($page == 'subpages') {
unset($controllers);
$controllers['index'] = 'index';
} else {
unset($controllers[$page]);
}
} else {
if ($page != 'subpages') {
$result[$page] = $page;
} else {
unset($controllers['index']);
$result = array_merge($controllers);
unset($controllers);
$controllers['index'] = 'index';
}
}
}
}
return $result;
}
/**
* Check word in array
*
* @param array $hooks Array of hooks
* @param string $needle
*
* @return bool result
*/
protected function checkHookDif($hooks, $needle)
{
foreach ($hooks as $value) {
if ($value == $needle) {
return true;
}
}
return false;
}
/**
* Check module in origin hook
*
* @param object $module Module object
* @param string $hook Hook name
*
* @return bool result
*/
protected function checkModuleInOriginHook($module, $hook)
{
foreach ($this->jxmegalayout->defLayoutHooks[$hook]['hooks'] as $origin_hook) {
$id_hook = Hook::getIdByName($origin_hook);
if (count(Hook::getModulesFromHook($id_hook, $module->id)) != 0) {
return true;
}
}
return false;
}
/**
* Check module in origin hooks
*
* @param object $module
*
* @return array result
*/
protected function getModuleOriginHooks($module)
{
$hooks = $this->jxmegalayout->defLayoutHooks;
foreach (array_keys($hooks) as $hook_name) {
if (!$this->checkModuleInOriginHook($module, $hook_name)) {
unset($hooks[$hook_name]);
}
}
return $hooks;
}
/**
* Check module on all pages
*
* @param object $module
* @param array $hooks
*
* @return bool result
*/
protected function checkModuleInAllPages($module, $hooks)
{
foreach (array_keys($hooks) as $hook_name) {
if ($active_layout = JXMegaLayoutLayouts::getActiveLayoutId($hook_name, $this->id_shop)) {
if ($module_list = JXMegaLayoutItems::checkModuleInLayout($active_layout)) {
if (in_array($module->name, $module_list)) {
return true;
}
}
}
}
return false;
}
/**
* Check module on page
*
* @param object $module
* @param string $page
* @param array$hooks
*
* @return bool result
*/
protected function checkModuleOnPage($module, $page, $hooks)
{
foreach (array_keys($hooks) as $hook_name) {
if ($id_layout = JXMegaLayoutLayouts::getPageActiveLayoutId($hook_name, $page, $this->id_shop)) {
if ($module_list = JXMegaLayoutItems::checkModuleInLayout($id_layout)) {
if (in_array($module->name, $module_list)) {
return true;
}
}
} else {
if ($active_layout = JXMegaLayoutLayouts::getActiveLayoutId($hook_name, $this->id_shop)) {
if ($module_list = JXMegaLayoutItems::checkModuleInLayout($active_layout)) {
if (!in_array($module->name, $module_list)) {
return false;
}
}
}
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,8 @@
drwxr-xr-x 2 30094 users 8 Oct 6 10:16 .
drwxr-xr-x 4 30094 users 9 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 2686 Aug 31 2021 JXMegaLayoutExtraBanner.php
-rw-r--r-- 1 30094 users 9368 Aug 31 2021 JXMegaLayoutExtraExport.php
-rw-r--r-- 1 30094 users 2419 Aug 31 2021 JXMegaLayoutExtraHtml.php
-rw-r--r-- 1 30094 users 13569 Aug 31 2021 JXMegaLayoutExtraImport.php
-rw-r--r-- 1 30094 users 8675 Aug 31 2021 JXMegaLayoutExtraSlider.php
-rw-r--r-- 1 30094 users 2540 Aug 31 2021 JXMegaLayoutExtraVideo.php

View File

@@ -0,0 +1,76 @@
<?php
/**
* 2017-2019 Zemez
*
* JX Mega Layout
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul & Alexander Pervakov)
* @copyright 2017-2019 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class JXMegaLayoutExtraBanner extends ObjectModel
{
public $name;
public $link;
public $img;
public $content;
public $specific_class;
public static $definition = array(
'table' => 'jxmegalayout_extra_banner',
'primary' => 'id_extra_banner',
'multilang' => true,
'fields' => array(
'name' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'required' => true, 'lang' => true),
'link' => array('type' => self::TYPE_STRING, 'validate' => 'isUrl', 'lang' => true),
'img' => array('type' => self::TYPE_STRING, 'validate' => 'isUrl', 'lang' => true),
'content' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml', 'size' => 4000),
'specific_class' => array('type' => self::TYPE_STRING, 'validate' => 'isCleanHtml', 'size' => 128)
),
);
/**
* Get the list of all available banners
*
* @param $id_lang
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public static function getList($id_lang)
{
return Db::getInstance()->executeS('
SELECT *, jeb.`id_extra_banner` as `id`
FROM '._DB_PREFIX_.'jxmegalayout_extra_banner jeb
LEFT JOIN '._DB_PREFIX_.'jxmegalayout_extra_banner_lang jebl
ON(jeb.`id_extra_banner` = jebl.`id_extra_banner`)
WHERE jebl.`id_lang` = '.(int)$id_lang);
}
public static function getItem($id_item, $id_lang)
{
return Db::getInstance()->getRow('
SELECT jeb.*, jebl.*
FROM '._DB_PREFIX_.'jxmegalayout_extra_banner jeb
LEFT JOIN '._DB_PREFIX_.'jxmegalayout_extra_banner_lang jebl
ON(jeb.`id_extra_banner` = jebl.`id_extra_banner`)
WHERE jeb.`id_extra_banner` = '.(int)$id_item.'
AND jebl.`id_lang` = '.(int)$id_lang);
}
}

View File

@@ -0,0 +1,253 @@
<?php
/**
* 2017-2019 Zemez
*
* JX Mega Layout
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul & Alexander Pervakov)
* @copyright 2017-2019 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class JXMegaLayoutExtraExport
{
protected $temporaryPath;
protected $webPath;
protected $context;
protected $defaultLanguage;
protected $languages;
public function __construct($path, $webPath)
{
$this->context = Context::getContext();
$this->languages = Language::getLanguages(true);
$this->defaultLanguage = Language::getLanguage(Configuration::get('PS_LANG_DEFAULT'));
$this->temporaryPath = $path;
$this->webPath = $webPath;
}
/**
* Initialization of extra content generation
*
* @return string a href to a generated archive
*/
public function export()
{
$extraContent = array();
// result href is empty by default
$href = '';
// check out if a temporary path exists before generation has begun
// if not then create the path and continue a generation
// if yes then clear all old files before new ones generation
if ($this->checkTemporaryPath()) {
// assemble all extra content information to one array
$extraContent = $this->collectExtraContent();
}
// if any extra content exists then begin to generate json files with all related information
if ($extraContent) {
// if files were generated successfully then check if media files exist and copy them
if ($this->generateExtraContentExportData($extraContent)) {
$this->exportExtraContentMedia();
}
// generate an archive with necessary data and get its path
$href = $this->prepareArchive();
}
return $href;
}
/**
* Check if temporary folder has is already exists
* if yes clear it if not create it
*
* @return string
*/
protected function checkTemporaryPath()
{
$temp_folder = $this->temporaryPath.'export/temp/';
if (!file_exists($temp_folder)) {
mkdir($temp_folder, 0777);
} else {
Jxmegalayout::cleanFolder($temp_folder);
}
return $temp_folder;
}
/**
* Get information about all extra content and collect it into an one archive
* First level of the archive is a content type(videos, html etc.)
* Second level is an element id
* Third level is a default item information or "LANGUAGES" if there are more then one
* If "LANGUAGES" exists then next level is a language ISO code with an item information related to the language
*
* @return array an array that contain all extra content information
*/
protected function collectExtraContent()
{
$collectedExtraContent = array();
if ($extraHtml = JXMegaLayoutExtraHtml::getList($this->context->language->id)) {
foreach ($extraHtml as $html) {
$collectedExtraContent['html'][$html['id_extra_html']]['default'] = JXMegaLayoutExtraHtml::getItem($html['id_extra_html'], $this->defaultLanguage['id_lang']);
if (count($this->languages) > 1) {
foreach ($this->languages as $language) {
$collectedExtraContent['html'][$html['id_extra_html']]['languages'][$language['iso_code']] = JXMegaLayoutExtraHtml::getItem($html['id_extra_html'], $language['id_lang']);
}
}
}
}
if ($extraBanners = JXMegaLayoutExtraBanner::getList($this->context->language->id)) {
foreach ($extraBanners as $banner) {
$collectedExtraContent['banners'][$banner['id_extra_banner']]['default'] = JXMegaLayoutExtraBanner::getItem($banner['id_extra_banner'], $this->defaultLanguage['id_lang']);
if (count($this->languages) > 1) {
foreach ($this->languages as $language) {
$collectedExtraContent['banners'][$banner['id_extra_banner']]['languages'][$language['iso_code']] = JXMegaLayoutExtraBanner::getItem($banner['id_extra_banner'], $language['id_lang']);
}
}
}
}
if ($extraVideos = JXMegaLayoutExtraVideo::getList($this->context->language->id)) {
foreach ($extraVideos as $video) {
$collectedExtraContent['videos'][$video['id_extra_video']]['default'] = JXMegaLayoutExtraVideo::getItem($video['id_extra_video'], $this->defaultLanguage['id_lang']);
if (count($this->languages) > 1) {
foreach ($this->languages as $language) {
$collectedExtraContent['videos'][$video['id_extra_video']]['languages'][$language['iso_code']] = JXMegaLayoutExtraVideo::getItem($video['id_extra_video'], $language['id_lang']);
}
}
}
}
if ($extraSliders = JXMegaLayoutExtraSlider::getList($this->context->language->id)) {
foreach ($extraSliders as $slider) {
$collectedExtraContent['sliders'][$slider['id_extra_slider']]['default'] = JXMegaLayoutExtraSlider::getItem($slider['id_extra_slider'], $this->defaultLanguage['id_lang']);
if (count($this->languages) > 1) {
foreach ($this->languages as $language) {
$collectedExtraContent['sliders'][$slider['id_extra_slider']]['languages'][$language['iso_code']] = JXMegaLayoutExtraSlider::getItem($slider['id_extra_slider'], $language['id_lang']);
}
}
if ($slides = JXMegaLayoutExtraSlider::getSliderSlides($slider['id_extra_slider'])) {
$collectedExtraContent['sliders'][$slider['id_extra_slider']]['slides'] = $slides;
}
}
}
return $collectedExtraContent;
}
/**
* Create and fill extra content data files based on extra content information
*
* @param array $extraContentArray
*
* @return bool
*/
protected function generateExtraContentExportData(array $extraContentArray)
{
$path = $this->temporaryPath.'export/temp/';
foreach ($extraContentArray as $key => $item) {
$file = fopen($path.$key.'.json', 'w');
fwrite($file, json_encode($item, JSON_UNESCAPED_UNICODE)); // JSON_UNESCAPED_UNICODE is used to avoid encoding issues
fclose($file);
}
return true;
}
/**
* Copy extra content media files to a source archive
*
* @return bool
*/
protected function exportExtraContentMedia()
{
$mediaPath = $this->temporaryPath.'extracontent/';
$tempPath = $this->temporaryPath.'export/temp/media/';
if (!file_exists($tempPath)) {
mkdir($tempPath, 0777);
}
$media = array_merge(
Tools::scandir($mediaPath, 'jpg'),
Tools::scandir($mediaPath, 'png'),
Tools::scandir($mediaPath, 'gif'),
Tools::scandir($mediaPath, 'jpeg')
);
if ($media) {
foreach ($media as $item) {
copy($mediaPath.$item, $tempPath.$item);
}
}
return true;
}
/**
* Create an archive internal structure
*
* @param $path
* @param $ZipArchiveObj
* @param string $zip_path
*/
protected function archiveFolders($path, $ZipArchiveObj, $zip_path = '')
{
$files = scandir($path);
foreach ($files as $file) {
if ($file != '.' && $file != '..') {
if (is_dir($path . $file)) {
$ZipArchiveObj->addEmptyDir($zip_path . $file);
$new_zip_path = $zip_path . $file . '/';
$new_path = $path . $file . '/';
$this->archiveFolders($new_path, $ZipArchiveObj, $new_zip_path);
} else {
$ZipArchiveObj->addFile($path . $file, $zip_path . $file);
}
}
}
}
/**
* Make export archive
*
* @return string path to export archive
*/
protected function prepareArchive()
{
$fileName = 'extracontent.zip';
$path = $this->temporaryPath.'export/';
if (file_exists($path.$fileName)) {
unlink($path.$fileName);
}
$zip = new ZipArchive();
if ($zip->open($path.$fileName, ZipArchive::OVERWRITE | ZipArchive::CREATE) !== true) {
$this->errors = $this->displayError(sprintf($this->l('cannot open %s'), $fileName));
}
$this->archiveFolders($path.'temp/', $zip);
$zip->close();
return $this->webPath.'export/'.$fileName;
}
}

View File

@@ -0,0 +1,73 @@
<?php
/**
* 2017-2019 Zemez
*
* JX Mega Layout
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul & Alexander Pervakov)
* @copyright 2017-2019 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class JXMegaLayoutExtraHtml extends ObjectModel
{
public $name;
public $content;
public $specific_class;
public static $definition = array(
'table' => 'jxmegalayout_extra_html',
'primary' => 'id_extra_html',
'multilang' => true,
'fields' => array(
'name' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'required' => true, 'lang' => true),
'content' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml', 'size' => 4000),
'specific_class' => array('type' => self::TYPE_STRING, 'validate' => 'isCleanHtml', 'size' => 128)
),
);
/**
* Get the list of all available HTML blocks
*
* @param $id_lang
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public static function getList($id_lang)
{
return Db::getInstance()->executeS('
SELECT *, jeh.`id_extra_html` as `id`
FROM '._DB_PREFIX_.'jxmegalayout_extra_html jeh
LEFT JOIN '._DB_PREFIX_.'jxmegalayout_extra_html_lang jehl
ON(jeh.`id_extra_html` = jehl.`id_extra_html`)
WHERE jehl.`id_lang` = '.(int)$id_lang);
}
public static function getItem($id_item, $id_lang)
{
return Db::getInstance()->getRow('
SELECT jeh.*, jehl.*
FROM '._DB_PREFIX_.'jxmegalayout_extra_html jeh
LEFT JOIN '._DB_PREFIX_.'jxmegalayout_extra_html_lang jehl
ON(jeh.`id_extra_html` = jehl.`id_extra_html`)
WHERE jeh.`id_extra_html` = '.(int)$id_item.'
AND jehl.`id_lang` = '.(int)$id_lang);
}
}

View File

@@ -0,0 +1,364 @@
<?php
/**
* 2017-2019 Zemez
*
* JX Mega Layout
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul & Alexander Pervakov)
* @copyright 2017-2019 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class JXMegaLayoutExtraImport
{
protected $context;
protected $temporaryPath;
public function __construct($path)
{
$this->context = Context::getContext();
$this->temporaryPath = $path;
}
/**
* Init extra content import after a valid archive was uploaded
*/
public function import()
{
// assure that an archive is still in a correct path
if (!$this->checkExtraContentArchive()) {
return die(Tools::jsonEncode(array('status' => false, 'error' => 'Fail to find an archive!')));
}
// extract an archive into a temporary path and remove it after extraction
if (!$this->extractExtraContentArchive()) {
return die(Tools::jsonEncode(array('status' => false, 'error' => 'Fail to extract an archive! Be sure that an archive is valid and contain allowed data.')));
}
// clear all old extra content data to avoid a confusion
if (!$this->clearOldExtraContentData()) {
return die(Tools::jsonEncode(array('status' => false, 'error' => 'Fail to remove old extra content data!')));
}
// fill extra content with new data
if (!$this->populateNewExtraContentData()) {
return die(Tools::jsonEncode(array('status' => false, 'error' => 'Fail to populate new extra content data!')));
}
// import all related extra content media files
if (!$this->importMediaFiles()) {
return die(Tools::jsonEncode(array('status' => false, 'error' => 'Fail to import media files!')));
}
return die(Tools::jsonEncode(array('status' => true)));
}
/**
* Check if an archive with extra content data exists
*
* @return bool
*/
protected function checkExtraContentArchive()
{
if (!file_exists($this->temporaryPath.'import/extracontent.zip')) {
return false;
}
return true;
}
/**
* Extract an archive in a temporary path
*
* @return bool
*/
protected function extractExtraContentArchive()
{
$file = $this->temporaryPath.'import/extracontent.zip';
$zip = new ZipArchive;
if ($zip->open($file) === true) {
if (!file_exists($this->temporaryPath.'import/temp/')) {
mkdir($this->temporaryPath.'import/temp/', 0777);
}
$zip->extractTo($this->temporaryPath.'import/temp/');
$zip->close();
unlink($file);
return true;
}
return false;
}
/**
* Delete all old extra content information
*
* @return bool
*/
protected function clearOldExtraContentData()
{
$result = $this->clearExtraHtml();
$result &= $this->clearExtraBanners();
$result &= $this->clearExtraVideos();
$result &= $this->clearExtraSliders();
return $result;
}
private function clearExtraHtml()
{
$result = true;
$html = JXMegaLayoutExtraHtml::getList($this->context->language->id);
if ($html) {
foreach ($html as $item) {
$extraHtml = new JXMegaLayoutExtraHtml($item['id_extra_html']);
$result &= $extraHtml->delete();
}
}
return $result;
}
private function clearExtraBanners()
{
$result = true;
$banners = JXMegaLayoutExtraBanner::getList($this->context->language->id);
if ($banners) {
foreach ($banners as $banner) {
$extraBanner = new JXMegaLayoutExtraBanner($banner['id_extra_banner']);
$result &= $extraBanner->delete();
}
}
return $result;
}
private function clearExtraVideos()
{
$result = true;
$videos = JXMegaLayoutExtraVideo::getList($this->context->language->id);
if ($videos) {
foreach ($videos as $video) {
$extraVideo = new JXMegaLayoutExtraVideo($video['id_extra_video']);
$result &= $extraVideo->delete();
}
}
return $result;
}
private function clearExtraSliders()
{
$result = true;
$sliders = JXMegaLayoutExtraSlider::getList($this->context->language->id);
if ($sliders) {
foreach ($sliders as $slider) {
$extraSlider = new JXMegaLayoutExtraSlider($slider['id_extra_slider']);
$result &= $extraSlider->delete();
}
}
return $result;
}
/**
* Populate new extra content data
* @return bool
*/
private function populateNewExtraContentData()
{
$result = true;
$result &= $this->populateExtraContentHTML();
$result &= $this->populateExtraContentBanners();
$result &= $this->populateExtraContentVideos();
$result &= $this->populateExtraContentSliders();
return $result;
}
private function populateExtraContentHTML()
{
$htmlPath = $this->temporaryPath.'import/temp/html.json';
if (!file_exists($htmlPath)) {
return true;
}
$htmlData = Tools::jsonDecode(Tools::file_get_contents($htmlPath), true);
if ($htmlData) {
foreach ($htmlData as $id => $html) {
$extraHtml = new JXMegaLayoutExtraHtml();
$extraHtml->id = $id;
$extraHtml->force_id = true;
$extraHtml->specific_class = $html['default']['specific_class'];
foreach (Language::getLanguages(false) as $language) {
if (isset($html['languages'][$language['iso_code']])) {
$extraHtml->name[$language['id_lang']] = $html['languages'][$language['iso_code']]['name'];
$extraHtml->content[$language['id_lang']] = $html['languages'][$language['iso_code']]['content'];
} else {
$extraHtml->name[$language['id_lang']] = $html['default']['name'];
$extraHtml->content[$language['id_lang']] = $html['default']['content'];
}
}
$extraHtml->add();
}
}
return true;
}
private function populateExtraContentBanners()
{
$bannersPath = $this->temporaryPath.'import/temp/banners.json';
if (!file_exists($bannersPath)) {
return true;
}
$bannersData = Tools::jsonDecode(Tools::file_get_contents($bannersPath), true);
if ($bannersData) {
foreach ($bannersData as $id => $banner) {
$extraBanner = new JXMegaLayoutExtraBanner();
$extraBanner->id = $id;
$extraBanner->force_id = true;
$extraBanner->specific_class = $banner['default']['specific_class'];
foreach (Language::getLanguages(false) as $language) {
if (isset($banner['languages'][$language['iso_code']])) {
$extraBanner->name[$language['id_lang']] = $banner['languages'][$language['iso_code']]['name'];
$extraBanner->img[$language['id_lang']] = $banner['languages'][$language['iso_code']]['img'];
$extraBanner->link[$language['id_lang']] = $banner['languages'][$language['iso_code']]['link'];
$extraBanner->content[$language['id_lang']] = $banner['languages'][$language['iso_code']]['content'];
} else {
$extraBanner->name[$language['id_lang']] = $banner['default']['name'];
$extraBanner->img[$language['id_lang']] = $banner['default']['img'];
$extraBanner->link[$language['id_lang']] = $banner['default']['link'];
$extraBanner->content[$language['id_lang']] = $banner['default']['content'];
}
}
$extraBanner->add();
}
}
return true;
}
private function populateExtraContentVideos()
{
$videosPath = $this->temporaryPath.'import/temp/videos.json';
if (!file_exists($videosPath)) {
return true;
}
$videosData = Tools::jsonDecode(Tools::file_get_contents($videosPath), true);
if ($videosData) {
foreach ($videosData as $id => $video) {
$extraVideo = new JXMegaLayoutExtraVideo();
$extraVideo->id = $id;
$extraVideo->force_id = true;
$extraVideo->specific_class = $video['default']['specific_class'];
foreach (Language::getLanguages(false) as $language) {
if (isset($video['languages'][$language['iso_code']])) {
$extraVideo->name[$language['id_lang']] = $video['languages'][$language['iso_code']]['name'];
$extraVideo->url[$language['id_lang']] = $video['languages'][$language['iso_code']]['url'];
$extraVideo->content[$language['id_lang']] = $video['languages'][$language['iso_code']]['content'];
} else {
$extraVideo->name[$language['id_lang']] = $video['default']['name'];
$extraVideo->url[$language['id_lang']] = $video['default']['url'];
$extraVideo->content[$language['id_lang']] = $video['default']['content'];
}
}
$extraVideo->add();
}
}
return true;
}
private function populateExtraContentSliders()
{
$slidersPath = $this->temporaryPath.'import/temp/sliders.json';
if (!file_exists($slidersPath)) {
return true;
}
$slidersData = Tools::jsonDecode(Tools::file_get_contents($slidersPath), true);
if ($slidersData) {
foreach ($slidersData as $id => $slider) {
$extraSlider = new JXMegaLayoutExtraSlider();
$extraSlider->id = $id;
$extraSlider->force_id = true;
$extraSlider->specific_class = $slider['default']['specific_class'];
$extraSlider->visible_items = $slider['default']['visible_items'];
$extraSlider->items_scroll = $slider['default']['items_scroll'];
$extraSlider->margin = $slider['default']['margin'];
$extraSlider->speed = $slider['default']['speed'];
$extraSlider->auto_scroll = $slider['default']['auto_scroll'];
$extraSlider->pause = $slider['default']['pause'];
$extraSlider->loop = $slider['default']['loop'];
$extraSlider->pager = $slider['default']['pager'];
$extraSlider->controls = $slider['default']['controls'];
$extraSlider->auto_height = $slider['default']['auto_height'];
foreach (Language::getLanguages(false) as $language) {
if (isset($slider['languages'][$language['iso_code']])) {
$extraSlider->name[$language['id_lang']] = $slider['languages'][$language['iso_code']]['name'];
$extraSlider->content[$language['id_lang']] = $slider['languages'][$language['iso_code']]['content'];
} else {
$extraSlider->name[$language['id_lang']] = $slider['default']['name'];
$extraSlider->content[$language['id_lang']] = $slider['default']['content'];
}
}
if (isset($slider['slides']) && count($slider['slides'])) {
foreach ($slider['slides'] as $slide) {
$extraSlider->addImportedSliderSlide($slide['id_item'], $slide['id_extra_slider'], $slide['type'], $slide['id_content'], $slide['position']);
}
}
$extraSlider->add();
}
}
return true;
}
/**
* Copy extra content media files
*
* @return bool
*/
private function importMediaFiles()
{
$mediaFilesSourcePath = $this->temporaryPath.'import/temp/media/';
$mediaFilesPath = $this->temporaryPath.'extracontent/';
if (!file_exists($mediaFilesPath)) {
mkdir($mediaFilesPath, 0777);
}
$mediaFiles = array_merge(
Tools::scandir($mediaFilesSourcePath, 'jpg'),
Tools::scandir($mediaFilesSourcePath, 'png'),
Tools::scandir($mediaFilesSourcePath, 'gif'),
Tools::scandir($mediaFilesSourcePath, 'jpeg')
);
if ($mediaFiles) {
foreach ($mediaFiles as $file) {
copy($mediaFilesSourcePath.$file, $mediaFilesPath.$file);
}
}
return true;
}
}

View File

@@ -0,0 +1,227 @@
<?php
/**
* 2017-2019 Zemez
*
* JX Mega Layout
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul & Alexander Pervakov)
* @copyright 2017-2019 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class JXMegaLayoutExtraSlider extends ObjectModel
{
public $name;
public $content;
public $specific_class;
public $visible_items;
public $items_scroll;
public $margin;
public $speed;
public $auto_scroll;
public $pause;
public $loop;
public $pager;
public $controls;
public $auto_height;
public static $definition = array(
'table' => 'jxmegalayout_extra_slider',
'primary' => 'id_extra_slider',
'multilang' => true,
'fields' => array(
'name' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'required' => true, 'lang' => true),
'content' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml', 'size' => 4000),
'specific_class' => array('type' => self::TYPE_STRING, 'validate' => 'isCleanHtml', 'size' => 128),
'visible_items' => array('type' => self::TYPE_INT, 'validate' => 'isInt', 'required' => true),
'items_scroll' => array('type' => self::TYPE_INT, 'validate' => 'isInt', 'required' => true),
'margin' => array('type' => self::TYPE_INT, 'validate' => 'isInt', 'required' => true),
'speed' => array('type' => self::TYPE_INT, 'validate' => 'isInt', 'required' => true),
'auto_scroll' => array('type' => self::TYPE_INT, 'validate' => 'isInt', 'required' => true),
'pause' => array('type' => self::TYPE_INT, 'validate' => 'isInt', 'required' => true),
'loop' => array('type' => self::TYPE_INT, 'validate' => 'isInt', 'required' => true),
'pager' => array('type' => self::TYPE_INT, 'validate' => 'isInt', 'required' => true),
'controls' => array('type' => self::TYPE_INT, 'validate' => 'isInt', 'required' => true),
'auto_height' => array('type' => self::TYPE_INT, 'validate' => 'isInt', 'required' => true)
),
);
/**
* Extend method in order to remove all related slides
*
* @return bool
*/
public function delete()
{
$this->removeSliderSlides();
return parent::delete();
}
/**
* Remove all related slides
* @return bool
*/
private function removeSliderSlides()
{
return Db::getInstance()->delete('jxmegalayout_extra_slider_item', '`id_extra_slider` = '.(int)$this->id);
}
/**
* Update all slides after each slider modification
* At start remove every old relation and than add new ones
*
* @param $slides - list of new related slides
*
* @return bool
* @throws PrestaShopDatabaseException
*/
public function updateSlides($slides)
{
$result = true;
$result &= $this->removeSliderSlides();
if (count($slides)) {
foreach ($slides as $slide) {
$info = explode('-', $slide);
$result &= Db::getInstance()->insert(
'jxmegalayout_extra_slider_item',
array('id_extra_slider' => (int)$this->id, 'type' => pSQL($info[0]), 'id_content' => (int)$info[1])
);
}
}
return $result;
}
/**
* Get the list of all available sliders
*
* @param $id_lang
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public static function getList($id_lang)
{
return Db::getInstance()->executeS(
'SELECT *, jes.`id_extra_slider` as `id`
FROM '._DB_PREFIX_.'jxmegalayout_extra_slider jes
LEFT JOIN '._DB_PREFIX_.'jxmegalayout_extra_slider_lang jesl
ON(jes.`id_extra_slider` = jesl.`id_extra_slider`)
WHERE jesl.`id_lang` = '.(int)$id_lang
);
}
/**
* Get all related to slider items, with information about them
*
* @param $id_slider
* @param $id_lang
* @param $front
*
* @return array
* @throws PrestaShopDatabaseException
*/
public static function getSlides($id_slider, $id_lang, $front = false)
{
$jxmegalayout = new Jxmegalayout();
$result = array();
$slides = Db::getInstance()->executeS('SELECT * FROM '._DB_PREFIX_.'jxmegalayout_extra_slider_item WHERE `id_extra_slider` = '.(int)$id_slider);
if ($slides) {
foreach ($slides as $key => $slide) {
$result[$key]['entity'] = $slide;
if ($slide['type'] != 'product' && $slide['type'] != 'post') {
$result[$key]['info'] = Db::getInstance()->getRow(
'SELECT t.*, tl.*, t.`id_extra_'.pSQL($slide['type']).'` as `id`
FROM '._DB_PREFIX_.'jxmegalayout_extra_'.$slide['type'].' t
LEFT JOIN '._DB_PREFIX_.'jxmegalayout_extra_'.$slide['type'].'_lang tl
ON(t.`id_extra_'.pSQL($slide['type']).'` = tl.`id_extra_'.pSQL($slide['type']).'`)
WHERE tl.`id_lang` = '.(int)$id_lang.'
AND t.`id_extra_'.pSQL($slide['type']).'` = '.(int)$slide['id_content']
);
} else if ($slide['type'] == 'product') {
if (!$front) {
$result[$key]['info'] = array('id' => $slide['id_content'], 'name' => $slide['id_content']);
} else {
$result[$key]['info'] = $jxmegalayout->assembleProduct($slide['id_content']);
}
} else if ($slide['type'] == 'post') {
if (!$front) {
$result[$key]['info'] = array('id' => $slide['id_content'], 'name' => $slide['id_content']);
} else {
if ($jxmegalayout->checkModuleStatus('jxblog')) {
$result[$key]['info'] = false;
} else {
$result[$key]['info'] = JXBlogPost::getPost(
$slide['id_content'],
Context::getContext()->language->id,
Context::getContext()->shop->id,
Context::getContext()->customer->id_default_group
);
}
}
}
}
}
return $result;
}
public static function getItem($id_item, $id_lang, $front = false)
{
$result = Db::getInstance()->getRow('
SELECT jes.*, jesl.*
FROM '._DB_PREFIX_.'jxmegalayout_extra_slider jes
LEFT JOIN '._DB_PREFIX_.'jxmegalayout_extra_slider_lang jesl
ON(jes.`id_extra_slider` = jesl.`id_extra_slider`)
WHERE jes.`id_extra_slider` = '.(int)$id_item.'
AND jesl.`id_lang` = '.(int)$id_lang);
if ($result) {
$result['slides'] = self::getSlides($id_item, $id_lang, $front);
}
return $result;
}
/**
* Get all slides related to a slider
*
* @param $id_slider
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public static function getSliderSlides($id_slider)
{
return Db::getInstance()->executeS('SELECT * FROM '._DB_PREFIX_.'jxmegalayout_extra_slider_item WHERE `id_extra_slider` = '.(int)$id_slider);
}
public function addImportedSliderSlide($id_slide, $id_slider, $type, $id_content, $position)
{
return Db::getInstance()->insert(
'jxmegalayout_extra_slider_item',
array(
'id_item' => (int)$id_slide,
'id_extra_slider' => (int)$id_slider,
'type' => pSQL($type),
'id_content' => (int)$id_content,
'position' => (int)$position
)
);
}
}

View File

@@ -0,0 +1,74 @@
<?php
/**
* 2017-2019 Zemez
*
* JX Mega Layout
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul & Alexander Pervakov)
* @copyright 2017-2019 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class JXMegaLayoutExtraVideo extends ObjectModel
{
public $name;
public $url;
public $content;
public $specific_class;
public static $definition = array(
'table' => 'jxmegalayout_extra_video',
'primary' => 'id_extra_video',
'multilang' => true,
'fields' => array(
'name' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'required' => true, 'lang' => true),
'url' => array('type' => self::TYPE_STRING, 'validate' => 'isUrl', 'lang' => true),
'content' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml', 'size' => 4000),
'specific_class' => array('type' => self::TYPE_STRING, 'validate' => 'isCleanHtml', 'size' => 128)
),
);
/**
* Get the list of all available video
*
* @param $id_lang
*
* @return array|false|mysqli_result|null|PDOStatement|resource
* @throws PrestaShopDatabaseException
*/
public static function getList($id_lang)
{
return Db::getInstance()->executeS('
SELECT *, jev.`id_extra_video` as `id`
FROM '._DB_PREFIX_.'jxmegalayout_extra_video jev
LEFT JOIN '._DB_PREFIX_.'jxmegalayout_extra_video_lang jevl
ON(jev.`id_extra_video` = jevl.`id_extra_video`)
WHERE jevl.`id_lang` = '.(int)$id_lang);
}
public static function getItem($id_item, $id_lang)
{
return Db::getInstance()->getRow('
SELECT jev.*, jevl.*
FROM '._DB_PREFIX_.'jxmegalayout_extra_video jev
LEFT JOIN '._DB_PREFIX_.'jxmegalayout_extra_video_lang jevl
ON(jev.`id_extra_video` = jevl.`id_extra_video`)
WHERE jev.`id_extra_video` = '.(int)$id_item.'
AND jevl.`id_lang` = '.(int)$id_lang);
}
}

View File

@@ -0,0 +1,3 @@
drwxr-xr-x 2 30094 users 3 Oct 6 10:16 .
drwxr-xr-x 4 30094 users 9 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 16665 Aug 31 2021 JXMegaLayoutThemeBuilder.php

View File

@@ -0,0 +1,547 @@
<?php
/**
* 2017-2019 Zemez
*
* JX Mega Layout
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul & Alexander Pervakov)
* @copyright 2017-2019 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManager;
use Symfony\Component\Yaml\Yaml;
use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManagerBuilder;
use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeRepository;
use Symfony\Component\HttpFoundation\Request as BuilderRequest;
class JXMegalayoutThemeBuilder
{
protected $parent_theme;
protected $parent_theme_library;
protected $theme_manager;
protected $theme_repository;
private $api_url = 'http://prestashop7.devoffice.com/meilleur/themebuilder_api/';
public function __construct()
{
$this->theme_manager = (new ThemeManagerBuilder(Context::getContext(), Db::getInstance()))->build();
$this->theme_repository = (new ThemeManagerBuilder(Context::getContext(), Db::getInstance()))->buildRepository();
}
public function setParentTheme($name)
{
$this->parent_theme = $this->theme_repository->getInstanceByName($name);
return $this;
}
/**
* Get all existed themes names
*
* @return array
*/
public function getAllThemesNames()
{
$themes = array();
if ($allThemes = $this->theme_repository->getList()) {
foreach (array_keys($allThemes) as $name) {
$themes[] = $name;
}
}
return $themes;
}
/**
* Get a list of the themes which are compatible with a theme builder
* To be a compatible theme it has to contain library folder theme_name/templates/library/
* and a info.yml file inside the latter
*
* @return array of themes names
*/
public function getCompatibleParentThemes()
{
$compatibleThemes = array();
if ($allThemes = $this->theme_repository->getList()) {
foreach ($allThemes as $name => $theme) {
if (!$theme->get('parent') && $this->hasLayoutsLibrary($theme)) {
$compatibleThemes[] = array('name' => $name, 'image' => _PS_BASE_URL_ . __PS_BASE_URI__ . $theme->get('preview'));
}
}
}
return $compatibleThemes;
}
/**
* Check if a theme has a library and info.yml file
*
* @param $theme object
*
* @return bool
*/
private function hasLayoutsLibrary($theme)
{
if (file_exists($theme->getDirectory().'templates/library/') && file_exists($theme->getDirectory().'templates/library/info.yml')) {
return true;
}
return false;
}
/**
* Get all compatible children themes which were produced from this one
*
* @return array
*/
public function getChildren()
{
$children = array();
if ($allThemes = $this->theme_repository->getList()) {
foreach ($allThemes as $themeName => $theme) {
if ($theme->get('parent') == $this->parent_theme->getName() && $this->checkChildCompatibility($theme)) {
$children[] = array('name' => $themeName, 'image' => _PS_BASE_URL_ . __PS_BASE_URI__ . $theme->get('preview'));
}
}
}
return $children;
}
/**
* Get a library info for a theme by its name
*
* @return mixed
*/
public function loadParentThemeLibrary()
{
$this->parent_theme_library = Yaml::parse(Tools::file_get_contents($this->parent_theme->getDirectory().'templates/library/info.yml'));
return $this->parent_theme_library;
}
/**
* Get layouts previews
*
* @return array
*/
public function loadParentThemeLibraryPreviews()
{
$previewList = array();
if ($this->parent_theme_library && isset($this->parent_theme_library['pages_list'])) {
foreach ($this->parent_theme_library['pages_list'] as $type => $data) {
if (isset($data['layouts']) && $data['layouts']) {
foreach (array_keys($data['layouts']) as $name) {
if (file_exists($this->parent_theme->getDirectory().'templates/library/preview/'.$type.'/'.$name.'.png')) {
$previewList[$type][$name] = __PS_BASE_URI__.'/themes/'.$this->parent_theme->get('name').'/templates/library/preview/'.$type.'/'.$name.'.png';
} else {
$previewList[$type][$name] = false;
}
}
}
}
}
return $previewList;
}
/**
* Check if a child theme is a compatible with a current parent theme
*
* @param $theme object
*
* @return bool
*/
private function checkChildCompatibility($theme)
{
return file_exists($theme->getDirectory().'config/themeChildInfo.yml');
}
/**
* Build/rebuild child theme according to selected parameters
*
* @param $parentTheme name of a parent theme
* @param $name a name which will be used for child theme
* @param $publicName a public name which will be used for current theme in an admin panel
* @param array $layouts a list of selected layouts which will be applied to a child theme
*
* @return int a code of an error if it occurred
*/
public function buildChildTheme($parentTheme, $name, $publicName, array $layouts)
{
$theme = $this->theme_repository->getInstanceByName($parentTheme);
$themeDir = $theme->getDirectory();
$libraryDirectory = $themeDir.'templates/library/';
if (!$newPath = $this->copyFilesFromLibrary($name, $libraryDirectory, $layouts)) {
return 1;
}
if (!$this->createThemeSettingsFiles($themeDir, $newPath, $name, $publicName)) {
return 2;
}
if (!copy($themeDir.'preview.png', $newPath.'preview.png')) {
return 3;
}
if (!$this->writeSettingsFile($newPath.'config/', 'themeChildInfo.yml', array('name' => $name, 'display_name' => $publicName, 'layouts' => $layouts))) {
return 4;
}
return 0;
}
/**
* Copy all layout's files which are necessary for the child theme
*
* @param $name name of a new theme
* @param $libraryDirectory a path to the library inside a parent theme
* @param array $layouts a list of layouts
*
* @return string
*/
private function copyFilesFromLibrary($name, $libraryDirectory, array $layouts)
{
$newThemeDirectory = _PS_ALL_THEMES_DIR_.$name.'/';
if (is_dir($newThemeDirectory)) {
$this->deleteDir($newThemeDirectory);
}
mkdir($newThemeDirectory, 0777, true);
foreach ($layouts as $type => $layout) {
if (is_dir($libraryDirectory.'/'.$type.'/'.$layout['name'].'/')) {
$this->recurseCopy($libraryDirectory.'/'.$type.'/'.$layout['name'].'/', $newThemeDirectory);
}
}
return $newThemeDirectory;
}
/**
* Remove a directory and everything inside it
*
* @param $dirPath
*/
private function deleteDir($dirPath)
{
if (Tools::substr($dirPath, Tools::strlen($dirPath) - 1, 1) != '/') {
$dirPath .= '/';
}
$files = glob($dirPath.'*', GLOB_MARK);
foreach ($files as $file) {
if (is_dir($file)) {
$this->deleteDir($file);
} else {
unlink($file);
}
}
rmdir($dirPath);
}
/**
* Copy folder with containing files
*
* @param $src copy from
* @param $dst copy to
*/
private function recurseCopy($src, $dst)
{
$dir = opendir($src);
if (!is_dir($dst)) {
mkdir($dst, 0777, true);
}
while (false !== ($file = readdir($dir))) {
if ($file != '.' && $file != '..') {
if (is_dir($src.'/'.$file)) {
$this->recurseCopy($src.'/'.$file, $dst.'/'.$file);
} else {
copy($src.'/'.$file, $dst.'/'.$file);
}
}
}
closedir($dir);
}
/**
* Create a file with mandatory settings for a child theme usage
*
* @param $themeDir a path to a parent theme
* @param $newPath a path a path to a new child theme
* @param $name a name of the new child theme
* @param $publicName a public name of the new child theme
*
* @return int
*/
private function createThemeSettingsFiles($themeDir, $newPath, $name, $publicName)
{
$childThemeSettings = $parentThemeSettings = Yaml::parse(Tools::file_get_contents($themeDir.'config/theme.yml'));
$childThemeSettings['parent'] = $parentThemeSettings['name'];
if (!$parentThemeSettings['assets']) {
unset($childThemeSettings['assets']);
}
$childThemeSettings['name'] = $name;
$childThemeSettings['display_name'] = $publicName;
return $this->writeSettingsFile($newPath.'config/', 'theme.yml', $childThemeSettings);
}
/**
* Write an information to a yml file
*
* @param $path to a new file
* @param $name a name of the new file
* @param $data an information
*
* @return int
*/
private function writeSettingsFile($path, $name, $data)
{
if (!is_dir($path)) {
mkdir($path, 0777, true);
}
if (!file_exists($path.$name)) {
$fp = fopen($path.$name, 'w');
fclose($fp);
}
return file_put_contents($path.$name, Yaml::dump($data, 5, 2));
}
/**
* Load information about child theme to get know which layouts it uses and other information
*
* @param $name
*
* @return mixed
*/
public function loadChildThemeInfo($name)
{
$theme = $this->theme_repository->getInstanceByName($name);
$infoPath = $theme->getDirectory().'config/themeChildInfo.yml';
return Yaml::parse(Tools::file_get_contents($infoPath));
}
/**
* Init theme remove
*
* @param $name
*
* @return int
*/
public function remove($name)
{
// check if a theme isn't used
if ($this->checkIfThemeIsUsed($name)) {
return 1;
}
if (!$this->theme_manager->uninstall($name)) {
return 2;
}
return 0;
}
/**
* Check if any of stores use the theme
*
* @param $name
*
* @return bool
*/
private function checkIfThemeIsUsed($name)
{
$shops = Shop::getShops(false);
$used = false;
foreach ($shops as $shop) {
if ($shop['theme_name'] == $name) {
$used = true;
}
}
return $used;
}
/**
* Check if this theme has a new version on the repository
*
* @return bool
*/
public function checkParentThemeUpdates()
{
$latestVersion = $this->getLatestThemeVersion($this->parent_theme->getName(), $this->parent_theme->get('secret_hash'));
if ($latestVersion && Tools::version_compare($this->parent_theme->get('version'), $latestVersion, '<')) {
return true;
}
return false;
}
/**
* Send a query to an API in order to check if a local theme has latest version
*
* @param $themeName
* @param $hash secret key used to avoid fraudulent theme uploading
*
* @return mixed
*/
private function getLatestThemeVersion($themeName, $hash)
{
return $this->getAPIData($this->api_url, array('action' => 'getLatestVersion', 'theme_name' => $themeName, 'secret_hash' => $hash));
}
/**
* Check if a theme library has a new version
*
* @return bool
*/
public function checkParentThemeLibraryUpdates()
{
$latestLibraryVersion = $this->getLatestThemeLibraryVersion($this->parent_theme->getName(), $this->parent_theme->get('secret_hash'));
$libraryInfo = $this->loadParentThemeLibrary();
if ($latestLibraryVersion && Tools::version_compare($libraryInfo['version'], $latestLibraryVersion, '<')) {
return true;
}
return false;
}
private function getLatestThemeLibraryVersion($themeName, $hash)
{
return $this->getAPIData($this->api_url, array('action' => 'getLibraryLatestVersion', 'theme_name' => $themeName, 'secret_hash' => $hash));
}
/**
* Send request to API
*
* @param $url
* @param $data
*
* @return mixed
*/
private function getAPIData($url, $data)
{
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
/**
* Upload latest files and update parent theme
*
* @return bool
*/
public function updateParentTheme()
{
$themeUpdatesPath = $this->getParentThemeLatestArchivePath();
if (Tools::file_get_contents($themeUpdatesPath)) {
$jxmegalayout = new Jxmegalayout();
$tmpPath = $jxmegalayout->localPath().'tmp/';
if (!is_dir($tmpPath)) {
mkdir($tmpPath, 0777);
}
$themeName = $this->parent_theme->getName();
copy($themeUpdatesPath, $tmpPath.$themeName.'.zip');
if (file_exists($tmpPath.$themeName.'.zip')) {
$this->extractArchive($tmpPath.$themeName.'.zip');
}
if (is_dir($tmpPath)) {
$this->deleteDir($tmpPath);
}
return $this->theme_manager->reset($themeName);
}
return false;
}
/**
* Upload latest files and update parent theme library
*
* @return bool
*/
public function updateParentThemeLibrary()
{
$themeLibraryUpdatesPath = $this->getParentThemeLibraryLatestArchivePath();
if (Tools::file_get_contents($themeLibraryUpdatesPath)) {
$jxmegalayout = new Jxmegalayout();
$tmpPath = $jxmegalayout->localPath().'tmp/';
if (is_dir($tmpPath)) {
$this->deleteDir($tmpPath);
}
mkdir($tmpPath, 0777);
copy($themeLibraryUpdatesPath, $tmpPath.'library.zip');
if (file_exists($tmpPath.'library.zip')) {
$this->extractArchive($tmpPath.'library.zip', true);
}
if (is_dir($tmpPath)) {
$this->deleteDir($tmpPath);
}
return true;
}
return false;
}
/**
* Extract archive with all files overriding
*
* @param $file
* @param bool $library
*
* @return bool
*/
private function extractArchive($file, $library = false)
{
$destination = $this->parent_theme->getDirectory();
if ($library) {
$destination = $destination.'templates/library/';
}
$zip = new ZipArchive();
if ($zip->open($file) === true) {
$zip->extractTo($destination);
$zip->close();
return true;
}
return false;
}
/**
* Get path to an archive
*
* @return mixed
*/
private function getParentThemeLatestArchivePath()
{
return $this->getAPIData($this->api_url, array('action' => 'getLatestVersionArchive', 'theme_name' => $this->parent_theme->getName()));
}
/**
* Get path to an archive
*
* @return mixed
*/
private function getParentThemeLibraryLatestArchivePath()
{
return $this->getAPIData($this->api_url, array('action' => 'getLatestLibraryVersionArchive', 'theme_name' => $this->parent_theme->getName()));
}
}

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>jxmegalayout</name>
<displayName><![CDATA[JX Mega Layout]]></displayName>
<version><![CDATA[1.5.4]]></version>
<description><![CDATA[Module adds more functionality for hooks.]]></description>
<author><![CDATA[Zemez (Alexander Grosul & Alexander Pervakov)]]></author>
<tab><![CDATA[front_office_features]]></tab>
<is_configurable>1</is_configurable>
<need_instance>0</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>jxmegalayout</name>
<displayName><![CDATA[JX Mega Layout]]></displayName>
<version><![CDATA[1.5.4]]></version>
<description><![CDATA[Module adds more functionality for hooks.]]></description>
<author><![CDATA[Zemez (Alexander Grosul & Alexander Pervakov)]]></author>
<tab><![CDATA[front_office_features]]></tab>
<is_configurable>1</is_configurable>
<need_instance>0</need_instance>
<limited_countries></limited_countries>
</module>

View File

@@ -0,0 +1,3 @@
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 .
drwxr-xr-x 9 30094 users 15 Oct 6 10:16 ..
drwxr-xr-x 2 30094 users 3 Oct 6 10:16 admin

View File

@@ -0,0 +1,3 @@
drwxr-xr-x 2 30094 users 3 Oct 6 10:16 .
drwxr-xr-x 3 30094 users 3 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 37408 Aug 31 2021 AdminJXMegaLayout.php

View File

@@ -0,0 +1,854 @@
<?php
/**
* 2017-2019 Zemez
*
* JX Mega Layout
*
* NOTICE OF LICENSE
*
* This source file is subject to the General Public License (GPL 2.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/GPL-2.0
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade the module to newer
* versions in the future.
*
* @author Zemez (Alexander Grosul & Alexander Pervakov)
* @copyright 2017-2019 Zemez
* @license http://opensource.org/licenses/GPL-2.0 General Public License (GPL 2.0)
*/
class AdminJXMegaLayoutController extends ModuleAdminController
{
public function ajaxProcessUpdateLayoutItem()
{
$errors = array();
$item_data = Tools::getValue('data');
$id_item = Tools::getValue('id_item');
if ($id_item != 'false') {
$item = new JXMegaLayoutItems($id_item);
} else {
$item = new JXMegaLayoutItems();
$item->id_unique = 'it_'.Tools::passwdGen(12, 'NO_NUMERIC');
}
$item->id_layout = $item_data['id_layout'];
$item->id_parent = $item_data['id_parent'];
$item->sort_order = $item_data['sort_order'];
$item->col = $item_data['col'];
$item->col_xs = $item_data['col'];
$item->col_sm = $item_data['col_sm'];
$item->col_md = $item_data['col_md'];
$item->col_lg = $item_data['col_lg'];
$item->col_xl = $item_data['col_xl'];
$item->col_xxl = $item_data['col_xxl'];
$item->module_name = $item_data['module_name'];
$item->specific_class = $item_data['specific_class'];
$item->extra_css = $item_data['extra_css'];
if ($item->module_name == 'logo' || $item->module_name == 'copyright' || $item->module_name == 'tabs') {
$item->type = 'block';
} else {
if (!empty($item_data['origin_hook'])) {
$item->origin_hook = $item_data['origin_hook'];
}
$item->type = $item_data['type'];
}
if ($id_item == 'false') {
if (!$item->add()) {
$errors[] = $this->l('Error occurred while adding an item!');
}
} else {
if (!$item->update()) {
$errors[] = $this->l('Error occurred while saving an item!');
}
}
if (count($errors)) {
die(Tools::jsonEncode(
array('status' => 'false', 'response_msg' => $this->l('Oops...something went wrong!'))
));
}
$item->id_item = $item->id;
$jxmegalayout = new Jxmegalayout();
$item_content = null;
switch ($item_data['type']) {
case 'module':
$this->context->smarty->assign(
array(
'elem' => get_object_vars($item),
'preview' => false,
'position' => ''
)
);
$item_content = $jxmegalayout->display(
$jxmegalayout->getLocalPath(),
'/views/templates/admin/layouts/module.tpl'
);
break;
case 'wrapper':
$this->context->smarty->assign(
array(
'elem' => get_object_vars($item),
'preview' => false,
'position' => ''
)
);
$item_content = $jxmegalayout->display(
$jxmegalayout->getLocalPath(),
'/views/templates/admin/layouts/wrapper.tpl'
);
break;
case 'row':
$this->context->smarty->assign(
array(
'elem' => get_object_vars($item),
'preview' => false,
'position' => ''
)
);
$item_content = $jxmegalayout->display(
$jxmegalayout->getLocalPath(),
'/views/templates/admin/layouts/row.tpl'
);
break;
case 'col':
$class = $item_data['col'].' '.$item_data['col_xs'].' '.$item_data['col_sm'].' '.$item_data['col_md'].' '.$item_data['col_lg'].' '.$item_data['col_xl'].' '.$item_data['col_xxl'].' ';
$this->context->smarty->assign(
array(
'elem' => get_object_vars($item),
'preview' => false,
'position' => '',
'class' => $class
)
);
$item_content = $jxmegalayout->display(
$jxmegalayout->getLocalPath(),
'/views/templates/admin/layouts/col.tpl'
);
break;
case 'block':
$this->context->smarty->assign(
array(
'elem' => get_object_vars($item),
'preview' => false,
'position' => '',
)
);
$item_content = $jxmegalayout->display(
$jxmegalayout->getLocalPath(),
'/views/templates/admin/layouts/module.tpl'
);
break;
case 'content':
$this->context->smarty->assign(
array(
'elem' => get_object_vars($item),
'preview' => false,
'position' => '',
'info' => '',
)
);
$item_content = $jxmegalayout->display(
$jxmegalayout->getLocalPath(),
'/views/templates/admin/layouts/content.tpl'
);
break;
}
die(Tools::jsonEncode(
array('status' => 'true', 'id_item' => $item->id, 'id_unique' => $item->id_unique, 'response_msg' => $this->l(
'Changes were saved successfully'
), 'content' => $item_content)
));
}
public function ajaxProcessDeleteLayoutItem()
{
$id_items = Tools::getValue('id_item');
if (count($id_items) < 1) {
die(Tools::jsonEncode(array('status' => 'error', 'response_msg' => $this->l('Bad ID value'))));
}
foreach ($id_items as $id_item) {
if (Tools::isEmpty($id_item)) {
continue;
}
$item = new JXMegaLayoutItems($id_item);
if (!$item->delete()) {
die(Tools::jsonEncode(array('status' => 'error', 'response_msg' => $this->l('Can\'t delete item(s)'))));
}
}
die(Tools::jsonEncode(
array('status' => 'true', 'response_msg' => $this->l('Item(s) was/were deleted successfully'))
));
}
public function ajaxProcessUpdateLayoutItemsOrder()
{
$data = Tools::getValue('data');
if (count($data) > 1) {
foreach ($data as $id_item => $sort_order) {
$item = new JXMegaLayoutItems($id_item);
if (!Validate::isLoadedObject($item)) {
die(Tools::jsonEncode(array('status' => 'error', 'response_msg' => $this->l('Bad ID value'))));
}
$item->sort_order = $sort_order;
if (!$item->update()) {
die(Tools::jsonEncode(
array('status' => 'error', 'response_msg' => $this->l(
'Sort order changes were not saved successfully'
))
));
}
}
die(Tools::jsonEncode(
array('status' => 'true', 'response_msg' => $this->l('Changes were saved successfully'))
));
}
}
public function ajaxProcessLayoutPreview()
{
$id_layout = Tools::getValue('id_layout');
$item = new Jxmegalayout();
die(Tools::jsonEncode(array('status' => 'true', 'msg' => $item->getLayoutAdmin($id_layout, true))));
}
public function ajaxProcessLayoutExport()
{
$id_layout = Tools::getValue('id_layout');
$obj = new JXMegalayoutExport();
$href = $obj->init($id_layout);
die(Tools::jsonEncode(array('status' => true, 'href' => $href)));
}
public function ajaxProcessLoadTool()
{
$tool_name = Tools::getValue('tool_name');
$tools = new Jxmegalayout();
die(Tools::jsonEncode(array('status' => 'true', 'rawData' => $tools->renderToolContent($tool_name))));
}
public function ajaxProcessGetItemStyles()
{
$id_unique = Tools::getValue('id_unique');
$tools = new Jxmegalayout();
$styles = $tools->getItemStyles($id_unique);
die(Tools::jsonEncode(array('status' => 'true', 'content' => $styles)));
}
public function ajaxProcessSaveItemStyles()
{
$id_unique = Tools::getValue('id_unique');
$data = Tools::getValue('data');
if (!$data || Tools::isEmpty($data)) {
die(Tools::jsonEncode(array('status' => 'true', 'message' => $this->l('Nothing to save'))));
}
$tools = new Jxmegalayout();
if ($tools->saveItemStyles($id_unique, $data)) {
die(Tools::jsonEncode(array('status' => 'true', 'message' => $this->l('Saved'))));
}
die(Tools::jsonEncode(array('status' => 'false', 'message' => $this->l('Some errors occurred'))));
}
public function ajaxProcessClearItemStyles()
{
$id_unique = Tools::getValue('id_unique');
$tools = new Jxmegalayout();
if ($tools->deleteItemStyles($id_unique)) {
die(Tools::jsonEncode(array('status' => 'true', 'message' => $this->l('Item styles are removed'))));
}
die(Tools::jsonEncode(
array('status' => 'false', 'message' => $this->l('Some errors occurred while removing styles'))
));
}
public function ajaxProcessAddLayoutForm()
{
$hook_name = Tools::getValue('hook_name');
$layout = new Jxmegalayout();
if (!$result = $layout->showMessage($hook_name, 'addLayout')) {
die(Tools::jsonEncode(array('status' => 'false', 'message' => $this->l('Some errors occurred'))));
}
die(Tools::jsonEncode(array('status' => 'true', 'response_msg' => $result)));
}
public function ajaxProcessAddLayout()
{
$hook_name = Tools::getValue('hook_name');
$layout_name = Tools::getValue('layout_name');
$layout = new Jxmegalayout();
if ((bool)JXMegaLayoutLayouts::getLayoutByName($layout_name)) {
die(Tools::jsonEncode(
array('status' => 'false', 'type' => 'popup', 'message' => $this->l('You have preset with this name'))
));
}
if (!$id_layout = $layout->addLayout($hook_name, $layout_name)) {
die(Tools::jsonEncode(array('status' => 'false', 'message' => $this->l('Some errors occurred'))));
}
die(Tools::jsonEncode(
array('status' => 'true', 'id_layout' => $id_layout, 'message' => $this->l(
'The layout is successfully added.'
))
));
}
public function ajaxProcessAddModuleConfirmation()
{
$hook_name = Tools::getValue('hook_name');
$id_layout = (int)Tools::getValue('id_layout');
$jxmegalayout = new Jxmegalayout();
if (!$form = $jxmegalayout->addModuleForm($hook_name, $id_layout)) {
die(Tools::jsonEncode(array('status' => 'false', 'message' => $this->l('Some error occurred'))));
}
die(Tools::jsonEncode(array('status' => 'true', 'message' => $form)));
}
public function ajaxProcessLoadLayoutContent()
{
$id_layout = Tools::getValue('id_layout');
$layout = new Jxmegalayout();
if (!$result = $layout->renderLayoutContent($id_layout)) {
die(Tools::jsonEncode(array('status' => 'false', 'message' => $this->l('Some errors occurred'))));
}
die(Tools::jsonEncode(array('status' => 'true', 'layout' => $result[0], 'layout_buttons' => $result[1])));
}
public function ajaxProcessGetLayoutRemoveConfirmation()
{
$id_layout = Tools::getValue('id_layout');
$layout = new Jxmegalayout();
if (!$result = $layout->showMessage($id_layout, 'layoutRemoveConf')) {
die(Tools::jsonEncode(array('status' => 'false', 'message' => $this->l('Some errors occurred'))));
}
die(Tools::jsonEncode(array('status' => 'true', 'message' => $result)));
}
public function ajaxProcessRemoveLayout()
{
$id_layout = (int)Tools::getValue('id_layout');
$layouts = JXMegaLayoutItems::getItems($id_layout);
$jxmegalayout = new Jxmegalayout();
$jxmegalayout->deleteFilesOfLayout($id_layout);
if ($layouts && count($layouts) > 0) {
foreach ($layouts as $layout) {
$item = new JXMegaLayoutItems($layout['id_item']);
if (!$item->delete()) {
die(Tools::jsonEncode(
array(
'status' => 'false',
'message' => $this->l('Some error occurred. Can\'t delete layout item').$item->id
)
));
}
}
}
$tab = new JXMegaLayoutLayouts($id_layout);
if (!$tab->delete() || !$tab->dropLayoutFromPages()) {
die(Tools::jsonEncode(array('status' => 'false', 'message' => 'Can\'t delete layout')));
}
die(Tools::jsonEncode(
array('status' => 'true', 'message' => $this->l(
'Layout is successfully removed'
))
));
}
public function ajaxProcessGetLayoutRenameConfirmation()
{
$id_layout = Tools::getValue('id_layout');
$layout = new Jxmegalayout();
$tab = new JXMegaLayoutLayouts($id_layout);
if (!$result = $layout->showMessage($id_layout, 'layoutRenameConf', $tab->layout_name)) {
die(Tools::jsonEncode(array('status' => 'false', 'message' => $this->l('Some errors occurred'))));
}
die(Tools::jsonEncode(array('status' => 'true', 'message' => $result)));
}
public function ajaxProcessRenameLayout()
{
$id_layout = (int)Tools::getValue('id_layout');
$layout_name = Tools::getValue('layout_name');
$jxmegalayout = new Jxmegalayout();
if ((bool)JXMegaLayoutLayouts::getLayoutByName($layout_name)) {
die(Tools::jsonEncode(
array('status' => 'false', 'type' => 'popup', 'message' => $this->l('You have preset with this name'))
));
} else {
if (!$jxmegalayout->renameFilesOfLayout($id_layout, $layout_name)) {
die(Tools::jsonEncode(
array('status' => 'false', 'message' => $this->l('Can\'t rename a layouts files'))
));
}
}
$tab = new JXMegaLayoutLayouts($id_layout);
$tab->layout_name = $layout_name;
if (!$tab->update()) {
die(Tools::jsonEncode(array('status' => 'false', 'message' => $this->l('Can\'t update a layout name'))));
}
die(Tools::jsonEncode(array('status' => 'true', 'message' => $this->l('Layout name is successfully changed'))));
}
public function ajaxProcessDisableLayout()
{
$id_layout = (int)Tools::getValue('id_layout');
$jxmegalayout = new Jxmegalayout();
$tab = new JXMegaLayoutLayouts($id_layout);
$tab->status = 0;
if (!$tab->update() || !$tab->disableLayoutForAllPages()) {
die(Tools::jsonEncode(array('status' => 'false', 'message' => $this->l('Can\'t disable layout'))));
}
if (!$jxmegalayout->combineAllItemsStyles()) {
die(Tools::jsonEncode(
array('status' => 'false', 'message' => $this->l('Can\'t regenerate layout styles'))
));
}
die(Tools::jsonEncode(array('status' => 'true', 'message' => $this->l('Layout is disabled'))));
}
public function ajaxProcessEnableLayout()
{
$id_layout = (int)Tools::getValue('id_layout');
$hook_name = Tools::getValue('hook_name');
$pages = Tools::getValue('pages'); // pages list if assigned not for all
$status = Tools::getValue('layout_status'); // current status of layout
$type = ''; // set type for different responses after updating
$jxmegalayout = new Jxmegalayout();
// do if assigned for all pages
if (!$pages) {
$tabs = JXMegaLayoutLayouts::getLayoutsForHook($hook_name, $this->context->shop->id);
if ($tabs) {
foreach ($tabs as $layout) {
$tab = new JXMegaLayoutLayouts($layout['id_layout']);
$tab->status = 0;
if (!$tab->update()) {
die(Tools::jsonEncode(
array('status' => 'false', 'message' => $this->l('Can\'t disable previous layout'))
));
}
}
}
$item = new JXMegaLayoutLayouts($id_layout);
$item->status = 1;
if (!$item->update() || !$item->dropLayoutFromPages()) {
die(Tools::jsonEncode(array('status' => 'false', 'message' => $this->l('Can\'t enable this layout'))));
}
$type = 'all'; // set type for response
$response_pages = $this->l('All pages');
} else {
$item = new JXMegaLayoutLayouts($id_layout);
// do if layout was just cleared but not enabled/disabled
if ($pages == 'empty') {
if ($item->dropLayoutFromPages()) {
die(Tools::jsonEncode(
array('status' => 'true', 'clear', 'message' => $this->l('Layout is saved'))
));
}
}
$item->status = 0;
if (!$item->update()) {
die(Tools::jsonEncode(array('status' => 'false', 'message' => $this->l('Can\'t enable this layout'))));
}
$item->setLayoutToPage($pages, $hook_name, $status);
$response_pages = implode(', ', $pages);
if ($status) {
$type = 'sub';// set type for response
}
}
if (!$jxmegalayout->combineAllItemsStyles()) {
die(Tools::jsonEncode(
array('status' => 'false', 'message' => $this->l('Can\'t regenerate layout styles'))
));
}
// do if different pages assigned
if ($pages) {
$relations = $this->l('assigned');
if ($status) {
$relations = $this->l('enabled');
}
die(Tools::jsonEncode(
array(
'status' => 'true',
'type' => $type,
'message' => sprintf(
$this->l('Layout(s) is(are) %s for %s'),
$relations,
$response_pages
)
)
));
} else {
die(Tools::jsonEncode(
array(
'status' => 'true',
'type' => $type,
'message' => $this->l('Layout is enabled for All Pages')
)
));
}
}
public function ajaxProcessGetImportInfo()
{
$import = new JXMegaLayoutImport();
$import_path = new Jxmegalayout();
Jxmegalayout::cleanFolder($import_path->getLocalPath().'import/');
$file_name = basename($_FILES['file']['name']);
$upload_file = $import_path->getLocalPath().'import/'.$file_name;
move_uploaded_file($_FILES['file']['tmp_name'], $upload_file);
$preview = $import->layoutPreview($import_path->getLocalPath().'import/', $file_name);
$rawPreview = $import->layoutPreview($import_path->getLocalPath().'import/', $file_name, true);
die(Tools::jsonEncode(array('status' => 'true', 'rawData' => $rawPreview, 'preview' => $preview)));
}
public function ajaxProcessImportLayout()
{
$import = new JXMegaLayoutImport();
$import_path = new Jxmegalayout();
Jxmegalayout::cleanFolder($import_path->getLocalPath().'import/');
$file_name = basename($_FILES['file']['name']);
$upload_file = $import_path->getLocalPath().'import/'.$file_name;
move_uploaded_file($_FILES['file']['tmp_name'], $upload_file);
$name_layout = Tools::getValue('name_layout');
if ((bool)JXMegaLayoutLayouts::getLayoutByName($name_layout)) {
die(Tools::jsonEncode(
array('status' => 'false', 'type' => 'popup', 'message' => $this->l('You have preset with this name'))
));
}
$import->importLayout($import_path->getLocalPath().'import/', $file_name, false, $name_layout);
die(Tools::jsonEncode(array('status' => 'true', 'response_msg' => $this->l('Successful import'))));
}
public function ajaxProcessLoadLayoutTabContent()
{
$hook = Tools::getValue('tab_name');
$info = $this->module->getLayoutTabConfig($hook, $this->module->defLayoutHooks[$hook]);
die(Tools::jsonEncode(array('status' => true, 'content' => $info)));
}
public function ajaxProcessAfterImport()
{
$import_path = new Jxmegalayout();
$path = $import_path->getLocalPath().'import/';
Jxmegalayout::cleanFolder($path);
die(Tools::jsonEncode(array('status' => 'true')));
}
public function ajaxProcessAfterExport()
{
die(Tools::jsonEncode(array('status' => 'true')));
}
public function ajaxProcessResetToDefault()
{
// get all tabs for this store
$layouts = JXMegaLayoutLayouts::getShopLayoutsIds();
if ($layouts) {
foreach ($layouts as $layout) {
// if no layouts for this tab delete it immediately
if (!$items = JXMegaLayoutItems::getItems($layout['id_layout'])) {
$current_layout = new JXMegaLayoutLayouts($layout['id_layout']);
if (!$current_layout->dropLayoutFromPages() || !$current_layout->delete()) {
die(Tools::jsonEncode(
array(
'status' => false,
'message' => $this->l('Some error occurred. Can\'t delete layout').$current_layout->id
)
));
}
// if there is layouts for this tab delete all and delete tab after
} else {
foreach ($items as $item) {
$current_item = new JXMegaLayoutItems($item['id_item']);
if (!$current_item->delete()) {
die(Tools::jsonEncode(
array(
'status' => false,
'message' => $this->l('Some error occurred. Can\'t delete layout item').$current_item->id
)
));
}
}
$current_layout = new JXMegaLayoutLayouts($layout['id_layout']);
if (!$current_layout->dropLayoutFromPages() || !$current_layout->delete()) {
die(Tools::jsonEncode(
array(
'status' => false,
'message' => $this->l('Some error occurred. Can\'t delete layout item').$current_layout->id
)
));
}
}
}
}
$jxmegalayout = new Jxmegalayout();
// install default layouts from "default" folder
if (!$jxmegalayout->installDefLayouts()) {
die(Tools::jsonEncode(array('status' => false, 'message' => $this->l('Can\'t load default layouts'))));
}
die(Tools::jsonEncode(array('status' => true, 'message' => $this->l('All data is successfully removed'))));
}
public function ajaxProcessUpdateOptionOptimize()
{
$optimize = new JXMegaLayoutOptimize();
$optimize->optimize();
Configuration::updateValue('JXMEGALAYOUT_OPTIMIZE', true);
die(Tools::jsonEncode(array('status' => 'true', 'response_msg' => $this->l('Optimization is complete'))));
}
public function ajaxProcessUpdateOptionDeoptimize()
{
$optimize = new JXMegaLayoutOptimize();
$optimize->deoptimize();
Configuration::updateValue('JXMEGALAYOUT_OPTIMIZE', false);
die(Tools::jsonEncode(array('status' => 'true', 'response_msg' => $this->l('Optimization is disabled'))));
}
public function ajaxProcessOptimizeMessage()
{
$optimize = new JXMegaLayoutOptimize();
$needOptimization = false;
$optimize->deoptimize();
Configuration::updateValue('JXMEGALAYOUT_OPTIMIZE', false);
if (Configuration::get('JXMEGALAYOUT_SHOW_MESSAGES') != '1' || Configuration::get('JXMEGALAYOUT_OPTIMIZE') == '1') {
$needOptimization = true;
}
die(Tools::jsonEncode(array('status' => 'true', 'needOptimization' => !$needOptimization)));
}
public function ajaxProcessShowMessages()
{
$value = Configuration::get('JXMEGALAYOUT_SHOW_MESSAGES');
if ((bool)$value) {
$optimize = new JXMegaLayoutOptimize();
$optimize->deoptimize();
Configuration::updateValue('JXMEGALAYOUT_OPTIMIZE', false);
Configuration::updateValue('JXMEGALAYOUT_SHOW_MESSAGES', false);
die(Tools::jsonEncode(array('status' => false, 'response_msg' => $this->l('Optimization is disabled'))));
} else {
$optimize = new JXMegaLayoutOptimize();
$optimize->optimize();
Configuration::updateValue('JXMEGALAYOUT_OPTIMIZE', true);
Configuration::updateValue('JXMEGALAYOUT_SHOW_MESSAGES', true);
die(Tools::jsonEncode(array('status' => true, 'response_msg' => $this->l('Optimization is complete'))));
}
}
public function ajaxProcessGetCssClassesByUnique()
{
$jxmegalayout = new Jxmegalayout();
$classes = $jxmegalayout->getModuleExtraCss(Tools::getValue('unique_id'));
$active = JXMegaLayoutItems::getItemCssByUniqueId(Tools::getValue('unique_id'));
die(Tools::jsonEncode(array('status' => 'true', 'classes' => $classes, 'active' => $active)));
}
/**
* Load the extra content tabs with a data included
*/
public function ajaxProcessLoadExtraContent()
{
$item_type = Tools::getValue('item_type');
$id_item = Tools::getValue('id_item');
$tools = new Jxmegalayout();
$extra_content = $tools->renderToolExtraContent($item_type, $id_item);
die(Tools::jsonEncode(array('status' => 'true', 'content' => $extra_content)));
}
/**
* Attempt to save extra content
*/
public function ajaxProcessSaveExtraItem()
{
$item_type = Tools::getValue('extra_content_type');
$tools = new Jxmegalayout();
$extra_content = $tools->saveExtraContent($item_type, Tools::getAllValues());
die(json_encode(array('status' => $extra_content['status'], 'content' => $extra_content['report'])));
}
/**
* Attempt to remove extra content
*/
public function ajaxProcessRemoveExtraItem()
{
$item_type = Tools::getValue('item_type');
$id_item = Tools::getValue('id_extra_item');
$tools = new Jxmegalayout();
$extra_content = $tools->removeExtraContent($item_type, $id_item);
die(Tools::jsonEncode(array('status' => 'true', 'content' => $extra_content)));
}
public function ajaxProcessAddExtraContentConfirmation()
{
$jxmegalayout = new Jxmegalayout();
if (!$form = $jxmegalayout->addExtraContentForm()) {
die(Tools::jsonEncode(array('status' => 'false', 'message' => $this->l('Some error occurred'))));
}
die(Tools::jsonEncode(array('status' => 'true', 'message' => $form)));
}
/**
* Start process of extra content generation
*/
public function ajaxProcessExportExtraContent()
{
$megalayout = new Jxmegalayout();
$export = new JXMegaLayoutExtraExport($megalayout->getLocalPath(), $megalayout->getWebPath());
die(Tools::jsonEncode(array('status' => true, 'href' => $export->export())));
}
/**
* Load extra content selection form to the back-end
*/
public function ajaxProcessImportExtraContentForm()
{
$jxmegalayout = new Jxmegalayout();
die(Tools::jsonEncode(
array('status' => true, 'content' => $jxmegalayout->display(
$jxmegalayout->getLocalPath(),
'/views/templates/admin/tools/extra/extra-content-import.tpl'
))
));
}
/**
* Start to import extra content after a valid archive was added
*/
public function ajaxProcessImportExtraContent()
{
$jxmegalayout = new Jxmegalayout();
$fileName = basename($_FILES['file']['name']);
$upload_file = $jxmegalayout->getLocalPath().'import/'.$fileName;
if (!move_uploaded_file($_FILES['file']['tmp_name'], $upload_file)) {
die(Tools::jsonEncode(array('status' => false, 'error' => $this->l('An error occurred during an archive uploading'))));
}
$extraContentImport = new JXMegaLayoutExtraImport($jxmegalayout->getLocalPath());
$extraContentImport->import();
}
public function ajaxProcessLoadThemesContent()
{
$themeBuilder = new JXMegalayoutThemeBuilder();
$jxmegalayout = new Jxmegalayout();
$theme = Tools::getValue('theme');
$childTheme = Tools::getValue('child_theme');
$action = Tools::getValue('theme_action');
if (!Validate::isThemeName($theme)) {
die(Tools::jsonEncode(array('status' => false, 'error' => $this->l('It seems that you attempt to load an invalid theme!'))));
}
$parentTheme = $themeBuilder->setParentTheme($theme);
$this->context->smarty->assign('current_theme', $theme);
$this->context->smarty->assign('has_update', $parentTheme->checkParentThemeUpdates());
$this->context->smarty->assign('has_library_update', $parentTheme->checkParentThemeLibraryUpdates());
switch ($action) {
case 'load_parent':
$this->context->smarty->assign('children_themes', $parentTheme->getChildren());
$content = $jxmegalayout->display($jxmegalayout->getLocalPath(), '/views/templates/admin/tools/themebuilder/theme-builder-manage-themes.tpl');
break;
case 'add_new_theme':
$this->context->smarty->assign('theme_library', $parentTheme->loadParentThemeLibrary());
$this->context->smarty->assign('theme_library_previews', $parentTheme->loadParentThemeLibraryPreviews());
$content = $jxmegalayout->display($jxmegalayout->getLocalPath(), '/views/templates/admin/tools/themebuilder/theme-builder-new-theme.tpl');
break;
case 'load_child':
$this->context->smarty->assign('theme_library', $parentTheme->loadParentThemeLibrary());
$this->context->smarty->assign('theme_library_previews', $parentTheme->loadParentThemeLibraryPreviews());
$this->context->smarty->assign('current_child_theme', $themeBuilder->loadChildThemeInfo($childTheme));
$content = $jxmegalayout->display($jxmegalayout->getLocalPath(), '/views/templates/admin/tools/themebuilder/theme-builder-new-theme.tpl');
break;
}
die(Tools::jsonEncode(array('status' => true, 'content' => $content)));
}
public function ajaxProcessSaveBuilderTheme()
{
$themeBuilder = new JXMegalayoutThemeBuilder();
$jxmegalayout = new Jxmegalayout();
$parentTheme = Tools::getValue('parent_theme');
$themeName = Tools::getValue('theme_name');
$themePublicName = Tools::getValue('theme_public_name');
$layouts = Tools::getValue('layouts');
if (!$themeName && $errors = $jxmegalayout->validateThemeNames($themeName, $themePublicName)) {
die(Tools::jsonEncode(array('status' => false, 'content' => $errors)));
}
if (!$layouts) {
die(Tools::jsonEncode(array('status' => false, 'content' => $this->l('No layouts were selected. Please select at least one layout to create a new child theme.'))));
}
$this->context->smarty->assign('current_theme', $parentTheme);
if (!$errors = $themeBuilder->buildChildTheme($parentTheme, $themeName, $themePublicName, $layouts)) {
$this->context->smarty->assign('message', $jxmegalayout->displayConfirmation($this->l('All setting were successfully saved.')));
die(Tools::jsonEncode(array('status' => true, 'content' => $jxmegalayout->display($jxmegalayout->getLocalPath(), '/views/templates/admin/tools/themebuilder/message/theme-builder-message.tpl'))));
}
switch ($errors) {
case 1:
$message = $this->l('An error occurred during files copying.');
break;
case 2:
$message = $this->l('An error occurred during settings file creation.');
break;
case 3:
$message = $this->l('An error occurred during preview image copying.');
break;
case 4:
$message = $this->l('An error occurred during child theme settings file creation.');
break;
}
die(Tools::jsonEncode(array('status' => false, 'content' => $jxmegalayout->displayError($message))));
}
public function ajaxProcessRemoveBuilderTheme()
{
$themeBuilder = new JXMegalayoutThemeBuilder();
$jxmegalayout = new Jxmegalayout();
$themeName = Tools::getValue('theme_name');
$parentTheme = Tools::getValue('parent_theme');
if (!$themeName) {
die(Tools::jsonEncode(array('status' => false, 'content' => $jxmegalayout->displayError('The theme was not found.'))));
}
if ($error = $themeBuilder->remove($themeName)) {
switch ($error) {
case 1:
$message = $this->l('You cannot delete a theme while it is used by any of your stores. Please, switch all stores themes to another one and try again.');
break;
case 2:
$message = $this->l('It seems that cannot delete a theme. Probably you don\'t have enough do to process this');
break;
}
die(Tools::jsonEncode(array('status' => false, 'content' => $jxmegalayout->displayError($message))));
}
$this->context->smarty->assign('current_theme', $parentTheme);
$this->context->smarty->assign('message', $jxmegalayout->displayConfirmation($this->l('Theme successfully deleted.')));
die(Tools::jsonEncode(array('status' => true, 'content' => $jxmegalayout->display($jxmegalayout->getLocalPath(), '/views/templates/admin/tools/themebuilder/message/theme-builder-message.tpl'))));
}
public function ajaxProcessUpdateParentTheme()
{
$jxmegalayoutBuilder = new JXMegalayoutThemeBuilder();
$jxmegalayout = new Jxmegalayout();
$themeName = Tools::getValue('parent_theme');
$parentTheme = $jxmegalayoutBuilder->setParentTheme($themeName);
if ($parentTheme->updateParentTheme()) {
die(Tools::jsonEncode(array('status' => true, 'content' => $jxmegalayout->displayConfirmation('Parent theme successfully updated'))));
}
die(Tools::jsonEncode(array('status' => false, 'content' => $jxmegalayout->displayError('An error occurred during theme updating'))));
}
public function ajaxProcessUpdateParentThemeLibrary()
{
$jxmegalayoutBuilder = new JXMegalayoutThemeBuilder();
$jxmegalayout = new Jxmegalayout();
$themeName = Tools::getValue('parent_theme');
$parentTheme = $jxmegalayoutBuilder->setParentTheme($themeName);
if ($parentTheme->updateParentThemeLibrary()) {
die(Tools::jsonEncode(array('status' => true, 'content' => $jxmegalayout->displayConfirmation('Parent theme library successfully updated'))));
}
die(Tools::jsonEncode(array('status' => false, 'content' => $jxmegalayout->displayError('An error occurred during theme\'s library updating'))));
}
}

View File

@@ -0,0 +1,8 @@
drwxr-xr-x 3 30094 users 8 Oct 6 10:16 .
drwxr-xr-x 9 30094 users 15 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 1546 Aug 31 2021 Footer-1.zip
-rw-r--r-- 1 30094 users 2032 Aug 31 2021 Header-1.zip
-rw-r--r-- 1 30094 users 1399 Aug 31 2021 Home-1.zip
-rw-r--r-- 1 30094 users 1171 Aug 31 2021 Product-footer1.zip
-rw-r--r-- 1 30094 users 1171 Aug 31 2021 TopColumn-1.zip
drwxr-xr-x 2 30094 users 2 Oct 6 10:16 temp

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,2 @@
drwxr-xr-x 2 30094 users 2 Oct 6 10:16 .
drwxr-xr-x 3 30094 users 8 Oct 6 10:16 ..

View File

@@ -0,0 +1,75 @@
drwxr-xr-x 2 30094 users 75 Oct 6 10:16 .
drwxr-xr-x 9 30094 users 15 Oct 6 10:16 ..
-rw-r--r-- 1 30094 users 227237 Aug 31 2021 1UOXhHvoK9Gpn4d7.jpg
-rw-r--r-- 1 30094 users 910931 Aug 31 2021 1YKe0udf21VPe1Sd.png
-rw-r--r-- 1 30094 users 258011 Sep 6 14:32 2U0TSPIrvfemLtfP.jpg
-rw-r--r-- 1 30094 users 910931 Aug 31 2021 35q7Gozi1DrI86nv.png
-rw-r--r-- 1 30094 users 246451 Dec 6 2021 3ttRSavwAcuDMqro.jpg
-rw-r--r-- 1 30094 users 1130100 Aug 31 2021 49Fze2wBmEe5X62N.png
-rw-r--r-- 1 30094 users 1212479 Aug 31 2021 69NCFsQBk9FPL2hI.png
-rw-r--r-- 1 30094 users 1066502 Aug 31 2021 7I89tncujs1WQhj4.png
-rw-r--r-- 1 30094 users 91555 Oct 19 2021 7ObBsrdP3gcFGo5B.jpg
-rw-r--r-- 1 30094 users 378532 Sep 1 2021 7fqtAGDm8uwuA9Qy.jpg
-rw-r--r-- 1 30094 users 1147815 Aug 31 2021 8IS7b3oLuJ67IY9j.png
-rw-r--r-- 1 30094 users 464771 Aug 31 2021 8btsTuJrYChAhckT.jpg
-rw-r--r-- 1 30094 users 867070 Oct 19 2021 92udZBgNwLsgpKVM.jpg
-rw-r--r-- 1 30094 users 150497 Sep 6 14:47 ATxrjAEaSJPRTKAq.jpg
-rw-r--r-- 1 30094 users 1130100 Aug 31 2021 AWOUUUT0Hazfdo04.png
-rw-r--r-- 1 30094 users 483093 Aug 31 2021 BquGINba66hMzkQE.jpg
-rw-r--r-- 1 30094 users 1066502 Aug 31 2021 CKLJBZ2qSzitwdZG.png
-rw-r--r-- 1 30094 users 47307 Sep 2 2021 CVJbN1tow3cmGsEu.jpg
-rw-r--r-- 1 30094 users 464771 Aug 31 2021 DGJADPUVJyevXNqN.jpg
-rw-r--r-- 1 30094 users 36443 Aug 31 2021 EGssSjfYm6aCGisT.png
-rw-r--r-- 1 30094 users 910931 Aug 31 2021 I4AL5ahSq3g1WPrR.png
-rw-r--r-- 1 30094 users 1147815 Aug 31 2021 ILh9VuPby31MAZsD.png
-rw-r--r-- 1 30094 users 1212479 Aug 31 2021 JbQFjayvbovrmSUf.png
-rw-r--r-- 1 30094 users 1066502 Aug 31 2021 LVMLbjSqOwrptRLp.png
-rw-r--r-- 1 30094 users 27703 Sep 21 2021 LbkC7WRn4d0hSxiI.png
-rw-r--r-- 1 30094 users 286040 Sep 1 2021 MZ2v5xXDV2STqxHt.jpg
-rw-r--r-- 1 30094 users 91555 Oct 19 2021 Nieir28P3k9FgTu6.jpg
-rw-r--r-- 1 30094 users 483093 Aug 31 2021 PJG5O7GheF61dsP2.jpg
-rw-r--r-- 1 30094 users 338688 Nov 19 2021 PpVH28yOHBEpsBJt.jpg
-rw-r--r-- 1 30094 users 152934 Sep 1 2021 QN926TugLqs2AHFE.jpg
-rw-r--r-- 1 30094 users 1147815 Aug 31 2021 Qe1X4PAOExO8kN7M.png
-rw-r--r-- 1 30094 users 281448 Aug 31 2021 SrghV4R7PjITERGV.jpg
-rw-r--r-- 1 30094 users 1147815 Aug 31 2021 SzRXfiVVTny3Bfge.png
-rw-r--r-- 1 30094 users 315464 Nov 19 2021 TWw6V9KiVZpc4FMW.jpg
-rw-r--r-- 1 30094 users 464771 Aug 31 2021 UU1JYx8xBPu3e3hy.jpg
-rw-r--r-- 1 30094 users 483093 Aug 31 2021 VtMs0FB7Vo7mgO4F.jpg
-rw-r--r-- 1 30094 users 36443 Aug 31 2021 Yjz17EMCP6vOGvgd.png
-rw-r--r-- 1 30094 users 910931 Aug 31 2021 Zot61gDFi4bIM50W.png
-rw-r--r-- 1 30094 users 249727 Sep 6 14:35 bCM4zqD7yP5hsh85.jpg
-rw-r--r-- 1 30094 users 223175 Aug 31 2021 bEdvqzsxyF5GMPpg.jpg
-rw-r--r-- 1 30094 users 93903 Oct 19 2021 bG8mQ7sXwwYuTq9Q.jpg
-rw-r--r-- 1 30094 users 890128 Nov 19 2021 bzL39P3JNQaUdWXd.jpg
-rw-r--r-- 1 30094 users 602008 Sep 1 2021 d55bTLIQe09IDZuX.jpg
-rw-r--r-- 1 30094 users 1212479 Aug 31 2021 eWx8f0o59ZTYsXHh.png
-rw-r--r-- 1 30094 users 8498 Sep 21 2021 f9JrnjGwUOo24FKC.png
-rw-r--r-- 1 30094 users 1066502 Aug 31 2021 fV9Zooeea6rHSrZw.png
-rw-r--r-- 1 30094 users 910931 Aug 31 2021 gFK9JvOvQ0GHinuD.png
-rw-r--r-- 1 30094 users 1130100 Aug 31 2021 hgve9eNsHORJwHM3.png
-rw-r--r-- 1 30094 users 464771 Aug 31 2021 hpwLjvUUNJtoRFbi.jpg
-rw-r--r-- 1 30094 users 141158 Sep 6 14:45 i4hIjN097jPzwYtF.jpg
-rw-r--r-- 1 30094 users 36443 Aug 31 2021 iy6WehS40CRaWjCt.png
-rw-r--r-- 1 30094 users 192582 Sep 14 19:10 j5n7gYfA7W0gVKJr.jpg
-rw-r--r-- 1 30094 users 159289 May 31 13:02 jXpLO6gMWpQam61K.jpg
-rw-r--r-- 1 30094 users 320811 Nov 19 2021 k6eJ9mxv5fGZoeqg.jpg
-rw-r--r-- 1 30094 users 98444 Oct 19 2021 kEVDoNqxCMj90Xwv.jpg
-rw-r--r-- 1 30094 users 788262 Nov 19 2021 kOOpgyHmqKBNDkv3.jpg
-rw-r--r-- 1 30094 users 959735 Sep 1 2021 kxxCx3vJeAZREwP1.jpg
-rw-r--r-- 1 30094 users 36443 Aug 31 2021 mghbGmEZQIUsQFIP.png
-rw-r--r-- 1 30094 users 483093 Aug 31 2021 nWiRC3eanrGynXdt.jpg
-rw-r--r-- 1 30094 users 1130100 Aug 31 2021 nyYcfvTU354gIZQ0.png
-rw-r--r-- 1 30094 users 483093 Aug 31 2021 oPir9eRZbag1r2Ay.jpg
-rw-r--r-- 1 30094 users 227037 Oct 19 2021 oopmrIO4dqY3KdHD.jpg
-rw-r--r-- 1 30094 users 1212479 Aug 31 2021 qJcibFxs9MsKwo8q.png
-rw-r--r-- 1 30094 users 1147815 Aug 31 2021 qnus2F4jNx5N0fwO.png
-rw-r--r-- 1 30094 users 867070 Oct 19 2021 r7NZVwdx146TkTBW.jpg
-rw-r--r-- 1 30094 users 1212479 Aug 31 2021 rW9GesGezh2fsBhT.png
-rw-r--r-- 1 30094 users 330801 Nov 19 2021 rWevsVgOBYBi4be0.jpg
-rw-r--r-- 1 30094 users 335964 Nov 19 2021 sAkFNi9s0I8Ft2Eq.jpg
-rw-r--r-- 1 30094 users 36443 Aug 31 2021 vLRXgtennRiF57pT.png
-rw-r--r-- 1 30094 users 464771 Aug 31 2021 vbfhSRJtPSSUXkA8.jpg
-rw-r--r-- 1 30094 users 344336 Nov 19 2021 vvw4Eef442cduZaS.jpg
-rw-r--r-- 1 30094 users 1130100 Aug 31 2021 vz4Jgy4G6cLb8jFS.png
-rw-r--r-- 1 30094 users 200968 May 31 12:58 wQouMHuh7GWiIRuD.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 890 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 890 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 890 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 890 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 869 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 890 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 770 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 937 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Some files were not shown because too many files have changed in this diff Show More