· 8 years ago · Dec 26, 2017, 03:26 PM
1<?php
2
3use PrestaShop\PrestaShop\Core\Module\WidgetInterface;
4
5if (!defined('_PS_VERSION_'))
6 exit;
7
8class AtchConfigurator extends Module implements WidgetInterface
9{
10 protected $max_image_size = 1048576;
11 protected $default_language;
12 protected $languages;
13
14 public function __construct()
15 {
16 $this->name = 'atchconfigurator';
17 $this->author = 'atchworks';
18 $this->version = '2.0.0';
19 $this->tab = 'front_office_features';
20 $this->bootstrap = true;
21 $this->secure_key = Tools::encrypt($this->name);
22 $this->default_language = Language::getLanguage(Configuration::get('PS_LANG_DEFAULT'));
23 $this->languages = Language::getLanguages();
24 parent::__construct();
25 $this->displayName = $this->l('Theme configurator');
26 $this->description = $this->l('Configure the main elements of Atchworks theme.');
27 $this->ps_versions_compliancy = array('min' => '1.7.0.0', 'max' => _PS_VERSION_);
28 $this->module_path = _PS_MODULE_DIR_.$this->name.'/';
29 $this->uploads_path = _PS_MODULE_DIR_.$this->name.'/img/';
30 $this->admin_tpl_path = _PS_MODULE_DIR_.$this->name.'/views/templates/admin/';
31 $this->hooks_tpl_path = _PS_MODULE_DIR_.$this->name.'/views/templates/hooks/';
32 }
33
34 public function createAjaxController()
35 {
36 $tab = new Tab();
37 $tab->active = 1;
38 $languages = Language::getLanguages(false);
39 if (is_array($languages))
40 foreach ($languages as $language)
41 $tab->name[$language['id_lang']] = 'atchconfigurator';
42 $tab->class_name = 'AdminAtchConfigurator';
43 $tab->module = $this->name;
44 $tab->id_parent = - 1;
45 return (bool)$tab->add();
46 }
47
48 private function _removeAjaxContoller()
49 {
50 if ($tab_id = (int)Tab::getIdFromClassName('AdminAtchConfigurator'))
51 {
52 $tab = new Tab($tab_id);
53 $tab->delete();
54 }
55 return true;
56 }
57
58 public function install()
59 {
60 $themes_variables = array(
61 'layout_style' => 'wide',
62 'header_style' => 1
63 );
64
65 if (!parent::install()
66 || !$this->installDB() ||
67 !$this->registerHook('displayHeader') ||
68 !$this->registerHook('displayHome') ||
69 !$this->registerHook('displayFooterBefore') ||
70 !$this->registerHook('displayFooterAfter') ||
71 !$this->registerHook('actionObjectLanguageAddAfter') ||
72 !Configuration::updateValue('ATCH_VARIABLES', serialize($themes_variables)) ||
73 !$this->createAjaxController()
74
75 )
76 return false;
77
78 return true;
79 }
80
81 private function installDB()
82 {
83 return (
84 Db::getInstance()->Execute('DROP TABLE IF EXISTS `'._DB_PREFIX_.'atchconfigurator`') &&
85 Db::getInstance()->Execute('
86 CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'atchconfigurator` (
87 `id_item` int(10) unsigned NOT NULL AUTO_INCREMENT,
88 `id_shop` int(10) unsigned NOT NULL,
89 `id_lang` int(10) unsigned NOT NULL,
90 `item_order` int(10) unsigned NOT NULL,
91 `title` VARCHAR(100),
92 `title_use` tinyint(1) unsigned NOT NULL DEFAULT \'0\',
93 `mobile` tinyint(1) unsigned NOT NULL DEFAULT \'0\',
94 `hook` VARCHAR(100),
95 `url` TEXT,
96 `target` tinyint(1) unsigned NOT NULL DEFAULT \'0\',
97 `image` VARCHAR(100),
98 `image_w` VARCHAR(10),
99 `image_h` VARCHAR(10),
100 `icon` VARCHAR(100),
101 `grid` VARCHAR(100),
102 `html` TEXT,
103 `active` tinyint(1) unsigned NOT NULL DEFAULT \'1\',
104 PRIMARY KEY (`id_item`)
105 ) ENGINE = '._MYSQL_ENGINE_.' DEFAULT CHARSET=UTF8;')
106 );
107
108 }
109
110
111 public function uninstall()
112 {
113 if (!parent::uninstall() ||
114 !Db::getInstance()->Execute('DROP TABLE IF EXISTS `'._DB_PREFIX_.'atchconfigurator`') ||
115 !$this->_removeAjaxContoller() ||
116 !Configuration::deleteByName('ATCH_VARIABLES')
117 )
118 return false;
119
120 return true;
121 }
122
123 public function hookdisplayHeader()
124 {
125 $this->context->smarty->assign(array(
126 'atch_variables' => Tools::unserialize(Configuration::get('ATCH_VARIABLES'))
127 ));
128 }
129
130
131 public function renderWidget($hookName, array $params)
132 {
133
134 if( $hookName == 'displayReassuranceTop'|| $hookName == 'displayFooterBefore' ){
135 $this->smarty->assign($this->getWidgetVariables($hookName, $params));
136 return $this->display(__FILE__, 'reinsurance.tpl');
137
138 } elseif ($hookName == 'displayHome') {
139 $this->smarty->assign($this->getWidgetVariables($hookName, $params));
140 return $this->display(__FILE__, 'home.tpl');
141
142 } elseif ($hookName == 'hookDisplayRightColumn' || $hookName == 'displayRightSlideColmun') {
143 $this->smarty->assign($this->getWidgetVariables($hookName, $params));
144 return $this->display(__FILE__, 'left.tpl');
145
146 } elseif ($hookName == 'displayReassuranceProduct') {
147 $this->smarty->assign($this->getWidgetVariables($hookName, $params));
148 return $this->display(__FILE__, 'product.tpl');
149
150 } elseif ($hookName == 'displayFooterAfter') {
151 $this->smarty->assign($this->getWidgetVariables($hookName, $params));
152 return $this->display(__FILE__, 'footer.tpl');
153 }
154
155 }
156
157
158 public function getWidgetVariables($hookName, array $params)
159 {
160
161 if( $hookName == 'displayReassuranceTop' || $hookName == 'displayFooterBefore' ){
162
163 return [
164 'htmlitems' => $this->getItemsFromHook('top'),
165 'hook' => 'top'
166 ];
167
168 } elseif ($hookName == 'displayHome' || $hookName == 'displayHomeFull') {
169
170 return [
171 'htmlitems' => $this->getItemsFromHook('home'),
172 'hook' => 'home'
173 ];
174 } elseif ($hookName == 'hookDisplayRightColumn' || $hookName == 'displayRightSlideColmun') {
175
176 return [
177 'htmlitems' => $this->getItemsFromHook('left'),
178 'hook' => 'left'
179 ];
180 } elseif ($hookName == 'displayReassuranceProduct') {
181
182 return [
183 'htmlitems' => $this->getItemsFromHook('right'),
184 'hook' => 'right'
185 ];
186 } elseif ($hookName == 'displayFooterAfter') {
187
188 return [
189 'htmlitems' => $this->getItemsFromHook('footer'),
190 'hook' => 'footer'
191 ];
192 }
193 }
194
195 protected function getItemsFromHook($hook)
196 {
197 if (!$hook)
198 return false;
199
200 return Db::getInstance()->ExecuteS('
201 SELECT *
202 FROM `'._DB_PREFIX_.'atchconfigurator`
203 WHERE id_shop = '.(int)$this->context->shop->id.' AND id_lang = '.(int)$this->context->language->id.'
204 AND hook = \''.pSQL($hook).'\' AND active = 1
205 ORDER BY item_order ASC');
206 }
207
208 protected function deleteImage($image)
209 {
210 $file_name = $this->uploads_path.$image;
211
212 if (realpath(dirname($file_name)) != realpath($this->uploads_path))
213 Tools::dieOrLog(sprintf('Could not find upload directory'));
214
215 if ($image != '' && is_file($file_name) && !strpos($file_name, 'banner-img') && !strpos($file_name, 'bg-theme') && !strpos($file_name, 'footer-bg'))
216 unlink($file_name);
217 }
218
219 protected function removeItem()
220 {
221 $id_item = (int)Tools::getValue('item_id');
222
223 if ($image = Db::getInstance()->getValue('SELECT image FROM `'._DB_PREFIX_.'atchconfigurator` WHERE id_item = '.(int)$id_item))
224 $this->deleteImage($image);
225
226 Db::getInstance()->delete(_DB_PREFIX_.'atchconfigurator', 'id_item = '.(int)$id_item);
227
228 if (Db::getInstance()->Affected_Rows() == 1)
229 {
230 Db::getInstance()->execute('
231 UPDATE `'._DB_PREFIX_.'atchconfigurator`
232 SET item_order = item_order-1
233 WHERE (
234 item_order > '.(int)Tools::getValue('item_order').' AND
235 id_shop = '.(int)$this->context->shop->id.' AND
236 hook = \''.pSQL(Tools::getValue('item_hook')).'\')'
237 );
238 Tools::redirectAdmin('index.php?tab=AdminModules&configure='.$this->name.'&conf=6&token='.Tools::getAdminTokenLite('AdminModules'));
239 }
240 else
241 $this->context->smarty->assign('error', $this->l('Can\'t delete the slide.'));
242 }
243
244 protected function updateItem()
245 {
246 $id_item = (int)Tools::getValue('item_id');
247 $title = Tools::getValue('item_title');
248 $content = Tools::getValue('item_html');
249 $icon = Tools::getValue('item_icon');
250 $grid = Tools::getValue('item_grid');
251
252 if (!Validate::isCleanHtml($title, (int)Configuration::get('PS_ALLOW_HTML_IFRAME')) || !Validate::isCleanHtml($content, (int)Configuration::get('PS_ALLOW_HTML_IFRAME')))
253 {
254 $this->context->smarty->assign('error', $this->l('Invalid content'));
255 return false;
256 }
257
258 $new_image = '';
259 $image_w = (is_numeric(Tools::getValue('item_img_w'))) ? (int)Tools::getValue('item_img_w') : '';
260 $image_h = (is_numeric(Tools::getValue('item_img_h'))) ? (int)Tools::getValue('item_img_h') : '';
261
262 if (!empty($_FILES['item_img']['name']))
263 {
264 if ($old_image = Db::getInstance()->getValue('SELECT image FROM `'._DB_PREFIX_.'atchconfigurator` WHERE id_item = '.(int)$id_item))
265 if (file_exists(dirname(__FILE__).'/img/'.$old_image))
266 @unlink(dirname(__FILE__).'/img/'.$old_image);
267
268 if (!$image = $this->uploadImage($_FILES['item_img'], $image_w, $image_h))
269 return false;
270
271 $new_image = 'image = \''.pSQL($image).'\',';
272 }
273
274 if (!Db::getInstance()->execute('
275 UPDATE `'._DB_PREFIX_.'atchconfigurator` SET
276 title = \''.pSQL($title).'\',
277 title_use = '.(int)Tools::getValue('item_title_use').',
278 mobile = '.(int)Tools::getValue('item_mobile').',
279 hook = \''.pSQL(Tools::getValue('item_hook')).'\',
280 url = \''.pSQL(Tools::getValue('item_url')).'\',
281 target = '.(int)Tools::getValue('item_target').',
282 '.$new_image.'
283 image_w = '.(int)$image_w.',
284 image_h = '.(int)$image_h.',
285 active = '.(int)Tools::getValue('item_active').',
286 html = \''.pSQL($this->filterVar($content), true).'\',
287 icon = \''.pSQL(Tools::purifyHTML($icon), true).'\',
288 grid = \''.pSQL(Tools::getValue('item_grid')).'\'
289 WHERE id_item = '.(int)Tools::getValue('item_id')
290 ))
291 {
292 if ($image = Db::getInstance()->getValue('SELECT image FROM `'._DB_PREFIX_.'atchconfigurator` WHERE id_item = '.(int)Tools::getValue('item_id')))
293 $this->deleteImage($image);
294
295 $this->context->smarty->assign('error', $this->l('An error occurred while saving data.'));
296
297 return false;
298 }
299
300 $this->context->smarty->assign('confirmation', $this->l('Successfully updated.'));
301
302 return true;
303 }
304
305 protected function uploadImage($image, $image_w = '', $image_h = '')
306 {
307 $res = false;
308 if (is_array($image) && (ImageManager::validateUpload($image, $this->max_image_size) === false) && ($tmp_name = tempnam(_PS_TMP_IMG_DIR_, 'PS')) && move_uploaded_file($image['tmp_name'], $tmp_name))
309 {
310 $salt = sha1(microtime());
311 $pathinfo = pathinfo($image['name']);
312 $img_name = $salt.'_'.Tools::str2url($pathinfo['filename']).'.'.$pathinfo['extension'];
313
314 if (ImageManager::resize($tmp_name, dirname(__FILE__).'/img/'.$img_name, $image_w, $image_h))
315 $res = true;
316 }
317
318 if (!$res)
319 {
320 $this->context->smarty->assign('error', $this->l('An error occurred during the image upload.'));
321 return false;
322 }
323
324 return $img_name;
325 }
326
327 public function getContent()
328 {
329 if (Tools::isSubmit('submitModule'))
330 {
331 $themes_variables = array(
332 'layout_style' => Tools::getValue('atch_layout_style'),
333 'header_style' => Tools::getValue('atch_header_style')
334 );
335 Configuration::updateValue('ATCH_VARIABLES', serialize($themes_variables));
336
337 }
338
339 $this->context->controller->addCSS($this->_path.'views/css/admin.css');
340 $this->context->controller->addJS($this->_path.'views/js/admin.js');
341
342 if (Tools::isSubmit('newItem'))
343 $this->addItem();
344 elseif (Tools::isSubmit('updateItem'))
345 $this->updateItem();
346 elseif (Tools::isSubmit('removeItem'))
347 $this->removeItem();
348
349 $html = $this->renderConfigurationForm();
350 $html .= $this->renderAtchConfiguratorForm();
351
352 return $html;
353 }
354
355 protected function addItem()
356 {
357 $title = Tools::getValue('item_title');
358 $content = Tools::getValue('item_html');
359 $icon = Tools::getValue('item_icon');
360 $grid = Tools::getValue('item_grid');
361
362 if (!Validate::isCleanHtml($title, (int)Configuration::get('PS_ALLOW_HTML_IFRAME'))
363 || !Validate::isCleanHtml($content, (int)Configuration::get('PS_ALLOW_HTML_IFRAME')))
364 {
365 $this->context->smarty->assign('error', $this->l('Invalid content'));
366 return false;
367 }
368
369 if (!$current_order = (int)Db::getInstance()->getValue('
370 SELECT item_order + 1
371 FROM `'._DB_PREFIX_.'atchconfigurator`
372 WHERE
373 id_shop = '.(int)$this->context->shop->id.'
374 AND id_lang = '.(int)Tools::getValue('id_lang').'
375 AND hook = \''.pSQL(Tools::getValue('item_hook')).'\'
376 ORDER BY item_order DESC'
377 ))
378 $current_order = 1;
379
380 $image_w = is_numeric(Tools::getValue('item_img_w')) ? (int)Tools::getValue('item_img_w') : '';
381 $image_h = is_numeric(Tools::getValue('item_img_h')) ? (int)Tools::getValue('item_img_h') : '';
382
383 if (!empty($_FILES['item_img']['name']))
384 {
385 if (!$image = $this->uploadImage($_FILES['item_img'], $image_w, $image_h))
386 return false;
387 }
388 else
389 {
390 $image = '';
391 $image_w = '';
392 $image_h = '';
393 }
394
395 if (!Db::getInstance()->Execute('
396 INSERT INTO `'._DB_PREFIX_.'atchconfigurator` (
397 `id_shop`, `id_lang`, `item_order`, `title`, `title_use`,`mobile`, `hook`, `url`, `target`, `image`, `image_w`, `image_h`, `html`, `icon`, `grid`, `active`
398 ) VALUES (
399 \''.(int)$this->context->shop->id.'\',
400 \''.(int)Tools::getValue('id_lang').'\',
401 \''.(int)$current_order.'\',
402 \''.pSQL($title).'\',
403 \''.(int)Tools::getValue('item_title_use').'\',
404 \''.(int)Tools::getValue('item_mobile').'\',
405 \''.pSQL(Tools::getValue('item_hook')).'\',
406 \''.pSQL(Tools::getValue('item_url')).'\',
407 \''.(int)Tools::getValue('item_target').'\',
408 \''.pSQL($image).'\',
409 \''.pSQL($image_w).'\',
410 \''.pSQL($image_h).'\',
411 \''.pSQL($this->filterVar($content), true).'\',
412 \''.pSQL($this->filterVar($icon), true).'\',
413 \''.pSQL(Tools::getValue('item_grid')).'\',
414 1)'
415 ))
416 {
417 if (!Tools::isEmpty($image))
418 $this->deleteImage($image);
419
420 $this->context->smarty->assign('error', $this->l('An error occurred while saving data.'));
421 return false;
422 }
423
424 $this->context->smarty->assign('confirmation', $this->l('New item successfully added.'));
425 return true;
426 }
427
428 public function renderConfigurationForm()
429 {
430
431 $fields_form = array(
432 'form' => array(
433 'legend' => array(
434 'title' => $this->l('Settings'),
435 'icon' => 'icon-cogs'
436 ),
437 'input' => array(
438 array(
439 'type' => 'text',
440 'label' => $this->getTranslator()->trans('Speed', array(), 'Modules.Imageslider.Admin'),
441 'name' => 'atch_layout_style',
442 'suffix' => 'milliseconds',
443 'class' => 'fixed-width-sm',
444 'desc' => $this->getTranslator()->trans('The duration of the transition between two slides.', array(), 'Modules.Imageslider.Admin')
445 ),
446 array(
447 'type' => 'switch',
448 'label' => $this->getTranslator()->trans('Pause on hover', array(), 'Modules.Imageslider.Admin'),
449 'name' => 'atch_header_style',
450 'desc' => $this->getTranslator()->trans('Stop sliding when the mouse cursor is over the slideshow.', array(), 'Modules.Imageslider.Admin'),
451 'values' => array(
452 array(
453 'id' => 'active_on',
454 'value' => 1,
455 'label' => $this->getTranslator()->trans('Enabled', array(), 'Admin.Global')
456 ),
457 array(
458 'id' => 'active_off',
459 'value' => 0,
460 'label' => $this->getTranslator()->trans('Disabled', array(), 'Admin.Global')
461 )
462 ),
463 ),
464 ),
465 'submit' => array(
466 'title' => $this->l('Save'),
467 'class' => 'btn btn-default pull-right'
468 )
469 ),
470 );
471
472 $helper = new HelperForm();
473 $helper->show_toolbar = false;
474 $helper->table = $this->table;
475 $lang = new Language((int)Configuration::get('PS_LANG_DEFAULT'));
476 $helper->default_form_language = $lang->id;
477 $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0;
478 $this->fields_form = array();
479
480 $helper->identifier = $this->identifier;
481 $helper->submit_action = 'submitModule';
482 $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false).'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name;
483 $helper->token = Tools::getAdminTokenLite('AdminModules');
484 $helper->tpl_vars = array(
485 'fields_value' => $this->getConfigFieldsValues(),
486 'languages' => $this->context->controller->getLanguages(),
487 'id_language' => $this->context->language->id
488 );
489
490 return $helper->generateForm(array($fields_form));
491 }
492
493 protected function renderAtchConfiguratorForm()
494 {
495 $id_shop = (int)$this->context->shop->id;
496 $items = array();
497 $hooks = array();
498
499 $this->context->smarty->assign('htmlcontent', array(
500 'admin_tpl_path' => $this->admin_tpl_path,
501 'hooks_tpl_path' => $this->hooks_tpl_path,
502
503 'info' => array(
504 'module' => $this->name,
505 'name' => $this->displayName,
506 'version' => $this->version,
507 'psVersion' => _PS_VERSION_,
508 'context' => (Configuration::get('PS_MULTISHOP_FEATURE_ACTIVE') == 0) ? 1 : ($this->context->shop->getTotalShops() != 1) ? $this->context->shop->getContext() : 1
509 )
510 ));
511
512 foreach ($this->languages as $language)
513 {
514 $hooks[$language['id_lang']] = array(
515 'home',
516 'top',
517 'left',
518 'right',
519 'footer'
520 );
521
522 foreach ($hooks[$language['id_lang']] as $hook)
523 $items[$language['id_lang']][$hook] = Db::getInstance()->ExecuteS('
524 SELECT * FROM `'._DB_PREFIX_.'atchconfigurator`
525 WHERE id_shop = '.(int)$id_shop.'
526 AND id_lang = '.(int)$language['id_lang'].'
527 AND hook = \''.pSQL($hook).'\'
528 ORDER BY item_order ASC'
529 );
530 }
531
532 $this->context->smarty->assign('htmlitems', array(
533 'items' => $items,
534 'theme_url' => $this->context->link->getAdminLink('AdminAtchConfigurator'),
535 'lang' => array(
536 'default' => $this->default_language,
537 'all' => $this->languages,
538 'lang_dir' => _THEME_LANG_DIR_,
539 'user' => $this->context->language->id
540 ),
541 'postAction' => 'index.php?tab=AdminModules&configure='.$this->name.'&token='.Tools::getAdminTokenLite('AdminModules').'&tab_module=other&module_name='.$this->name.'',
542 'id_shop' => $id_shop
543 ));
544
545 $this->context->controller->addJqueryUI('ui.sortable');
546 return $this->display(__FILE__, 'views/templates/admin/admin.tpl');
547 }
548
549 public function getConfigFieldsValues()
550 {
551 return array(
552 'atch_variables' => Tools::unserialize(Configuration::get('ATCH_VARIABLES'))
553 );
554 }
555
556
557 protected function filterVar($value)
558 {
559
560 return Tools::purifyHTML($value);
561 }
562}