* @copyright 2007-2013 PrestaShop SA * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) * International Registered Trademark & Property of PrestaShop SA */ /** * @since 1.5.0 * @version 1.2 (2012-03-14) */ if (!defined('_PS_VERSION_')) exit; include_once(_PS_MODULE_DIR_.'homeslider/HomeSlide.php'); class HomeSlider extends Module { private $_html = ''; public function __construct() { $this->name = 'homeslider'; $this->tab = 'front_office_features'; $this->version = '1.2.1'; $this->author = 'PrestaShop'; $this->need_instance = 0; $this->secure_key = Tools::encrypt($this->name); parent::__construct(); $this->displayName = $this->l('Image slider for your homepage.'); $this->description = $this->l('Adds an image slider to your homepage.'); } /** * @see Module::install() */ public function install() { /* Adds Module */ if (parent::install() && $this->registerHook('displayHome') && $this->registerHook('actionShopDataDuplication')) { /* Sets up configuration */ $res = Configuration::updateValue('HOMESLIDER_WIDTH', '535'); $res &= Configuration::updateValue('HOMESLIDER_HEIGHT', '300'); $res &= Configuration::updateValue('HOMESLIDER_SPEED', '500'); $res &= Configuration::updateValue('HOMESLIDER_PAUSE', '3000'); $res &= Configuration::updateValue('HOMESLIDER_LOOP', '1'); /* Creates tables */ $res &= $this->createTables(); /* Adds samples */ if ($res) $this->installSamples(); return $res; } return false; } /** * Adds samples */ private function installSamples() { $languages = Language::getLanguages(false); for ($i = 1; $i <= 5; ++$i) { $slide = new HomeSlide(); $slide->position = $i; $slide->active = 1; foreach ($languages as $language) { $slide->title[$language['id_lang']] = 'Sample '.$i; $slide->description[$language['id_lang']] = 'This is a sample picture'; $slide->legend[$language['id_lang']] = 'sample-'.$i; $slide->url[$language['id_lang']] = 'http://www.prestashop.com'; $slide->image[$language['id_lang']] = 'sample-'.$i.'.jpg'; } $slide->add(); } } /** * @see Module::uninstall() */ public function uninstall() { /* Deletes Module */ if (parent::uninstall()) { /* Deletes tables */ $res = $this->deleteTables(); /* Unsets configuration */ $res &= Configuration::deleteByName('HOMESLIDER_WIDTH'); $res &= Configuration::deleteByName('HOMESLIDER_HEIGHT'); $res &= Configuration::deleteByName('HOMESLIDER_SPEED'); $res &= Configuration::deleteByName('HOMESLIDER_PAUSE'); $res &= Configuration::deleteByName('HOMESLIDER_LOOP'); return $res; } return false; } /** * Creates tables */ protected function createTables() { /* Slides */ $res = (bool)Db::getInstance()->execute(' CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'homeslider` ( `id_homeslider_slides` int(10) unsigned NOT NULL AUTO_INCREMENT, `id_shop` int(10) unsigned NOT NULL, PRIMARY KEY (`id_homeslider_slides`, `id_shop`) ) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=UTF8; '); /* Slides configuration */ $res &= Db::getInstance()->execute(' CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'homeslider_slides` ( `id_homeslider_slides` int(10) unsigned NOT NULL AUTO_INCREMENT, `position` int(10) unsigned NOT NULL DEFAULT \'0\', `active` tinyint(1) unsigned NOT NULL DEFAULT \'0\', PRIMARY KEY (`id_homeslider_slides`) ) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=UTF8; '); /* Slides lang configuration */ $res &= Db::getInstance()->execute(' CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'homeslider_slides_lang` ( `id_homeslider_slides` int(10) unsigned NOT NULL, `id_lang` int(10) unsigned NOT NULL, `title` varchar(255) NOT NULL, `description` text NOT NULL, `legend` varchar(255) NOT NULL, `url` varchar(255) NOT NULL, `image` varchar(255) NOT NULL, PRIMARY KEY (`id_homeslider_slides`,`id_lang`) ) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=UTF8; '); return $res; } /** * deletes tables */ protected function deleteTables() { $slides = $this->getSlides(); foreach ($slides as $slide) { $to_del = new HomeSlide($slide['id_slide']); $to_del->delete(); } return Db::getInstance()->execute(' DROP TABLE IF EXISTS `'._DB_PREFIX_.'homeslider`, `'._DB_PREFIX_.'homeslider_slides`, `'._DB_PREFIX_.'homeslider_slides_lang`; '); } public function getContent() { $this->_html .= $this->headerHTML(); $this->_html .= '

'.$this->displayName.'.

'; /* Validate & process */ if (Tools::isSubmit('submitSlide') || Tools::isSubmit('delete_id_slide') || Tools::isSubmit('submitSlider') || Tools::isSubmit('changeStatus')) { if ($this->_postValidation()) $this->_postProcess(); $this->_displayForm(); } elseif (Tools::isSubmit('addSlide') || (Tools::isSubmit('id_slide') && $this->slideExists((int)Tools::getValue('id_slide')))) $this->_displayAddForm(); else $this->_displayForm(); return $this->_html; } private function _displayForm() { /* Gets Slides */ $slides = $this->getSlides(); /* Begin fieldset slider */ $this->_html .= '
'.$this->l('Slider configuration').''; /* Begin form */ $this->_html .= '
'; /* Height field */ $this->_html .= '
px
'; /* Width field */ $this->_html .= '
px
'; /* Speed field */ $this->_html .= '
ms
'; /* Pause field */ $this->_html .= '
ms
'; /* Loop field */ $this->_html .= '
Yes No
'; /* Save */ $this->_html .= '
'; /* End form */ $this->_html .= '
'; /* End fieldset slider */ $this->_html .= '
'; $this->_html .= '

'; /* Begin fieldset slides */ $this->_html .= '
'.$this->l('Slides configuration').' '.$this->l('Add Slide').' '; /* Display notice if there are no slides yet */ if (!$slides) $this->_html .= '

'.$this->l('You have not yet added any slides.').'

'; else /* Display slides */ { $this->_html .= '
'; } // End fieldset $this->_html .= '
'; } private function _displayAddForm() { /* Sets Slide : depends if edited or added */ $slide = null; if (Tools::isSubmit('id_slide') && $this->slideExists((int)Tools::getValue('id_slide'))) $slide = new HomeSlide((int)Tools::getValue('id_slide')); /* Checks if directory is writable */ if (!is_writable('.')) $this->adminDisplayWarning(sprintf($this->l('Modules %s must be writable (CHMOD 755 / 777)'), $this->name)); /* Gets languages and sets which div requires translations */ $id_lang_default = (int)Configuration::get('PS_LANG_DEFAULT'); $languages = Language::getLanguages(false); $divLangName = 'image¤title¤url¤legend¤description'; $this->_html .= ''; /* Form */ $this->_html .= '
'; /* Fieldset Upload */ $this->_html .= '

1 - '.$this->l('Upload your slide').''; /* Image */ $this->_html .= '
'; foreach ($languages as $language) { $this->_html .= '
'; $this->_html .= ''; /* Sets image as hidden in case it does not change */ if ($slide && $slide->image[$language['id_lang']]) $this->_html .= ''; /* Display image */ if ($slide && $slide->image[$language['id_lang']]) $this->_html .= ''; $this->_html .= '
'; } $this->_html .= $this->displayFlags($languages, $id_lang_default, $divLangName, 'image', true); /* End Fieldset Upload */ $this->_html .= '


'; /* Fieldset edit/add */ $this->_html .= '
'; if (Tools::isSubmit('addSlide')) /* Configure legend */ $this->_html .= ' 2 - '.$this->l('Configure your slide').''; elseif (Tools::isSubmit('id_slide')) /* Edit legend */ $this->_html .= ' 2 - '.$this->l('Edit your slide').''; /* Sets id slide as hidden */ if ($slide && Tools::getValue('id_slide')) $this->_html .= ''; /* Sets position as hidden */ $this->_html .= ''; /* Form content */ /* Title */ $this->_html .= '
'; foreach ($languages as $language) { $this->_html .= '
'; } $this->_html .= $this->displayFlags($languages, $id_lang_default, $divLangName, 'title', true); $this->_html .= '


'; /* URL */ $this->_html .= '
'; foreach ($languages as $language) { $this->_html .= '
'; } $this->_html .= $this->displayFlags($languages, $id_lang_default, $divLangName, 'url', true); $this->_html .= '


'; /* Legend */ $this->_html .= '
'; foreach ($languages as $language) { $this->_html .= '
'; } $this->_html .= $this->displayFlags($languages, $id_lang_default, $divLangName, 'legend', true); $this->_html .= '


'; /* Description */ $this->_html .= '
'; foreach ($languages as $language) { $this->_html .= '
'; } $this->_html .= $this->displayFlags($languages, $id_lang_default, $divLangName, 'description', true); $this->_html .= '

'; /* Active */ $this->_html .= '
Yes active) && (int)$slide->active == 0)) ? '' : 'checked="checked" ').' value="1" /> No active) && (int)$slide->active == 0)) ? 'checked="checked" ' : '').' value="0" />
'; /* Save */ $this->_html .= '

'.$this->l('Cancel').'

'; /* End of fieldset & form */ $this->_html .= '

*'.$this->l('Required fields').'

'; } private function _postValidation() { $errors = array(); /* Validation for Slider configuration */ if (Tools::isSubmit('submitSlider')) { if (!Validate::isInt(Tools::getValue('HOMESLIDER_SPEED')) || !Validate::isInt(Tools::getValue('HOMESLIDER_PAUSE')) || !Validate::isInt(Tools::getValue('HOMESLIDER_WIDTH')) || !Validate::isInt(Tools::getValue('HOMESLIDER_HEIGHT'))) $errors[] = $this->l('Invalid values'); } /* Validation for status */ elseif (Tools::isSubmit('changeStatus')) { if (!Validate::isInt(Tools::getValue('id_slide'))) $errors[] = $this->l('Invalid slide'); } /* Validation for Slide */ elseif (Tools::isSubmit('submitSlide')) { /* Checks state (active) */ if (!Validate::isInt(Tools::getValue('active_slide')) || (Tools::getValue('active_slide') != 0 && Tools::getValue('active_slide') != 1)) $errors[] = $this->l('Invalid slide state'); /* Checks position */ if (!Validate::isInt(Tools::getValue('position')) || (Tools::getValue('position') < 0)) $errors[] = $this->l('Invalid slide position'); /* If edit : checks id_slide */ if (Tools::isSubmit('id_slide')) { if (!Validate::isInt(Tools::getValue('id_slide')) && !$this->slideExists(Tools::getValue('id_slide'))) $errors[] = $this->l('Invalid id_slide'); } /* Checks title/url/legend/description/image */ $languages = Language::getLanguages(false); foreach ($languages as $language) { if (Tools::strlen(Tools::getValue('title_'.$language['id_lang'])) > 255) $errors[] = $this->l('The title is too long.'); if (Tools::strlen(Tools::getValue('legend_'.$language['id_lang'])) > 255) $errors[] = $this->l('The legend is too long.'); if (Tools::strlen(Tools::getValue('url_'.$language['id_lang'])) > 255) $errors[] = $this->l('The URL is too long.'); if (Tools::strlen(Tools::getValue('description_'.$language['id_lang'])) > 4000) $errors[] = $this->l('The description is too long.'); if (Tools::strlen(Tools::getValue('url_'.$language['id_lang'])) > 0 && !Validate::isUrl(Tools::getValue('url_'.$language['id_lang']))) $errors[] = $this->l('The URL format is not correct.'); if (Tools::getValue('image_'.$language['id_lang']) != null && !Validate::isFileName(Tools::getValue('image_'.$language['id_lang']))) $errors[] = $this->l('Invalid filename'); if (Tools::getValue('image_old_'.$language['id_lang']) != null && !Validate::isFileName(Tools::getValue('image_old_'.$language['id_lang']))) $errors[] = $this->l('Invalid filename'); } /* Checks title/url/legend/description for default lang */ $id_lang_default = (int)Configuration::get('PS_LANG_DEFAULT'); if (Tools::strlen(Tools::getValue('title_'.$id_lang_default)) == 0) $errors[] = $this->l('The title is not set.'); if (Tools::strlen(Tools::getValue('legend_'.$id_lang_default)) == 0) $errors[] = $this->l('The legend is not set.'); if (Tools::strlen(Tools::getValue('url_'.$id_lang_default)) == 0) $errors[] = $this->l('The URL is not set.'); if (!Tools::isSubmit('has_picture') && (!isset($_FILES['image_'.$id_lang_default]) || empty($_FILES['image_'.$id_lang_default]['tmp_name']))) $errors[] = $this->l('The image is not set.'); if (Tools::getValue('image_old_'.$id_lang_default) && !Validate::isFileName(Tools::getValue('image_old_'.$id_lang_default))) $errors[] = $this->l('The image is not set.'); } /* Validation for deletion */ elseif (Tools::isSubmit('delete_id_slide') && (!Validate::isInt(Tools::getValue('delete_id_slide')) || !$this->slideExists((int)Tools::getValue('delete_id_slide')))) $errors[] = $this->l('Invalid id_slide'); /* Display errors if needed */ if (count($errors)) { $this->_html .= $this->displayError(implode('
', $errors)); return false; } /* Returns if validation is ok */ return true; } private function _postProcess() { $errors = array(); /* Processes Slider */ if (Tools::isSubmit('submitSlider')) { $res = Configuration::updateValue('HOMESLIDER_WIDTH', (int)Tools::getValue('HOMESLIDER_WIDTH')); $res &= Configuration::updateValue('HOMESLIDER_HEIGHT', (int)Tools::getValue('HOMESLIDER_HEIGHT')); $res &= Configuration::updateValue('HOMESLIDER_SPEED', (int)Tools::getValue('HOMESLIDER_SPEED')); $res &= Configuration::updateValue('HOMESLIDER_PAUSE', (int)Tools::getValue('HOMESLIDER_PAUSE')); $res &= Configuration::updateValue('HOMESLIDER_LOOP', (int)Tools::getValue('HOMESLIDER_LOOP')); $this->clearCache(); if (!$res) $errors[] = $this->displayError($this->l('The configuration could not be updated.')); $this->_html .= $this->displayConfirmation($this->l('Configuration updated')); } /* Process Slide status */ elseif (Tools::isSubmit('changeStatus') && Tools::isSubmit('id_slide')) { $slide = new HomeSlide((int)Tools::getValue('id_slide')); if ($slide->active == 0) $slide->active = 1; else $slide->active = 0; $res = $slide->update(); $this->clearCache(); $this->_html .= ($res ? $this->displayConfirmation($this->l('Configuration updated')) : $this->displayError($this->l('The configuration could not be updated.'))); } /* Processes Slide */ elseif (Tools::isSubmit('submitSlide')) { /* Sets ID if needed */ if (Tools::getValue('id_slide')) { $slide = new HomeSlide((int)Tools::getValue('id_slide')); if (!Validate::isLoadedObject($slide)) { $this->_html .= $this->displayError($this->l('Invalid id_slide')); return; } } else $slide = new HomeSlide(); /* Sets position */ $slide->position = (int)Tools::getValue('position'); /* Sets active */ $slide->active = (int)Tools::getValue('active_slide'); /* Sets each langue fields */ $languages = Language::getLanguages(false); foreach ($languages as $language) { $slide->title[$language['id_lang']] = Tools::getValue('title_'.$language['id_lang']); $slide->url[$language['id_lang']] = Tools::getValue('url_'.$language['id_lang']); $slide->legend[$language['id_lang']] = Tools::getValue('legend_'.$language['id_lang']); $slide->description[$language['id_lang']] = Tools::getValue('description_'.$language['id_lang']); /* Uploads image and sets slide */ $type = strtolower(substr(strrchr($_FILES['image_'.$language['id_lang']]['name'], '.'), 1)); $imagesize = array(); $imagesize = @getimagesize($_FILES['image_'.$language['id_lang']]['tmp_name']); if (isset($_FILES['image_'.$language['id_lang']]) && isset($_FILES['image_'.$language['id_lang']]['tmp_name']) && !empty($_FILES['image_'.$language['id_lang']]['tmp_name']) && !empty($imagesize) && in_array(strtolower(substr(strrchr($imagesize['mime'], '/'), 1)), array('jpg', 'gif', 'jpeg', 'png')) && in_array($type, array('jpg', 'gif', 'jpeg', 'png'))) { $temp_name = tempnam(_PS_TMP_IMG_DIR_, 'PS'); $salt = sha1(microtime()); if ($error = ImageManager::validateUpload($_FILES['image_'.$language['id_lang']])) $errors[] = $error; elseif (!$temp_name || !move_uploaded_file($_FILES['image_'.$language['id_lang']]['tmp_name'], $temp_name)) return false; elseif (!ImageManager::resize($temp_name, dirname(__FILE__).'/images/'.Tools::encrypt($_FILES['image_'.$language['id_lang']]['name'].$salt).'.'.$type, null, null, $type)) $errors[] = $this->displayError($this->l('An error occurred during the image upload process.')); if (isset($temp_name)) @unlink($temp_name); $slide->image[$language['id_lang']] = Tools::encrypt($_FILES['image_'.($language['id_lang'])]['name'].$salt).'.'.$type; } elseif (Tools::getValue('image_old_'.$language['id_lang']) != '') $slide->image[$language['id_lang']] = Tools::getValue('image_old_'.$language['id_lang']); } /* Processes if no errors */ if (!$errors) { /* Adds */ if (!Tools::getValue('id_slide')) { if (!$slide->add()) $errors[] = $this->displayError($this->l('The slide could not be added.')); } /* Update */ elseif (!$slide->update()) $errors[] = $this->displayError($this->l('The slide could not be updated.')); $this->clearCache(); } } /* Deletes */ elseif (Tools::isSubmit('delete_id_slide')) { $slide = new HomeSlide((int)Tools::getValue('delete_id_slide')); $res = $slide->delete(); $this->clearCache(); if (!$res) $this->_html .= $this->displayError('Could not delete'); else $this->_html .= $this->displayConfirmation($this->l('Slide deleted')); } /* Display errors if needed */ if (count($errors)) $this->_html .= $this->displayError(implode('
', $errors)); elseif (Tools::isSubmit('submitSlide') && Tools::getValue('id_slide')) $this->_html .= $this->displayConfirmation($this->l('Slide updated')); elseif (Tools::isSubmit('submitSlide')) $this->_html .= $this->displayConfirmation($this->l('Slide added')); } private function _prepareHook() { if (!$this->isCached('homeslider.tpl', $this->getCacheId())) { $slider = array( 'width' => Configuration::get('HOMESLIDER_WIDTH'), 'height' => Configuration::get('HOMESLIDER_HEIGHT'), 'speed' => Configuration::get('HOMESLIDER_SPEED'), 'pause' => Configuration::get('HOMESLIDER_PAUSE'), 'loop' => Configuration::get('HOMESLIDER_LOOP'), ); $slides = $this->getSlides(true); if (!$slides) return false; $this->smarty->assign('homeslider_slides', $slides); $this->smarty->assign('homeslider', $slider); } return true; } public function hookDisplayHome() { if(!$this->_prepareHook()) return; // Check if not a mobile theme if ($this->context->getMobileDevice() != false) return false; $this->context->controller->addJS($this->_path.'js/jquery.bxSlider.min.js'); $this->context->controller->addCSS($this->_path.'bx_styles.css'); $this->context->controller->addJS($this->_path.'js/homeslider.js'); return $this->display(__FILE__, 'homeslider.tpl', $this->getCacheId()); } public function clearCache() { $this->_clearCache('homeslider.tpl'); } public function hookActionShopDataDuplication($params) { Db::getInstance()->execute(' INSERT IGNORE INTO '._DB_PREFIX_.'homeslider (id_homeslider_slides, id_shop) SELECT id_homeslider_slides, '.(int)$params['new_id_shop'].' FROM '._DB_PREFIX_.'homeslider WHERE id_shop = '.(int)$params['old_id_shop']); $this->clearCache(); } public function headerHTML() { if (Tools::getValue('controller') != 'AdminModules' && Tools::getValue('configure') != $this->name) return; $this->context->controller->addJqueryUI('ui.sortable'); /* Style & js for fieldset 'slides configuration' */ $html = ' '; return $html; } public function getNextPosition() { $row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow(' SELECT MAX(hss.`position`) AS `next_position` FROM `'._DB_PREFIX_.'homeslider_slides` hss, `'._DB_PREFIX_.'homeslider` hs WHERE hss.`id_homeslider_slides` = hs.`id_homeslider_slides` AND hs.`id_shop` = '.(int)$this->context->shop->id ); return (++$row['next_position']); } public function getSlides($active = null) { $this->context = Context::getContext(); $id_shop = $this->context->shop->id; $id_lang = $this->context->language->id; return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT hs.`id_homeslider_slides` as id_slide, hssl.`image`, hss.`position`, hss.`active`, hssl.`title`, hssl.`url`, hssl.`legend`, hssl.`description` FROM '._DB_PREFIX_.'homeslider hs LEFT JOIN '._DB_PREFIX_.'homeslider_slides hss ON (hs.id_homeslider_slides = hss.id_homeslider_slides) LEFT JOIN '._DB_PREFIX_.'homeslider_slides_lang hssl ON (hss.id_homeslider_slides = hssl.id_homeslider_slides) WHERE (id_shop = '.(int)$id_shop.') AND hssl.id_lang = '.(int)$id_lang. ($active ? ' AND hss.`active` = 1' : ' ').' ORDER BY hss.position'); } public function displayStatus($id_slide, $active) { $title = ((int)$active == 0 ? $this->l('Disabled') : $this->l('Enabled')); $img = ((int)$active == 0 ? 'disabled.gif' : 'enabled.gif'); $html = ''; return $html; } public function slideExists($id_slide) { $req = 'SELECT hs.`id_homeslider_slides` as id_slide FROM `'._DB_PREFIX_.'homeslider` hs WHERE hs.`id_homeslider_slides` = '.(int)$id_slide; $row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($req); return ($row); } }