diff --git a/.vscode/ftp-kr.sync.cache.json b/.vscode/ftp-kr.sync.cache.json index d00fed2a..e270f3da 100644 --- a/.vscode/ftp-kr.sync.cache.json +++ b/.vscode/ftp-kr.sync.cache.json @@ -4036,13 +4036,13 @@ }, "google-merchant_id-1.xml": { "type": "-", - "size": 73985727, + "size": 72910906, "lmtime": 0, "modified": true }, "google-merchant_id-2.xml": { "type": "-", - "size": 2954405, + "size": 2932584, "lmtime": 0, "modified": true }, @@ -4074,8 +4074,8 @@ }, "import-product.php": { "type": "-", - "size": 23703, - "lmtime": 1742503757666, + "size": 23054, + "lmtime": 1742810375717, "modified": false }, "index.php": { diff --git a/classes/Dispatcher.php b/classes/Dispatcher.php new file mode 100644 index 00000000..6cbb3de0 --- /dev/null +++ b/classes/Dispatcher.php @@ -0,0 +1,1173 @@ + + * @copyright 2007-2018 PrestaShop SA + * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) + * International Registered Trademark & Property of PrestaShop SA + */ +use Symfony\Component\HttpFoundation\Request as SymfonyRequest; + +/** + * @since 1.5.0 + */ +class DispatcherCore +{ + /** + * List of available front controllers types. + */ + const FC_FRONT = 1; + const FC_ADMIN = 2; + const FC_MODULE = 3; + + /** + * @var Dispatcher + */ + public static $instance = null; + + /** + * @var SymfonyRequest + */ + private $request; + + /** + * @var array List of default routes + */ + public $default_routes = array( + 'category_rule' => array( + 'controller' => 'category', + 'rule' => '{id}-{rewrite}', + 'keywords' => array( + 'id' => array('regexp' => '[0-9]+', 'param' => 'id_category'), + 'rewrite' => array('regexp' => '[_a-zA-Z0-9\pL\pS-]*'), + 'meta_keywords' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + 'meta_title' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + ), + ), + 'supplier_rule' => array( + 'controller' => 'supplier', + 'rule' => 'supplier/{id}-{rewrite}', + 'keywords' => array( + 'id' => array('regexp' => '[0-9]+', 'param' => 'id_supplier'), + 'rewrite' => array('regexp' => '[_a-zA-Z0-9\pL\pS-]*'), + 'meta_keywords' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + 'meta_title' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + ), + ), + 'manufacturer_rule' => array( + 'controller' => 'manufacturer', + 'rule' => 'brand/{id}-{rewrite}', + 'keywords' => array( + 'id' => array('regexp' => '[0-9]+', 'param' => 'id_manufacturer'), + 'rewrite' => array('regexp' => '[_a-zA-Z0-9\pL\pS-]*'), + 'meta_keywords' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + 'meta_title' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + ), + ), + 'cms_rule' => array( + 'controller' => 'cms', + 'rule' => 'content/{id}-{rewrite}', + 'keywords' => array( + 'id' => array('regexp' => '[0-9]+', 'param' => 'id_cms'), + 'rewrite' => array('regexp' => '[_a-zA-Z0-9\pL\pS-]*'), + 'meta_keywords' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + 'meta_title' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + ), + ), + 'cms_category_rule' => array( + 'controller' => 'cms', + 'rule' => 'content/category/{id}-{rewrite}', + 'keywords' => array( + 'id' => array('regexp' => '[0-9]+', 'param' => 'id_cms_category'), + 'rewrite' => array('regexp' => '[_a-zA-Z0-9\pL\pS-]*'), + 'meta_keywords' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + 'meta_title' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + ), + ), + 'module' => array( + 'controller' => null, + 'rule' => 'module/{module}{/:controller}', + 'keywords' => array( + 'module' => array('regexp' => '[_a-zA-Z0-9_-]+', 'param' => 'module'), + 'controller' => array('regexp' => '[_a-zA-Z0-9_-]+', 'param' => 'controller'), + ), + 'params' => array( + 'fc' => 'module', + ), + ), + 'product_rule' => array( + 'controller' => 'product', + 'rule' => '{category:/}{id}{-:id_product_attribute}-{rewrite}{-:ean13}.html', + 'keywords' => array( + 'id' => array('regexp' => '[0-9]+', 'param' => 'id_product'), + 'id_product_attribute' => array('regexp' => '[0-9]+', 'param' => 'id_product_attribute'), + 'rewrite' => array('regexp' => '[_a-zA-Z0-9\pL\pS-]*', 'param' => 'rewrite'), + 'ean13' => array('regexp' => '[0-9\pL]*'), + 'category' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + 'categories' => array('regexp' => '[/_a-zA-Z0-9-\pL]*'), + 'reference' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + 'meta_keywords' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + 'meta_title' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + 'manufacturer' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + 'supplier' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + 'price' => array('regexp' => '[0-9\.,]*'), + 'tags' => array('regexp' => '[a-zA-Z0-9-\pL]*'), + ), + ), + /* Must be after the product and category rules in order to avoid conflict */ + 'layered_rule' => array( + 'controller' => 'category', + 'rule' => '{id}-{rewrite}{/:selected_filters}', + 'keywords' => array( + 'id' => array('regexp' => '[0-9]+', 'param' => 'id_category'), + /* Selected filters is used by the module blocklayered */ + 'selected_filters' => array('regexp' => '.*', 'param' => 'selected_filters'), + 'rewrite' => array('regexp' => '[_a-zA-Z0-9\pL\pS-]*'), + 'meta_keywords' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + 'meta_title' => array('regexp' => '[_a-zA-Z0-9-\pL]*'), + ), + ), + ); + + /** + * @var bool If true, use routes to build URL (mod rewrite must be activated) + */ + protected $use_routes = false; + + protected $multilang_activated = false; + + /** + * @var array List of loaded routes + */ + protected $routes = array(); + + /** + * @var string Current controller name + */ + protected $controller; + + /** + * @var string Current request uri + */ + protected $request_uri; + + /** + * @var array Store empty route (a route with an empty rule) + */ + protected $empty_route; + + /** + * @var string Set default controller, which will be used if http parameter 'controller' is empty + */ + protected $default_controller; + protected $use_default_controller = false; + + /** + * @var string Controller to use if found controller doesn't exist + */ + protected $controller_not_found = 'pagenotfound'; + + /** + * @var string Front controller to use + */ + protected $front_controller = self::FC_FRONT; + + /** + * Get current instance of dispatcher (singleton). + * + * @return Dispatcher + * + * @throws PrestaShopException + */ + public static function getInstance(SymfonyRequest $request = null) + { + if (!self::$instance) { + if (null === $request) { + $request = SymfonyRequest::createFromGlobals(); + } + self::$instance = new Dispatcher($request); + } + + return self::$instance; + } + + /** + * Needs to be instantiated from getInstance() method. + * + * @param SymfonyRequest|null $request + * + * @throws PrestaShopException + */ + protected function __construct(SymfonyRequest $request = null) + { + $this->setRequest($request); + + $this->use_routes = (bool) Configuration::get('PS_REWRITING_SETTINGS'); + + // Select right front controller + if (defined('_PS_ADMIN_DIR_')) { + $this->front_controller = self::FC_ADMIN; + $this->controller_not_found = 'adminnotfound'; + } elseif (Tools::getValue('fc') == 'module') { + $this->front_controller = self::FC_MODULE; + $this->controller_not_found = 'pagenotfound'; + } else { + $this->front_controller = self::FC_FRONT; + $this->controller_not_found = 'pagenotfound'; + } + + $this->setRequestUri(); + + // Switch language if needed (only on front) + if (in_array($this->front_controller, array(self::FC_FRONT, self::FC_MODULE))) { + Tools::switchLanguage(); + } + + if (Language::isMultiLanguageActivated()) { + $this->multilang_activated = true; + } + + $this->loadRoutes(); + } + + /** + * Either sets a given request or a new one. + * + * @param SymfonyRequest|null $request + */ + private function setRequest(SymfonyRequest $request = null) + { + if (null === $request) { + $request = SymfonyRequest::createFromGlobals(); + } + + $this->request = $request; + } + + /** + * Returns the request property. + * + * @return SymfonyRequest + */ + private function getRequest() + { + return $this->request; + } + + /** + * Sets and returns the default controller. + * + * @param int $frontControllerType The front controller type + * @param Employee|null $employee The current employee + * + * @return string + */ + private function getDefaultController($frontControllerType, Employee $employee = null) + { + switch ($frontControllerType) { + case self::FC_ADMIN: + // Default + $defaultController = 'AdminDashboard'; + // If there is an employee with a default tab set + if (null !== $employee) { + $tabClassName = $employee->getDefaultTabClassName(); + if (null !== $tabClassName) { + $defaultController = $tabClassName; + } + } + break; + case self::FC_MODULE: + $defaultController = 'default'; + break; + default: + $defaultController = 'index'; + } + + $this->setDefaultController($defaultController); + + return $defaultController; + } + + /** + * Sets the default controller. + * + * @param string $defaultController + */ + private function setDefaultController($defaultController) + { + $this->default_controller = $defaultController; + } + + /** + * Sets use_default_controller to true, sets and returns the default controller. + * + * @return string + */ + public function useDefaultController() + { + $this->use_default_controller = true; + + // If it was already set just return it + if (null !== $this->default_controller) { + return $this->default_controller; + } + + $employee = Context::getContext()->employee; + + return $this->getDefaultController($this->front_controller, $employee); + } + + /** + * Find the controller and instantiate it. + */ + public function dispatch() + { + $controller_class = ''; + + // Get current controller + $this->getController(); + if (!$this->controller) { + $this->controller = $this->useDefaultController(); + } + // Execute hook dispatcher before + Hook::exec('actionDispatcherBefore', array('controller_type' => $this->front_controller)); + + // Dispatch with right front controller + switch ($this->front_controller) { + // Dispatch front office controller + case self::FC_FRONT: + $controllers = Dispatcher::getControllers(array( + _PS_FRONT_CONTROLLER_DIR_, + _PS_OVERRIDE_DIR_ . 'controllers/front/', + )); + $controllers['index'] = 'IndexController'; + if (isset($controllers['auth'])) { + $controllers['authentication'] = $controllers['auth']; + } + if (isset($controllers['contact'])) { + $controllers['contactform'] = $controllers['contact']; + } + + if (!isset($controllers[strtolower($this->controller)])) { + $this->controller = $this->controller_not_found; + } + $controller_class = $controllers[strtolower($this->controller)]; + $params_hook_action_dispatcher = array( + 'controller_type' => self::FC_FRONT, + 'controller_class' => $controller_class, + 'is_module' => 0, + ); + break; + + // Dispatch module controller for front office + case self::FC_MODULE: + $module_name = Validate::isModuleName(Tools::getValue('module')) ? Tools::getValue('module') : ''; + $module = Module::getInstanceByName($module_name); + $controller_class = 'PageNotFoundController'; + if (Validate::isLoadedObject($module) && $module->active) { + $controllers = Dispatcher::getControllers(_PS_MODULE_DIR_ . "$module_name/controllers/front/"); + if (isset($controllers[strtolower($this->controller)])) { + include_once _PS_MODULE_DIR_ . "$module_name/controllers/front/{$this->controller}.php"; + if (file_exists( + _PS_OVERRIDE_DIR_ . "modules/$module_name/controllers/front/{$this->controller}.php" + )) { + include_once _PS_OVERRIDE_DIR_ . "modules/$module_name/controllers/front/{$this->controller}.php"; + $controller_class = $module_name . $this->controller . 'ModuleFrontControllerOverride'; + } else { + $controller_class = $module_name . $this->controller . 'ModuleFrontController'; + } + } + } + $params_hook_action_dispatcher = array( + 'controller_type' => self::FC_FRONT, + 'controller_class' => $controller_class, + 'is_module' => 1, + ); + break; + + // Dispatch back office controller + module back office controller + case self::FC_ADMIN: + if ($this->use_default_controller + && !Tools::getValue('token') + && Validate::isLoadedObject(Context::getContext()->employee) + && Context::getContext()->employee->isLoggedBack() + ) { + Tools::redirectAdmin( + "index.php?controller={$this->controller}&token=" . Tools::getAdminTokenLite($this->controller) + ); + } + + $tab = Tab::getInstanceFromClassName($this->controller, Configuration::get('PS_LANG_DEFAULT')); + $retrocompatibility_admin_tab = null; + + if ($tab->module) { + if (file_exists(_PS_MODULE_DIR_ . "{$tab->module}/{$tab->class_name}.php")) { + $retrocompatibility_admin_tab = _PS_MODULE_DIR_ . "{$tab->module}/{$tab->class_name}.php"; + } else { + $controllers = Dispatcher::getControllers(_PS_MODULE_DIR_ . $tab->module . '/controllers/admin/'); + if (!isset($controllers[strtolower($this->controller)])) { + $this->controller = $this->controller_not_found; + $controller_class = 'AdminNotFoundController'; + } else { + $controller_name = $controllers[strtolower($this->controller)]; + // Controllers in modules can be named AdminXXX.php or AdminXXXController.php + include_once _PS_MODULE_DIR_ . "{$tab->module}/controllers/admin/$controller_name.php"; + if (file_exists( + _PS_OVERRIDE_DIR_ . "modules/{$tab->module}/controllers/admin/$controller_name.php" + )) { + include_once _PS_OVERRIDE_DIR_ . "modules/{$tab->module}/controllers/admin/$controller_name.php"; + $controller_class = $controller_name . ( + strpos($controller_name, 'Controller') ? 'Override' : 'ControllerOverride' + ); + } else { + $controller_class = $controller_name . ( + strpos($controller_name, 'Controller') ? '' : 'Controller' + ); + } + } + } + $params_hook_action_dispatcher = array( + 'controller_type' => self::FC_ADMIN, + 'controller_class' => $controller_class, + 'is_module' => 1, + ); + } else { + $controllers = Dispatcher::getControllers( + array( + _PS_ADMIN_DIR_ . '/tabs/', + _PS_ADMIN_CONTROLLER_DIR_, + _PS_OVERRIDE_DIR_ . 'controllers/admin/', + ) + ); + if (!isset($controllers[strtolower($this->controller)])) { + // If this is a parent tab, load the first child + if (Validate::isLoadedObject($tab) + && $tab->id_parent == 0 + && ($tabs = Tab::getTabs(Context::getContext()->language->id, $tab->id)) + && isset($tabs[0]) + ) { + Tools::redirectAdmin(Context::getContext()->link->getAdminLink($tabs[0]['class_name'])); + } + $this->controller = $this->controller_not_found; + } + + $controller_class = $controllers[strtolower($this->controller)]; + $params_hook_action_dispatcher = array( + 'controller_type' => self::FC_ADMIN, + 'controller_class' => $controller_class, + 'is_module' => 0, + ); + + if (file_exists(_PS_ADMIN_DIR_ . '/tabs/' . $controller_class . '.php')) { + $retrocompatibility_admin_tab = _PS_ADMIN_DIR_ . '/tabs/' . $controller_class . '.php'; + } + } + + // @retrocompatibility with admin/tabs/ old system + if ($retrocompatibility_admin_tab) { + include_once $retrocompatibility_admin_tab; + include_once _PS_ADMIN_DIR_ . '/functions.php'; + runAdminTab($this->controller, !empty($_REQUEST['ajaxMode'])); + + return; + } + + break; + + default: + throw new PrestaShopException('Bad front controller chosen'); + } + + // Instantiate controller + try { + // Loading controller + $controller = Controller::getController($controller_class); + + // Execute hook dispatcher + if (isset($params_hook_action_dispatcher)) { + Hook::exec('actionDispatcher', $params_hook_action_dispatcher); + } + + // Running controller + $controller->run(); + + // Execute hook dispatcher after + if (isset($params_hook_action_dispatcher)) { + Hook::exec('actionDispatcherAfter', $params_hook_action_dispatcher); + } + } catch (PrestaShopException $e) { + $e->displayMessage(); + } + } + + /** + * Sets request uri and if necessary $_GET['isolang']. + */ + protected function setRequestUri() + { + $shop = Context::getContext()->shop; + if (!Validate::isLoadedObject($shop)) { + $shop = null; + } + + $this->request_uri = $this->buildRequestUri( + $this->getRequest()->getRequestUri(), + Language::isMultiLanguageActivated(), + $shop + ); + } + + /** + * Builds request URI and if necessary sets $_GET['isolang']. + * + * @param string $requestUri To retrieve the request URI from it + * @param bool $isMultiLanguageActivated + * @param Shop $shop + * + * @return string + */ + private function buildRequestUri($requestUri, $isMultiLanguageActivated, Shop $shop = null) + { + // Decode raw request URI + $requestUri = rawurldecode($requestUri); + + // Remove the shop base URI part from the request URI + if (null !== $shop) { + $requestUri = preg_replace( + '#^' . preg_quote($shop->getBaseURI(), '#') . '#i', + '/', + $requestUri + ); + } + + // If there are several languages, set $_GET['isolang'] and remove the language part from the request URI + if ( + $this->use_routes && + $isMultiLanguageActivated && + preg_match('#^/([a-z]{2})(?:/.*)?$#', $requestUri, $matches) + ) { + $_GET['isolang'] = $matches[1]; + $requestUri = substr($requestUri, 3); + } + + return $requestUri; + } + + /** + * Load default routes group by languages. + * + * @param int $id_shop + */ + protected function loadRoutes($id_shop = null) + { + $context = Context::getContext(); + + if (isset($context->shop) && $id_shop === null) { + $id_shop = (int) $context->shop->id; + } + + // Load custom routes from modules + $modules_routes = Hook::exec('moduleRoutes', array('id_shop' => $id_shop), null, true, false); + if (is_array($modules_routes) && count($modules_routes)) { + foreach ($modules_routes as $module_route) { + if (is_array($module_route) && count($module_route)) { + foreach ($module_route as $route => $route_details) { + if (array_key_exists('controller', $route_details) + && array_key_exists('rule', $route_details) + && array_key_exists('keywords', $route_details) + && array_key_exists('params', $route_details) + ) { + if (!isset($this->default_routes[$route])) { + $this->default_routes[$route] = array(); + } + $this->default_routes[$route] = array_merge($this->default_routes[$route], $route_details); + } + } + } + } + } + + $language_ids = Language::getIDs(); + + if (isset($context->language) && !in_array($context->language->id, $language_ids)) { + $language_ids[] = (int) $context->language->id; + } + + // Set default routes + foreach ($this->default_routes as $id => $route) { + $route = $this->computeRoute( + $route['rule'], + $route['controller'], + $route['keywords'], + isset($route['params']) ? $route['params'] : array() + ); + foreach ($language_ids as $id_lang) { + // the default routes are the same, whatever the language + $this->routes[$id_shop][$id_lang][$id] = $route; + } + } + + // Load the custom routes prior the defaults to avoid infinite loops + if ($this->use_routes) { + // Load routes from meta table + $sql = 'SELECT m.page, ml.url_rewrite, ml.id_lang + FROM `' . _DB_PREFIX_ . 'meta` m + LEFT JOIN `' . _DB_PREFIX_ . 'meta_lang` ml ON (m.id_meta = ml.id_meta' . Shop::addSqlRestrictionOnLang('ml', (int) $id_shop) . ') + ORDER BY LENGTH(ml.url_rewrite) DESC'; + if ($results = Db::getInstance()->executeS($sql)) { + foreach ($results as $row) { + if ($row['url_rewrite']) { + $this->addRoute( + $row['page'], + $row['url_rewrite'], + $row['page'], + $row['id_lang'], + array(), + array(), + $id_shop + ); + } + } + } + + // Set default empty route if no empty route (that's weird I know) + if (!$this->empty_route) { + $this->empty_route = array( + 'routeID' => 'index', + 'rule' => '', + 'controller' => 'index', + ); + } + + // Load custom routes + foreach ($this->default_routes as $route_id => $route_data) { + if ($custom_route = Configuration::get('PS_ROUTE_' . $route_id, null, null, $id_shop)) { + if (isset($context->language) && !in_array($context->language->id, $language_ids)) { + $language_ids[] = (int) $context->language->id; + } + + $route = $this->computeRoute( + $custom_route, + $route_data['controller'], + $route_data['keywords'], + isset($route_data['params']) ? $route_data['params'] : array() + ); + foreach ($language_ids as $id_lang) { + // those routes are the same, whatever the language + $this->routes[$id_shop][$id_lang][$route_id] = $route; + } + } + } + } + } + + /** + * Create the route array, by computing the final regex & keywords. + * + * @param string $rule Url rule + * @param string $controller Controller to call if request uri match the rule + * @param array $keywords keywords associated with the route + * @param array $params optional params of the route + * + * @return array + */ + public function computeRoute($rule, $controller, array $keywords = array(), array $params = array()) + { + $regexp = preg_quote($rule, '#'); + if ($keywords) { + $transform_keywords = array(); + preg_match_all( + '#\\\{(([^{}]*)\\\:)?(' . + implode('|', array_keys($keywords)) . ')(\\\:([^{}]*))?\\\}#', + $regexp, + $m + ); + for ($i = 0, $total = count($m[0]); $i < $total; ++$i) { + $prepend = $m[2][$i]; + $keyword = $m[3][$i]; + $append = $m[5][$i]; + $transform_keywords[$keyword] = array( + 'required' => isset($keywords[$keyword]['param']), + 'prepend' => stripslashes($prepend), + 'append' => stripslashes($append), + ); + + $prepend_regexp = $append_regexp = ''; + if ($prepend || $append) { + $prepend_regexp = '(' . $prepend; + $append_regexp = $append . ')?'; + } + + if (isset($keywords[$keyword]['param'])) { + $regexp = str_replace( + $m[0][$i], + $prepend_regexp . + '(?P<' . $keywords[$keyword]['param'] . '>' . $keywords[$keyword]['regexp'] . ')' . + $append_regexp, + $regexp + ); + } else { + $regexp = str_replace( + $m[0][$i], + $prepend_regexp . + '(' . $keywords[$keyword]['regexp'] . ')' . + $append_regexp, + $regexp + ); + } + } + $keywords = $transform_keywords; + } + + $regexp = '#^/' . $regexp . '$#u'; + + return array( + 'rule' => $rule, + 'regexp' => $regexp, + 'controller' => $controller, + 'keywords' => $keywords, + 'params' => $params, + ); + } + + /** + * @param string $route_id Name of the route (need to be uniq,a second route with same name will override the first) + * @param string $rule Url rule + * @param string $controller Controller to call if request uri match the rule + * @param int $id_lang + * @param array $keywords + * @param array $params + * @param int $id_shop + */ + public function addRoute( + $route_id, + $rule, + $controller, + $id_lang = null, + array $keywords = array(), + array $params = array(), + $id_shop = null + ) { + $context = Context::getContext(); + + if (isset($context->language) && $id_lang === null) { + $id_lang = (int) $context->language->id; + } + + if (isset($context->shop) && $id_shop === null) { + $id_shop = (int) $context->shop->id; + } + + $route = $this->computeRoute($rule, $controller, $keywords, $params); + + if (!isset($this->routes[$id_shop])) { + $this->routes[$id_shop] = array(); + } + if (!isset($this->routes[$id_shop][$id_lang])) { + $this->routes[$id_shop][$id_lang] = array(); + } + + $this->routes[$id_shop][$id_lang][$route_id] = $route; + } + + /** + * Check if a route exists. + * + * @param string $route_id + * @param int $id_lang + * @param int $id_shop + * + * @return bool + */ + public function hasRoute($route_id, $id_lang = null, $id_shop = null) + { + if (isset(Context::getContext()->language) && $id_lang === null) { + $id_lang = (int) Context::getContext()->language->id; + } + if (isset(Context::getContext()->shop) && $id_shop === null) { + $id_shop = (int) Context::getContext()->shop->id; + } + + return isset($this->routes[$id_shop]) && isset($this->routes[$id_shop][$id_lang]) + && isset($this->routes[$id_shop][$id_lang][$route_id]); + } + + /** + * Check if a keyword is written in a route rule. + * + * @param string $route_id + * @param int $id_lang + * @param string $keyword + * @param int $id_shop + * + * @return bool + */ + public function hasKeyword($route_id, $id_lang, $keyword, $id_shop = null) + { + if ($id_shop === null) { + $id_shop = (int) Context::getContext()->shop->id; + } + + if (!isset($this->routes[$id_shop])) { + $this->loadRoutes($id_shop); + } + + if (!isset($this->routes[$id_shop]) || !isset($this->routes[$id_shop][$id_lang]) + || !isset($this->routes[$id_shop][$id_lang][$route_id])) { + return false; + } + + return preg_match('#\{([^{}]*:)?' . preg_quote($keyword, '#') . + '(:[^{}]*)?\}#', $this->routes[$id_shop][$id_lang][$route_id]['rule']); + } + + /** + * Check if a route rule contain all required keywords of default route definition. + * + * @param string $route_id + * @param string $rule Rule to verify + * @param array $errors List of missing keywords + * + * @return bool + */ + public function validateRoute($route_id, $rule, &$errors = array()) + { + $errors = array(); + if (!isset($this->default_routes[$route_id])) { + return false; + } + + foreach ($this->default_routes[$route_id]['keywords'] as $keyword => $data) { + if (isset($data['param']) && !preg_match('#\{([^{}]*:)?' . $keyword . '(:[^{}]*)?\}#', $rule)) { + $errors[] = $keyword; + } + } + + return (count($errors)) ? false : true; + } + + /** + * Create an url from. + * + * @param string $route_id Name the route + * @param int $id_lang + * @param array $params + * @param bool $force_routes + * @param string $anchor Optional anchor to add at the end of this url + * @param null $id_shop + * + * @return string + * + * @throws PrestaShopException + */ + public function createUrl( + $route_id, + $id_lang = null, + array $params = array(), + $force_routes = false, + $anchor = '', + $id_shop = null + ) { + if ($id_lang === null) { + $id_lang = (int) Context::getContext()->language->id; + } + if ($id_shop === null) { + $id_shop = (int) Context::getContext()->shop->id; + } + + if (!isset($this->routes[$id_shop])) { + $this->loadRoutes($id_shop); + } + + if (!isset($this->routes[$id_shop][$id_lang][$route_id])) { + $query = http_build_query($params, '', '&'); + $index_link = $this->use_routes ? '' : 'index.php'; + + return ($route_id == 'index') ? $index_link . (($query) ? '?' . $query : '') : + ((trim($route_id) == '') ? '' : 'index.php?controller=' . $route_id) . (($query) ? '&' . $query : '') . $anchor; + } + $route = $this->routes[$id_shop][$id_lang][$route_id]; + // Check required fields + $query_params = isset($route['params']) ? $route['params'] : array(); + foreach ($route['keywords'] as $key => $data) { + if (!$data['required']) { + continue; + } + + if (!array_key_exists($key, $params)) { + // throw new PrestaShopException('Dispatcher::createUrl() miss required parameter "' . + // $key . '" for route "' . $route_id . '"'); + } + if (isset($this->default_routes[$route_id])) { + $query_params[$this->default_routes[$route_id]['keywords'][$key]['param']] = $params[$key]; + } + } + + // Build an url which match a route + if ($this->use_routes || $force_routes) { + $url = $route['rule']; + $add_param = array(); + + foreach ($params as $key => $value) { + if (!isset($route['keywords'][$key])) { + if (!isset($this->default_routes[$route_id]['keywords'][$key])) { + $add_param[$key] = $value; + } + } else { + if ($params[$key]) { + $replace = $route['keywords'][$key]['prepend'] . $params[$key] . $route['keywords'][$key]['append']; + } else { + $replace = ''; + } + $url = preg_replace('#\{([^{}]*:)?' . $key . '(:[^{}]*)?\}#', $replace, $url); + } + } + $url = preg_replace('#\{([^{}]*:)?[a-z0-9_]+?(:[^{}]*)?\}#', '', $url); + if (count($add_param)) { + $url .= '?' . http_build_query($add_param, '', '&'); + } + } else { + // Build a classic url index.php?controller=foo&... + $add_params = array(); + foreach ($params as $key => $value) { + if (!isset($route['keywords'][$key]) && !isset($this->default_routes[$route_id]['keywords'][$key])) { + $add_params[$key] = $value; + } + } + + if (!empty($route['controller'])) { + $query_params['controller'] = $route['controller']; + } + $query = http_build_query(array_merge($add_params, $query_params), '', '&'); + if ($this->multilang_activated) { + $query .= (!empty($query) ? '&' : '') . 'id_lang=' . (int) $id_lang; + } + $url = 'index.php?' . $query; + } + + return $url . $anchor; + } + + /** + * Retrieve the controller from url or request uri if routes are activated. + * + * @param int $id_shop + * + * @return string + */ + public function getController($id_shop = null) + { + if (defined('_PS_ADMIN_DIR_')) { + $_GET['controllerUri'] = Tools::getValue('controller'); + } + if ($this->controller) { + $_GET['controller'] = $this->controller; + + return $this->controller; + } + + if (isset(Context::getContext()->shop) && $id_shop === null) { + $id_shop = (int) Context::getContext()->shop->id; + } + + $controller = Tools::getValue('controller'); + + if (isset($controller) + && is_string($controller) + && preg_match('/^([0-9a-z_-]+)\?(.*)=(.*)$/Ui', $controller, $m) + ) { + $controller = $m[1]; + if (isset($_GET['controller'])) { + $_GET[$m[2]] = $m[3]; + } elseif (isset($_POST['controller'])) { + $_POST[$m[2]] = $m[3]; + } + } + + if (!Validate::isControllerName($controller)) { + $controller = false; + } + + // Use routes ? (for url rewriting) + if ($this->use_routes && !$controller && !defined('_PS_ADMIN_DIR_')) { + if (!$this->request_uri) { + return strtolower($this->controller_not_found); + } + $controller = $this->controller_not_found; + $test_request_uri = preg_replace('/(=http:\/\/)/', '=', $this->request_uri); + + // If the request_uri matches a static file, then there is no need to check the routes, we keep + // "controller_not_found" (a static file should not go through the dispatcher) + if (!preg_match( + '/\.(gif|jpe?g|png|css|js|ico)$/i', + parse_url($test_request_uri, PHP_URL_PATH) + )) { + // Add empty route as last route to prevent this greedy regexp to match request uri before right time + if ($this->empty_route) { + $this->addRoute( + $this->empty_route['routeID'], + $this->empty_route['rule'], + $this->empty_route['controller'], + Context::getContext()->language->id, + array(), + array(), + $id_shop + ); + } + + list($uri) = explode('?', $this->request_uri); + + if (isset($this->routes[$id_shop][Context::getContext()->language->id])) { + foreach ($this->routes[$id_shop][Context::getContext()->language->id] as $route) { + if (preg_match($route['regexp'], $uri, $m)) { + // Route found ! Now fill $_GET with parameters of uri + foreach ($m as $k => $v) { + if (!is_numeric($k)) { + $_GET[$k] = $v; + } + } + + $controller = $route['controller'] ? $route['controller'] : $_GET['controller']; + if (!empty($route['params'])) { + foreach ($route['params'] as $k => $v) { + $_GET[$k] = $v; + } + } + + // A patch for module friendly urls + if (preg_match('#module-([a-z0-9_-]+)-([a-z0-9_]+)$#i', $controller, $m)) { + $_GET['module'] = $m[1]; + $_GET['fc'] = 'module'; + $controller = $m[2]; + } + + if (isset($_GET['fc']) && $_GET['fc'] == 'module') { + $this->front_controller = self::FC_MODULE; + } + break; + } + } + } + } + + if ($controller == 'index' || preg_match('/^\/index.php(?:\?.*)?$/', $this->request_uri)) { + $controller = $this->useDefaultController(); + } + } + + $this->controller = str_replace('-', '', $controller); + $_GET['controller'] = $this->controller; + + return $this->controller; + } + + /** + * Get list of all available FO controllers. + * + * @var mixed + * + * @return array + */ + public static function getControllers($dirs) + { + if (!is_array($dirs)) { + $dirs = array($dirs); + } + + $controllers = array(); + foreach ($dirs as $dir) { + $controllers = array_merge($controllers, Dispatcher::getControllersInDirectory($dir)); + } + + return $controllers; + } + + /** + * Get list of all available Module Front controllers. + * + * @param string $type + * @param string $module + * + * @return array + */ + public static function getModuleControllers($type = 'all', $module = null) + { + $modules_controllers = array(); + if (is_null($module)) { + $modules = Module::getModulesOnDisk(true); + } elseif (!is_array($module)) { + $modules = array(Module::getInstanceByName($module)); + } else { + $modules = array(); + foreach ($module as $_mod) { + $modules[] = Module::getInstanceByName($_mod); + } + } + + foreach ($modules as $mod) { + foreach (Dispatcher::getControllersInDirectory(_PS_MODULE_DIR_ . $mod->name . '/controllers/') as $controller) { + if ($type == 'admin') { + if (strpos($controller, 'Admin') !== false) { + $modules_controllers[$mod->name][] = $controller; + } + } elseif ($type == 'front') { + if (strpos($controller, 'Admin') === false) { + $modules_controllers[$mod->name][] = $controller; + } + } else { + $modules_controllers[$mod->name][] = $controller; + } + } + } + + return $modules_controllers; + } + + /** + * Get list of available controllers from the specified dir. + * + * @param string $dir Directory to scan (recursively) + * + * @return array + */ + public static function getControllersInDirectory($dir) + { + if (!is_dir($dir)) { + return array(); + } + + $controllers = array(); + $controller_files = scandir($dir, SCANDIR_SORT_NONE); + foreach ($controller_files as $controller_filename) { + if ($controller_filename[0] != '.') { + if (!strpos($controller_filename, '.php') && is_dir($dir . $controller_filename)) { + $controllers += Dispatcher::getControllersInDirectory( + $dir . $controller_filename . DIRECTORY_SEPARATOR + ); + } elseif ($controller_filename != 'index.php') { + $key = str_replace(array('controller.php', '.php'), '', strtolower($controller_filename)); + $controllers[$key] = basename($controller_filename, '.php'); + } + } + } + + return $controllers; + } +} diff --git a/modules/appagebuilder/Readme.md b/modules/appagebuilder/Readme.md new file mode 100644 index 00000000..548c9cb4 --- /dev/null +++ b/modules/appagebuilder/Readme.md @@ -0,0 +1,5 @@ +# Ap Page Builder + +## About +Construction site: provide a method of building effective site, high flexibility, to create multi header and profile for the home page, product page. +The module will provide a full range of widgets with user friendly features for building websites for your shop as optimized for SEO, responsive design, multi header... \ No newline at end of file diff --git a/modules/appagebuilder/apadminajax.php b/modules/appagebuilder/apadminajax.php new file mode 100644 index 00000000..e4a87ab8 --- /dev/null +++ b/modules/appagebuilder/apadminajax.php @@ -0,0 +1,30 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} +require_once(dirname(__FILE__).'/../../config/config.inc.php'); +require_once(dirname(__FILE__).'/../../init.php'); +include_once(dirname(__FILE__).'/appagebuilder.php'); + +$module = APPageBuilder::getInstance(); + +//DONGND:: get product link for demo multi product detail +if (Tools::getValue('action') == 'get-list-shortcode') { + $result = ''; + $result = $module->getListShortCodeForEditor(); + die($result); +} diff --git a/modules/appagebuilder/apajax.php b/modules/appagebuilder/apajax.php new file mode 100644 index 00000000..5d896f6a --- /dev/null +++ b/modules/appagebuilder/apajax.php @@ -0,0 +1,237 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +require_once(dirname(__FILE__) . '/../../config/config.inc.php'); +require_once(dirname(__FILE__) . '/../../init.php'); +include_once(dirname(__FILE__) . '/appagebuilder.php'); +include_once(dirname(__FILE__) . '/classes/shortcodes.php'); +include_once(dirname(__FILE__) . '/classes/shortcodes/ApProductList.php'); +$module = APPageBuilder::getInstance(); +apPageHelper::setGlobalVariable(Context::getContext()); + +//DONGND:: get product link for demo multi product detail +if (Tools::getValue('action') == 'get-product-link') +{ + $result = ''; + + $sql = 'SELECT p.`id_product` FROM `' . _DB_PREFIX_ . 'product` p ' . Shop::addSqlAssociation('product', 'p') . ' + AND product_shop.`visibility` IN ("both", "catalog") + AND product_shop.`active` = 1 + ORDER BY p.`id_product` ASC'; + $first_product = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql); + $result = Context::getContext()->link->getProductLink($first_product['id_product'], null, null, null, null, null, (int)Product::getDefaultAttribute((int)$first_product['id_product'])); + die(Tools::jsonEncode($result)); +} + +if (Tools::getValue('leoajax') == 1) +{ + # process category + $list_cat = Tools::getValue('cat_list'); + $product_list_image = Tools::getValue('product_list_image'); + $product_one_img = Tools::getValue('product_one_img'); + $leo_pro_cdown = Tools::getValue('pro_cdown'); + $leo_pro_color = Tools::getValue('pro_color'); + // $ap_extra = Tools::getValue('product_apextra'); + //add function wishlist compare + $wishlist_compare = Tools::getValue('wishlist_compare'); + + $result = array(); + + // if ($ap_extra) { + // $id_lang = Context::getContext()->language->id; + // $id_shop = Context::getContext()->shop->id; + // $sql = 'SELECT * FROM '._DB_PREFIX_.'appagebuilder_extrapro WHERE id_product IN('.pSQL($ap_extra).') AND id_lang="'.(int)$id_lang.'" AND id_shop="'.(int)$id_shop.'"'; + // $product_extras = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); + // + // if ($product_extras) { + // foreach ($product_extras as $value) { + // $result['pro_apextra'][$value['id_product']] = $value; + // } + // } + // } + //get number product of compare + wishlist + if ($wishlist_compare) + { + $wishlist_products = 0; + if (Configuration::get('LEOFEATURE_ENABLE_PRODUCTWISHLIST') && isset(Context::getContext()->cookie->id_customer)) + { + $current_user = (int)Context::getContext()->cookie->id_customer; + $list_wishlist = Db::getInstance()->executeS("SELECT id_wishlist FROM `" . _DB_PREFIX_ . "leofeature_wishlist` WHERE id_customer = '" . (int)$current_user . "'"); + foreach ($list_wishlist as $list_wishlist_item) + { + $number_product_wishlist = Db::getInstance()->getValue("SELECT COUNT(id_wishlist_product) FROM `" . _DB_PREFIX_ . "leofeature_wishlist_product` WHERE id_wishlist = " . (int)$list_wishlist_item['id_wishlist']); + $wishlist_products += $number_product_wishlist; + } + // $wishlist_products = Db::getInstance()->getValue("SELECT COUNT(id_wishlist_product) FROM `"._DB_PREFIX_."wishlist_product` WHERE id_wishlist = '$id_wishlist'"); + } + + $compared_products = array(); + if (Configuration::get('LEOFEATURE_ENABLE_PRODUCTCOMPARE') && Configuration::get('LEOFEATURE_COMPARATOR_MAX_ITEM') > 0 && isset(Context::getContext()->cookie->id_compare)) + { + $compared_products = Db::getInstance()->executeS(' + SELECT DISTINCT `id_product` + FROM `' . _DB_PREFIX_ . 'leofeature_compare` c + LEFT JOIN `' . _DB_PREFIX_ . 'leofeature_compare_product` cp ON (cp.`id_compare` = c.`id_compare`) + WHERE cp.`id_compare` = ' . (int)(Context::getContext()->cookie->id_compare)); + } + $result['wishlist_products'] = $wishlist_products; + $result['compared_products'] = count($compared_products); + } + + if ($list_cat) + { + $list_cat = explode(',', $list_cat); + $list_cat = array_filter($list_cat); + $list_cat = array_unique($list_cat); + $list_cat = array_map('intval', $list_cat); // fix sql injection + $list_cat = implode(',', $list_cat); + + $sql = 'SELECT COUNT(cp.`id_product`) AS total, cp.`id_category` FROM `' . _DB_PREFIX_ . 'product` p ' . Shop::addSqlAssociation('product', 'p') . ' + LEFT JOIN `' . _DB_PREFIX_ . 'category_product` cp ON p.`id_product` = cp.`id_product` + WHERE cp.`id_category` IN (' . pSQL($list_cat) . ') + AND product_shop.`visibility` IN ("both", "catalog") + AND product_shop.`active` = 1 + GROUP BY cp.`id_category`'; + $cat = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); + if ($cat) + { + $result['cat'] = $cat; + } + } + + if ($leo_pro_cdown) + { + $leo_pro_cdown = explode(',', $leo_pro_cdown); + $leo_pro_cdown = array_unique($leo_pro_cdown); + $leo_pro_cdown = implode(',', $leo_pro_cdown); + $result['pro_cdown'] = $module->hookProductCdown($leo_pro_cdown); + } + + if ($leo_pro_color) + { + $leo_pro_color = explode(',', $leo_pro_color); + $leo_pro_color = array_unique($leo_pro_color); + $leo_pro_color = implode(',', $leo_pro_color); + $result['pro_color'] = $module->hookProductColor($leo_pro_color); + } + + if ($product_list_image) + { + $product_list_image = explode(',', $product_list_image); + $product_list_image = array_unique($product_list_image); + $product_list_image = implode(',', $product_list_image); + + # $leocustomajax = new Leocustomajax(); + $result['product_list_image'] = $module->hookProductMoreImg($product_list_image); + } + if ($product_one_img) + { + $product_one_img = explode(',', $product_one_img); + $product_one_img = array_unique($product_one_img); + $product_one_img = implode(',', $product_one_img); + + $result['product_one_img'] = $module->hookProductOneImg($product_one_img); + } + + if ($result) + { + die(Tools::jsonEncode($result)); + } +} +elseif (Tools::getValue('widget') == 'ApImageGallery') +{ + + $show_number = Tools::getValue('show_number'); + $assign = Tools::getValue('assign', array()); + $assign = Tools::jsonDecode($assign, true); + + $show_number_new = $show_number; + $form_atts = $assign['formAtts']; + + $limit = (int)$form_atts['limit'] + $show_number; + $images = array(); + $link = new Link(); + $current_link = $link->getPageLink('', false, Context::getContext()->language->id); + $path = _PS_ROOT_DIR_ . '/' . str_replace($current_link, '', isset($form_atts['path']) ? $form_atts['path'] : ''); + $arr_exten = array('jpg', 'jpge', 'gif', 'png'); + + + $count = 0; + if ($path && is_dir($path)) + { + if ($handle = scandir($path)) + { + + if (($key = array_search('.', $handle)) !== false) + { + unset($handle[$key]); + } + if (($key = array_search('..', $handle)) !== false) + { + unset($handle[$key]); + } + + foreach ($handle as $entry) + { + if ($entry != '.' && $entry != '..' && is_file($path . '/' . $entry)) + { + $ext = pathinfo($path . '/' . $entry, PATHINFO_EXTENSION); + if (in_array($ext, $arr_exten)) + { + $url = __PS_BASE_URI__ . '/' . str_replace($current_link, '', $form_atts['path']) . '/' . $entry; + $url = str_replace('//', '/', $url); + + if ($count >= $show_number) + { + $images[] = $url; + $show_number_new++; + } + $count++; + if ($count == $limit) + { + break; + } + } + } + } + } + } + + $total = count($handle); + $total_nerver_show = (int)($total - $count); + $c = (int)$form_atts['columns']; + $assign['columns'] = $c > 0 ? $c : 4; + + $result = array( + 'images' => array(), + 'show_number' => -1, + 'hasError' => 0, + 'errors' => array(), + ); + + $result['images'] = $images; + if ($total_nerver_show > 0) + { + $result['show_number'] = $show_number_new; + } + die(Tools::jsonEncode($result)); +} +else +{ + $obj = new ApProductList(); + $result = $obj->ajaxProcessRender($module); + die(Tools::jsonEncode($result)); +} diff --git a/modules/appagebuilder/appagebuilder.php b/modules/appagebuilder/appagebuilder.php new file mode 100644 index 00000000..cbce4fab --- /dev/null +++ b/modules/appagebuilder/appagebuilder.php @@ -0,0 +1,3255 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} +require_once(_PS_MODULE_DIR_.'appagebuilder/libs/Helper.php'); +require_once(_PS_MODULE_DIR_.'appagebuilder/libs/LeoFrameworkHelper.php'); +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageSetting.php'); +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageBuilderModel.php'); +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageBuilderProfilesModel.php'); +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageBuilderProductsModel.php'); +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageBuilderShortcodeModel.php'); + +class APPageBuilder extends Module +{ + protected $default_language; + protected $languages; + protected $theme_name; + protected $data_index_hook; + protected $profile_data; + protected $hook_index_data; + protected $profile_param; + protected $path_resource; + protected $product_active; + protected $backup_dir; + protected $header_content; + + protected $_confirmations = array(); + protected $_errors = array(); + protected $_warnings = array(); + private $templateFile; + + public function __construct() + { + $this->name = 'appagebuilder'; + $this->module_key = '9da746af2f0aa356120277ab2a148484'; + $this->tab = 'front_office_features'; + $this->version = '2.2.0'; + $this->author = 'ApolloTheme'; + $this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_); + $this->need_instance = 0; + $this->secure_key = Tools::encrypt($this->name); + $this->bootstrap = true; + parent::__construct(); + + $this->displayName = $this->l('Apollo Page Builder'); + $this->description = $this->l('Apollo Page Builder build content for your site.'); + $this->theme_name = _THEME_NAME_; + $this->default_language = Language::getLanguage(Context::getContext()->language->id); + $this->languages = Language::getLanguages(); + $this->path_resource = $this->_path.'views/'; + $this->templateFile = 'module:appagebuilder/views/templates/hook/appagebuilder.tpl'; + $this->redirectFriendUrl(); + } + + public function redirectFriendUrl() + { +// if (Context::getContext()->controller === null || (isset(Context::getContext()->controller->controller_type) && in_array(Context::getContext()->controller->controller_type, array('front', 'modulefront')))) { + // NEED HOOK TO MODULEROUTES + $ap_live_edit = Tools::getValue('ap_live_edit'); + if (empty($ap_live_edit) && (Context::getContext()->controller === null || Context::getContext()->controller->controller_type != 'admin')) { + $id_appagebuilder_profiles = Tools::getValue('id_appagebuilder_profiles'); + if (Configuration::get('PS_REWRITING_SETTINGS') && Tools::getIsset('id_appagebuilder_profiles') && $id_appagebuilder_profiles) { + $profile_data = ApPageBuilderProfilesModel::getActiveProfile('index'); + + if (isset($profile_data['friendly_url']) && !empty($profile_data['friendly_url'])) { + require_once(_PS_MODULE_DIR_.'appagebuilder/libs/LeoFriendlyUrl.php'); + $leo_friendly_url = LeoFriendlyUrl::getInstance(); + + $link = Context::getContext()->link; + $idLang = Context::getContext()->language->id; + $idShop = null; + $relativeProtocol = false; + + $url = $link->getBaseLink($idShop, null, $relativeProtocol).$leo_friendly_url->getLangLink($idLang, null, $idShop).$profile_data['friendly_url'].'.html'; + $leo_friendly_url->canonicalRedirection($url); + } + } + } + } + + public static function getInstance() + { + static $_instance; + if (!$_instance) { + $_instance = new APPageBuilder(); + } + return $_instance; + } + + public function install() + { + require_once(_PS_MODULE_DIR_.$this->name.'/libs/setup.php'); + + //DONGND:: build shortcode, create folder for override + apPageHelper::createShortCode(); + + if (!parent::install() || !ApPageSetup::installConfiguration() || !ApPageSetup::createTables() || !ApPageSetup::installModuleTab() || !$this->registerLeoHook()) { + return false; + } + + # NOT LOAD DATASAMPLE AGAIN + Configuration::updateValue('AP_INSTALLED_APPAGEBUILDER', '1'); + + # REMOVE FILE INDEX.PHP FOR TRANSLATE + ApPageSetup::processTranslateTheme(); + + Configuration::updateValue('APPAGEBUILDER_OVERRIDED', 1); + + return true; + } + + public function uninstall() + { + require_once(_PS_MODULE_DIR_.$this->name.'/libs/setup.php'); + + //DONGND:: rollback default file config for tinymce + Tools::copy(_PS_MODULE_DIR_.$this->name.'/views/js/shortcode/backup/tinymce.inc.js', _PS_ROOT_DIR_.'/js/admin/tinymce.inc.js'); + + if (!parent::uninstall()|| !ApPageSetup::uninstallModuleTab() || !ApPageSetup::deleteTables() || !ApPageSetup::uninstallConfiguration()) { + return false; + } + + //DONGND:: remove overrider folder + // $this->uninstallOverrides(); + Configuration::updateValue('APPAGEBUILDER_OVERRIDED', 0); + + return true; + } + + public function hookActionModuleRegisterHookAfter($params) + { + if (isset($params['hook_name']) && ($params['hook_name'] == 'header' || $params['hook_name']=='displayheader')) { + if ($this->getConfig('MOVE_END_HEADER')) { + $hook_name = 'header'; + $id_hook = Hook::getIdByName($hook_name); + $id_module = $this->id; + $id_shop = Context::getContext()->shop->id; + + // Get module position in hook + $sql = 'SELECT MAX(`position`) AS position + FROM `'._DB_PREFIX_.'hook_module` + WHERE `id_hook` = '.(int)$id_hook.' AND `id_shop` = '.(int)$id_shop . ' AND id_module != '.(int) $id_module; + if (!$position = Db::getInstance()->getValue($sql)) { + $position = 0; + } + + $sql = 'UPDATE `'._DB_PREFIX_.'hook_module'.'` SET `position` =' . (int)($position + 1) . ' WHERE ' + . '`id_module` = '.(int) $id_module + . ' AND `id_hook` = '.(int) $id_hook + . ' AND `id_shop` = '.(int) $id_shop; + Db::getInstance()->execute($sql); + } + } + } + + public function postProcess() + { + if (count($this->errors) > 0) { + return; + } + + if (Tools::isSubmit('installdemo')) { + require_once(_PS_MODULE_DIR_.$this->name.'/libs/setup.php'); + ApPageSetup::installSample(); + } else if (Tools::isSubmit('resetmodule')) { + require_once(_PS_MODULE_DIR_.$this->name.'/libs/setup.php'); + ApPageSetup::createTables(1); + } else if (Tools::isSubmit('deleteposition')) { + apPageHelper::processDeleteOldPosition(); + $this->_confirmations[] = 'POSITIONS NOT USE have been deleted successfully.'; + } else if (Tools::isSubmit('submitUpdateModule')) { + apPageHelper::processCorrectModule(); + $this->_confirmations[] = 'Update and Correct Module is successful'; + } else if (Tools::isSubmit('backup')) { + $this->processBackup(); + $this->_confirmations[] = 'Back-up to PHP file is successful'; + } else if (Tools::isSubmit('restore')) { + $this->processRestore(); + $this->_confirmations[] = 'Restore Back-up File is successful'; + } else if (Tools::isSubmit('submitApPageBuilder')) { + $load_owl = Tools::getValue('APPAGEBUILDER_LOAD_OWL'); + $header_hook = Tools::getValue('APPAGEBUILDER_HEADER_HOOK'); + $content_hook = Tools::getValue('APPAGEBUILDER_CONTENT_HOOK'); + $footer_hook = Tools::getValue('APPAGEBUILDER_FOOTER_HOOK'); + $product_hook = Tools::getValue('APPAGEBUILDER_PRODUCT_HOOK'); + Configuration::updateValue('APPAGEBUILDER_LOAD_OWL', (int)$load_owl); + Configuration::updateValue('APPAGEBUILDER_LOAD_SWIPER', Tools::getValue('APPAGEBUILDER_LOAD_SWIPER')); + Configuration::updateValue('APPAGEBUILDER_LOAD_SLICK', Tools::getValue('APPAGEBUILDER_LOAD_SLICK')); + Configuration::updateValue('APPAGEBUILDER_COOKIE_PROFILE', Tools::getValue('APPAGEBUILDER_COOKIE_PROFILE')); + Configuration::updateValue('APPAGEBUILDER_HEADER_HOOK', $header_hook); + Configuration::updateValue('APPAGEBUILDER_CONTENT_HOOK', $content_hook); + Configuration::updateValue('APPAGEBUILDER_FOOTER_HOOK', $footer_hook); + Configuration::updateValue('APPAGEBUILDER_PRODUCT_HOOK', $product_hook); +// Configuration::updateValue('APPAGEBUILDER_LOAD_AJAX', Tools::getValue('APPAGEBUILDER_LOAD_AJAX')); + Configuration::updateValue('APPAGEBUILDER_LOAD_STELLAR', Tools::getValue('APPAGEBUILDER_LOAD_STELLAR')); + Configuration::updateValue('APPAGEBUILDER_LOAD_WAYPOINTS', Tools::getValue('APPAGEBUILDER_LOAD_WAYPOINTS')); + Configuration::updateValue('APPAGEBUILDER_LOAD_INSTAFEED', Tools::getValue('APPAGEBUILDER_LOAD_INSTAFEED')); + Configuration::updateValue('APPAGEBUILDER_LOAD_IMAGE360', Tools::getValue('APPAGEBUILDER_LOAD_IMAGE360')); + Configuration::updateValue('APPAGEBUILDER_LOAD_IMAGEHOTPOT', Tools::getValue('APPAGEBUILDER_LOAD_IMAGEHOTPOT')); + Configuration::updateValue('APPAGEBUILDER_LOAD_HTML5VIDEO', Tools::getValue('APPAGEBUILDER_LOAD_HTML5VIDEO')); + Configuration::updateValue('APPAGEBUILDER_SAVE_MULTITHREARING', Tools::getValue('APPAGEBUILDER_SAVE_MULTITHREARING')); + Configuration::updateValue('APPAGEBUILDER_SAVE_SUBMIT', Tools::getValue('APPAGEBUILDER_SAVE_SUBMIT')); + Configuration::updateValue('APPAGEBUILDER_LOAD_PRODUCTZOOM', Tools::getValue('APPAGEBUILDER_LOAD_PRODUCTZOOM')); + + Configuration::updateValue('APPAGEBUILDER_LOAD_FULLPAGEJS', Tools::getValue('APPAGEBUILDER_LOAD_FULLPAGEJS')); + Configuration::updateValue('APPAGEBUILDER_LOAD_PN', Tools::getValue('APPAGEBUILDER_LOAD_PN')); + Configuration::updateValue('APPAGEBUILDER_LOAD_TRAN', Tools::getValue('APPAGEBUILDER_LOAD_TRAN')); + Configuration::updateValue('APPAGEBUILDER_LOAD_IMG', Tools::getValue('APPAGEBUILDER_LOAD_IMG')); + Configuration::updateValue('APPAGEBUILDER_LOAD_COUNT', Tools::getValue('APPAGEBUILDER_LOAD_COUNT')); +// Configuration::updateValue('APPAGEBUILDER_LOAD_COLOR', Tools::getValue('APPAGEBUILDER_LOAD_COLOR')); + Configuration::updateValue('APPAGEBUILDER_COLOR', Tools::getValue('APPAGEBUILDER_COLOR')); +// Configuration::updateValue('APPAGEBUILDER_LOAD_ACOLOR', Tools::getValue('APPAGEBUILDER_LOAD_ACOLOR')); + Configuration::updateValue('APPAGEBUILDER_PRODUCT_MAX_RANDOM', Tools::getValue('APPAGEBUILDER_PRODUCT_MAX_RANDOM')); + Configuration::updateValue('APPAGEBUILDER_LOAD_COOKIE', Tools::getValue('APPAGEBUILDER_LOAD_COOKIE')); + + //nghiatd - update extrafield + $this->saveConfigExtrafields('APPAGEBUILDER_PRODUCT_TEXTEXTRA', 'APPAGEBUILDER_PRODUCT_EDITOREXTRA', 'product'); + $this->saveConfigExtrafields('APPAGEBUILDER_CATEGORY_TEXTEXTRA', 'APPAGEBUILDER_CATEGORY_EDITOREXTRA', 'category'); + } + } + + + public function getContent() + { + $this->errors = array(); + if (!$this->access('configure')) { + $this->errors[] = $this->trans('You do not have permission to configure this.', array(), 'Admin.Notifications.Error'); + $this->context->smarty->assign('errors', $this->errors); + } + + $this->postProcess(); + + $output = ''; + $this->backup_dir = str_replace('\\', '/', _PS_CACHE_DIR_.'backup/modules/appagebuilder/'); + + $create_profile_link = $this->context->link->getAdminLink('AdminApPageBuilderProfiles').'&addappagebuilder_profiles'; + $profile_link = $this->context->link->getAdminLink('AdminApPageBuilderProfiles'); + $position_link = $this->context->link->getAdminLink('AdminApPageBuilderPositions'); + $product_link = $this->context->link->getAdminLink('AdminApPageBuilderProducts'); + $path_guide = _PS_MODULE_DIR_.$this->name.'/views/templates/admin/guide.tpl'; + $guide_box = ApPageSetting::buildGuide($this->context, $path_guide, 1); + + $module_link = $this->context->link->getAdminLink('AdminModules', false) + .'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name.'&token='.Tools::getAdminTokenLite('AdminModules'); + $back_up_file = @Tools::scandir($this->backup_dir, 'php'); + arsort($back_up_file); + $this->context->smarty->assign(array( + 'guide_box' => $guide_box, + 'create_profile_link' => $create_profile_link, + 'profile_link' => $profile_link, + 'position_link' => $position_link, + 'product_link' => $product_link, + 'module_link' => $module_link, + 'back_up_file' => $back_up_file, + 'backup_dir' => $this->backup_dir, + )); + $output = $this->generateLeoHtmlMessage(); + $output .= $this->context->smarty->fetch($this->local_path.'views/templates/admin/configure.tpl'); + Media::addJsDef(array('js_ap_controller' => 'module_configuration')); + return $output.$this->renderForm(); + } + + public function saveConfigExtrafields($ft, $fe, $type) + { + $field_text = array_unique(explode(',', Tools::getValue($ft))); + $field_default = array('name', 'description', 'description_short', 'link_rewrite', 'meta_description', 'meta_keywords', 'meta_title', 'name', 'available_now', 'available_later', 'online_only', 'ean13', 'isbn', 'upc', 'ecotax', 'quantity', 'minimal_quantity', 'price', 'wholesale_price', 'unity', 'unit_price_ratio', 'additional_shipping_cost', 'reference', 'supplier_reference', 'location', 'width', 'height', 'depth', 'weight', 'out_of_stock', 'quantity_discount', 'customizable', 'uploadable_files', 'text_fields', 'active', 'redirect_type', 'id_type_redirected', 'available_date', 'show_condition', 'condition', 'show_price', 'indexed', 'cache_is_pack', 'cache_has_attachments', 'is_virtual', 'cache_default_attribute', 'date_add', 'date_upd', 'advanced_stock_management', 'pack_stock_type', 'state'); + $field_text_valid = array(); + foreach ($field_text as $k => $v) { + // validate module + unset($k); + + $v = str_replace(' ', '_', trim($v)); + $v = preg_replace('/[^A-Za-z0-9\_]/', '', $v); + if ($v && !in_array($v, $field_default)) { + $field_text_valid[] = $v; + } + } + + Configuration::updateValue($ft, implode(',', $field_text_valid)); + $this->processExtrafield($field_text_valid, $type, 'varchar(255)'); + + $field_editor = array_unique(explode(',', Tools::getValue($fe))); + $field_editor_valid = array(); + foreach ($field_editor as $k => $v) { + // validate module + unset($k); + + $v = str_replace(' ', '_', trim($v)); + $v = preg_replace('/[^A-Za-z0-9\_]/', '', $v); + if ($v && !in_array($v, $field_text) && !in_array($v, $field_default)) { + $field_editor_valid[] = $v; + } + } + + Configuration::updateValue($fe, implode(',', $field_editor_valid)); + $this->processExtrafield($field_editor_valid, $type, 'text'); + } + + //add by nghiatd + public function processExtrafield($submit_fields, $type, $field_type) + { + $table = ($type == 'product')?_DB_PREFIX_.'appagebuilder_extrapro':_DB_PREFIX_.'appagebuilder_extracat'; + $id = ($type == 'product')?'id_product':'id_category'; + //$field_type = ($field_type == 'varchar(255)')?'VARCHAR(255) NULL;':'TEXT;'; + $files = array(); + //check table exist and return field + $sql = 'SELECT * FROM information_schema.tables + WHERE table_schema = "'._DB_NAME_.'" + AND table_name = "'.pSQL($table).'"'; + $result = Db::getInstance()->getValue($sql); + + if (!empty($result)) { + $sql = 'SHOW FIELDS FROM `'.pSQL($table) .'`'; + $result = Db::getInstance()->executeS($sql); + foreach ($result as $value) { + $files[$value['Field']] = $value['Type']; + } + } else { + #select product layout + $this->registerHook('actionObjectProductUpdateAfter'); + $this->registerHook('displayAdminProductsExtra'); + $this->registerHook('filterProductContent'); + #select category layout + $this->registerHook('actionObjectCategoryUpdateAfter'); + $this->registerHook('displayBackOfficeCategory'); + $this->registerHook('filterCategoryContent'); + + Db::getInstance()->execute(' + CREATE TABLE IF NOT EXISTS `'.pSQL($table).'` ( + `'.pSQL($id).'` int(11) unsigned NOT NULL, + `id_shop` int(11) unsigned NOT NULL DEFAULT \'1\', + `id_lang` int(10) unsigned NOT NULL, + PRIMARY KEY (`'.pSQL($id).'`, `id_shop`, `id_lang`) + ) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=UTF8; + '); + } + + //add field + foreach ($submit_fields as $value) { + if ($value && !array_key_exists($value, $files)) { + $sql = 'ALTER TABLE `'.pSQL($table).'` ADD `'.pSQL($value).'` '.pSQL($field_type); + //echo $sql.'
'; + Db::getInstance()->execute($sql); + $files[$value] = $field_type; + } + } + + //delete field + foreach ($files as $key => $value) { + if (!in_array($key, $submit_fields) && $key != $id && $key != 'id_shop' && $key != 'id_lang' && $value == $field_type) { + $sql = 'ALTER TABLE `'.pSQL($table).'` DROP `'.pSQL($key).'`'; + //echo $sql.'
'; + Db::getInstance()->execute($sql); + unset($files[$key]); + } + } + unset($files['id_product']); + unset($files['id_category']); + unset($files['id_shop']); + unset($files['id_lang']); + return implode(',', array_keys($files)); + } + + public function processRestore() + { + $file = Tools::getValue('backupfile'); + if (file_exists($this->backup_dir.$file)) { + $query = $dataLang = ''; + require_once($this->backup_dir.$file); + if (isset($query) && !empty($query)) { + $query = str_replace('_DB_PREFIX_', _DB_PREFIX_, $query); + $query = str_replace('_MYSQL_ENGINE_', _MYSQL_ENGINE_, $query); + $query = str_replace('LEO_ID_SHOP', (int)Context::getContext()->shop->id, $query); + $query = str_replace("\\'", "\'", $query); + + $db_data_settings = preg_split("/;\s*[\r\n]+/", $query); + foreach ($db_data_settings as $query) { + $query = trim($query); + if (!empty($query)) { + if (!Db::getInstance()->Execute($query)) { + $this->_html['error'][] = 'Can not restore for '.$this->name; + return false; + } + } + } + + if (isset($dataLang) && !empty($dataLang)) { + $languages = Language::getLanguages(true, Context::getContext()->shop->id); + foreach ($languages as $lang) { + if (isset($dataLang[Tools::strtolower($lang['iso_code'])])) { + $query = str_replace('_DB_PREFIX_', _DB_PREFIX_, $dataLang[Tools::strtolower($lang['iso_code'])]); + //if not exist language in list, get en + } else { + if (isset($dataLang['en'])) { + $query = str_replace('_DB_PREFIX_', _DB_PREFIX_, $dataLang['en']); + } else { + //firt item in array + foreach (array_keys($dataLang) as $key) { + $query = str_replace('_DB_PREFIX_', _DB_PREFIX_, $dataLang[$key]); + break; + } + } + } + $query = str_replace('_MYSQL_ENGINE_', _MYSQL_ENGINE_, $query); + $query = str_replace('LEO_ID_SHOP', (int)Context::getContext()->shop->id, $query); + $query = str_replace('LEO_ID_LANGUAGE', (int)$lang['id_lang'], $query); + $query = str_replace("\\\'", "\'", $query); + + $db_data_settings = preg_split("/;\s*[\r\n]+/", $query); + foreach ($db_data_settings as $query) { + $query = trim($query); + if (!empty($query)) { + if (!Db::getInstance()->Execute($query)) { + $this->_html['error'][] = 'Can not restore for data lang '.$this->name; + return false; + } + } + } + } + } + } + } + } + + public function processBackup() + { + $install_folder = $this->backup_dir; + + if (!is_dir($install_folder)) { + mkdir($install_folder, 0755, true); + } + $list_table = Db::getInstance()->executeS("SHOW TABLES LIKE '%appagebuilder%'"); + + $create_table = ''; + $data_with_lang = ''; + $backup_file = $install_folder.$this->name.date('_Y_m_d_H_i_s').'.php'; + $fp = @fopen($backup_file, 'w'); + if ($fp === false) { + die('Unable to create backup file '.addslashes($backup_file)); + } + + fwrite($fp, 'name." */\n"); + + $data_language = array(); + $list_lang = array(); + $languages = Language::getLanguages(true, Context::getContext()->shop->id); + foreach ($languages as $lang) { + $list_lang[$lang['id_lang']] = $lang['iso_code']; + } + + foreach ($list_table as $table) { + $table = current($table); + $table_name = str_replace(_DB_PREFIX_, '_DB_PREFIX_', $table); + // Skip tables which do not start with _DB_PREFIX_ + if (Tools::strlen($table) < Tools::strlen(_DB_PREFIX_) || strncmp($table, _DB_PREFIX_, Tools::strlen(_DB_PREFIX_)) != 0) { + continue; + } + $schema = Db::getInstance()->executeS('SHOW CREATE' . ' TABLE `'.pSQL($table).'`'); + if (count($schema) != 1 || !isset($schema[0]['Table']) || !isset($schema[0]['Create Table'])) { + fclose($fp); + die($this->l('An error occurred while backing up. Unable to obtain the schema of').' '.$table); + } + $create_table .= 'DROP TABLE IF EXISTS `'.$table_name."`;\n".$schema[0]['Create Table'].";\n"; + + if (strpos($schema[0]['Create Table'], '`id_shop`')) { + $data = Db::getInstance()->query('SELECT * FROM `'.pSQL($schema[0]['Table']).'` WHERE `id_shop`='.(int)Context::getContext()->shop->id, false); + } else { + $data = Db::getInstance()->query('SELECT * FROM `'.pSQL($schema[0]['Table']).'`', false); + } + + $sizeof = DB::getInstance()->NumRows(); + $lines = explode("\n", $schema[0]['Create Table']); + + if ($data && $sizeof > 0) { + //if table is language + $id_language = 0; + if (strpos($schema[0]['Table'], 'lang') !== false) { + $data_language[$schema[0]['Table']] = array(); + $i = 1; + while ($row = DB::getInstance()->nextRow($data)) { + $s = '('; + foreach ($row as $field => $value) { + if ($field == 'id_lang') { + $id_language = $value; + $tmp = "'".pSQL('LEO_ID_LANGUAGE', true)."',"; + } else if ($field == 'ID_SHOP') { + $tmp = "'".pSQL('ID_SHOP', true)."',"; + } else { + $tmp = "'".pSQL($value, true)."',"; + } + + if ($tmp != "'',") { + $s .= $tmp; + } else { + foreach ($lines as $line) { + if (strpos($line, '`'.$field.'`') !== false) { + if (preg_match('/(.*NOT NULL.*)/Ui', $line)) { + $s .= "'',"; + } else { + $s .= 'NULL,'; + } + break; + } + } + } + } + + if (!isset($list_lang[$id_language])) { + continue; + } + + if (!isset($data_language[$schema[0]['Table']][Tools::strtolower($list_lang[$id_language])])) { + $data_language[$schema[0]['Table']][Tools::strtolower($list_lang[$id_language])] = 'INSERT INTO `'.$table_name."` VALUES\n"; + } + + $s = rtrim($s, ','); + if ($i % 200 == 0 && $i < $sizeof) { + $s .= ");\nINSERT INTO `".$table_name."` VALUES\n"; + } else { + $s .= "),\n"; + } + $data_language[$schema[0]['Table']][Tools::strtolower($list_lang[$id_language])] .= $s; + } + } else { + //normal table + $create_table .= $this->createInsert($data, $table_name, $lines, $sizeof); + } + } + } + + $create_table = str_replace('$', '\$', $create_table); + $create_table = '$query = "'.$create_table; + //foreach by table + $tpl = array(); + + fwrite($fp, $create_table."\";\n"); + if ($data_language) { + foreach ($data_language as $key => $value) { + foreach ($value as $key1 => $value1) { + if (!isset($tpl[$key1])) { + $tpl[$key1] = Tools::substr($value1, 0, -2).";\n"; + } else { + $tpl[$key1] .= Tools::substr($value1, 0, -2).";\n"; + } + } + } + foreach ($tpl as $key => $value) { + if ($data_with_lang) { + $data_with_lang .= ',"'.$key.'"=>'.'"'.$value.'"'; + } else { + $data_with_lang .= '"'.$key.'"=>'.'"'.$value.'"'; + } + } + + //delete base uri when export + $data_with_lang = str_replace('$', '\$', $data_with_lang); + $data_with_lang = '$dataLang = Array('.$data_with_lang; + + fwrite($fp, $data_with_lang.');'); + } + fclose($fp); + } + + /** + * sub function of back-up database + */ + public function createInsert($data, $table_name, $lines, $sizeof) + { + $data_no_lang = 'INSERT INTO `'.$table_name."` VALUES\n"; + $i = 1; + while ($row = DB::getInstance()->nextRow($data)) { + $s = '('; + foreach ($row as $field => $value) { + if ($field == 'ID_SHOP') { + $tmp = "'".pSQL('ID_SHOP', true)."',"; + } else { + $tmp = "'".pSQL($value, true)."',"; + } + if ($tmp != "'',") { + $s .= $tmp; + } else { + foreach ($lines as $line) { + if (strpos($line, '`'.$field.'`') !== false) { + if (preg_match('/(.*NOT NULL.*)/Ui', $line)) { + $s .= "'',"; + } else { + $s .= 'NULL,'; + } + break; + } + } + } + } + $s = rtrim($s, ','); + if ($i % 200 == 0 && $i < $sizeof) { + $s .= ");\nINSERT INTO `".$table_name."` VALUES\n"; + } elseif ($i < $sizeof) { + $s .= "),\n"; + } else { + $s .= ");\n"; + } + $data_no_lang .= $s; + + ++$i; + } + return $data_no_lang; + } + + public function renderForm() + { + $list_all_hooks = $this->renderListAllHook(ApPageSetting::getHook('all')); + $list_header_hooks = (Configuration::get('APPAGEBUILDER_HEADER_HOOK')) ? + Configuration::get('APPAGEBUILDER_HEADER_HOOK') : implode(',', ApPageSetting::getHook('header')); + $list_content_hooks = (Configuration::get('APPAGEBUILDER_CONTENT_HOOK')) ? + Configuration::get('APPAGEBUILDER_CONTENT_HOOK') : implode(',', ApPageSetting::getHook('content')); + $list_footer_hooks = (Configuration::get('APPAGEBUILDER_FOOTER_HOOK')) ? + Configuration::get('APPAGEBUILDER_FOOTER_HOOK') : implode(',', ApPageSetting::getHook('footer')); + $list_product_hooks = (Configuration::get('APPAGEBUILDER_PRODUCT_HOOK')) ? + Configuration::get('APPAGEBUILDER_PRODUCT_HOOK') : implode(',', ApPageSetting::getHook('product')); + $form_general = array( + 'legend' => array( + 'title' => $this->l('General Settings'), + 'icon' => 'icon-cogs' + ), + 'input' => array( + array( + 'type' => 'html', + 'name' => 'default_html', + 'name' => 'dump_name', + 'html_content' => '
' + .$this->l('Loading JS and CSS library').'
', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Load Jquery Stellar Library'), + 'name' => 'APPAGEBUILDER_LOAD_STELLAR', + 'desc' => $this->l('This script is use for parallax. If you load it in other plugin please turn it off'), + 'is_bool' => true, + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Load Owl Carousel Library'), + 'name' => 'APPAGEBUILDER_LOAD_OWL', + 'desc' => $this->l('This script is use for Carousel. If you load it in other plugin please turn it off'), + 'is_bool' => true, + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Load Swiper Carousel Library'), + 'name' => 'APPAGEBUILDER_LOAD_SWIPER', + 'desc' => $this->l('This script is use for Carousel. If you load it in other plugin please turn it off'), + 'is_bool' => true, + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Load Waypoints Library'), + 'name' => 'APPAGEBUILDER_LOAD_WAYPOINTS', + 'desc' => $this->l('This script is use for Animated. If you load it in other plugin please turn it off'), + 'is_bool' => true, + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Load Instafeed Library'), + 'name' => 'APPAGEBUILDER_LOAD_INSTAFEED', + 'default' => 0, + 'values' => ApPageSetting::returnYesNo(), + ), + array( + 'type' => 'switch', + 'label' => $this->l('Load Video HTML5 Library'), + 'name' => 'APPAGEBUILDER_LOAD_HTML5VIDEO', + 'default' => 0, + 'values' => ApPageSetting::returnYesNo(), + ), + array( + 'type' => 'switch', + 'label' => $this->l('Load Full Page Library'), + 'name' => 'APPAGEBUILDER_LOAD_FULLPAGEJS', + 'default' => 0, + 'values' => ApPageSetting::returnYesNo(), + ), + array( + 'type' => 'switch', + 'label' => $this->l('Load Image360 Library'), + 'name' => 'APPAGEBUILDER_LOAD_IMAGE360', + 'default' => 0, + 'values' => ApPageSetting::returnYesNo(), + ), + array( + 'type' => 'switch', + 'label' => $this->l('Load Image Hotpot Library'), + 'name' => 'APPAGEBUILDER_LOAD_IMAGEHOTPOT', + 'default' => 0, + 'values' => ApPageSetting::returnYesNo(), + ), + array( + 'type' => 'switch', + 'label' => $this->l('Load Cookie Library'), + 'name' => 'APPAGEBUILDER_LOAD_COOKIE', + 'default' => 0, + 'values' => ApPageSetting::returnYesNo(), + 'desc' => $this->l('Yes : Load library JS jquery.cooki-plugin.js'), + ), + array( + 'type' => 'switch', + 'label' => $this->l('Load Product Zoom Library'), + 'name' => 'APPAGEBUILDER_LOAD_PRODUCTZOOM', + 'default' => 1, + 'values' => ApPageSetting::returnYesNo(), + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'name' => 'dump_name', + 'html_content' => '
' + .$this->l('Functions').'
', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Save Profile Multithrearing'), + 'name' => 'APPAGEBUILDER_SAVE_MULTITHREARING', + 'default' => 0, + 'values' => ApPageSetting::returnYesNo(), + 'desc' => $this->l('Yes - use AJAX SUBMIT, not load page again, keep your data safe'), + ), + array( + 'type' => 'switch', + 'label' => $this->l('Save Profile Submit'), + 'name' => 'APPAGEBUILDER_SAVE_SUBMIT', + 'default' => 0, + 'values' => ApPageSetting::returnYesNo(), + 'desc' => $this->l('Yes - use Normal SUBMIT and load page again. No - use AJAX SUBMIT, not load page again.'), + ), + array( + 'type' => 'switch', + 'label' => $this->l('Save profile and postion id to cookie'), + 'name' => 'APPAGEBUILDER_COOKIE_PROFILE', + 'default' => 0, + 'desc' => $this->l('That is only for demo, please turn off it in live site'), + 'values' => ApPageSetting::returnYesNo(), + ), + array( + 'type' => 'text', + 'label' => $this->l('Random Product'), + 'desc' => $this->l('Number of time create random product when using Prestashop_CACHED and showing product carousel has order by RANDOM'), + 'name' => 'APPAGEBUILDER_PRODUCT_MAX_RANDOM', + 'class' => '', + 'default' => 2, + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'name' => 'dump_name', + 'html_content' => '
' + .$this->l('AJAX SETTINGS'). + '
', + ), +// array( +// 'type' => 'switch', +// 'label' => $this->l('Use Ajax Feature'), +// 'name' => 'APPAGEBUILDER_LOAD_AJAX', +// 'default' => 1, +// 'values' => ApPageSetting::returnYesNo(), +// ), + array( + 'type' => 'switch', + 'label' => $this->l('AJAX Show Category Qty - Enable'), + 'name' => 'APPAGEBUILDER_LOAD_PN', + 'default' => 0, + 'values' => ApPageSetting::returnYesNo(), + ), + array( + 'type' => 'textarea', + 'label' => $this->l('AJAX Show Category Qty - Code'), + 'name' => 'APPAGEBUILDER_LOAD_TPN', + 'cols' => 100, + 'hint' => $this->l('Add this CODE to THEME_NAME/modules/ps_categorytree/views/templates/hook/ ps_categorytree.tpl file'), + ), + array( + 'type' => 'switch', + 'label' => $this->l('AJAX Show More Product Image - Enable'), + 'name' => 'APPAGEBUILDER_LOAD_TRAN', + 'default' => 0, + 'values' => ApPageSetting::returnYesNo(), + ), + array( + 'type' => 'textarea', + 'label' => $this->l('AJAX Show More Product Image - Code'), + 'name' => 'APPAGEBUILDER_LOAD_TTRAN', + 'cols' => 100, + 'hint' => $this->l('Add this CODE to THEME_NAME/templates/catalog/_partials/miniatures/product.tpl file'), + ), + array( + 'type' => 'switch', + 'label' => $this->l('AJAX Show Multiple Product Images - Enable'), + 'name' => 'APPAGEBUILDER_LOAD_IMG', + 'default' => 0, + 'values' => ApPageSetting::returnYesNo(), + ), + array( + 'type' => 'textarea', +// 'label' => $this->l('You can add this code in tpl file of module you want to show Multiple Product Image'), + 'label' => $this->l('AJAX Show Multiple Product Images - Code'), + 'name' => 'APPAGEBUILDER_LOAD_TIMG', + 'cols' => 100, + 'hint' => $this->l('Add this CODE to THEME_NAME/templates/catalog/_partials/miniatures/product.tpl file'), + ), + array( + 'type' => 'switch', + 'label' => $this->l('AJAX Show Count Down Product - Enable'), + 'name' => 'APPAGEBUILDER_LOAD_COUNT', + 'default' => 0, + 'values' => ApPageSetting::returnYesNo(), + ), + array( + 'type' => 'textarea', + 'label' => $this->l('AJAX Show Count Down Product - Code'), + 'name' => 'APPAGEBUILDER_LOAD_TCOUNT', + 'cols' => 100, + 'hint' => $this->l('Add this CODE to THEME_NAME/templates/catalog/_partials/miniatures/product.tpl file'), + ), +// array( +// 'type' => 'switch', +// 'label' => $this->l('Show Discount Color'), +// 'name' => 'APPAGEBUILDER_LOAD_ACOLOR', +// 'default' => 1, +// 'values' => ApPageSetting::returnYesNo(), +// ), +// array( +// 'type' => 'textarea', +// 'label' => $this->l('You can add this code in tpl file of module you want to show color discount'), +// 'name' => 'APPAGEBUILDER_LOAD_TCOLOR', +// 'cols' => 100, +// ), +// array( +// 'type' => 'textarea', +// 'label' => $this->l('For color (Ex: 10:#ff0000,20:#152ddb,40:#ffee001) '), +// 'name' => 'APPAGEBUILDER_LOAD_COLOR', +// 'cols' => 100 +// ), +// array( +// 'type' => 'textarea', +// 'label' => $this->l('If you want my script run fine with Layered navigation block. +// Please copy to override file modules/blocklayered/blocklayered.js to folder +// themes/TEMPLATE_NAME/js/modules/blocklayered/blocklayered.js. +// Then find function reloadContent(params_plus).'), +// 'name' => 'APPAGEBUILDER_LOAD_RTN', +// 'cols' => 100 +// ), +// array( +// 'type' => 'textarea', +// 'label' => $this->l('For color (Ex: 10:#ff0000,20:#152ddb,40:#ffee001)'), +// 'name' => 'APPAGEBUILDER_COLOR', +// 'default' => '', +// 'cols' => 100 +// ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'name' => 'dump_name', + 'html_content' => '
' + .$this->l('Setting hook in positions (This setting will apply for all profiles).') + .'
'.$this->l('Default all hooks: [').$list_all_hooks.' ]
' + .'
', + ), + array( + 'type' => 'text', + 'label' => $this->l('Hooks in header'), + 'name' => 'APPAGEBUILDER_HEADER_HOOK', + 'class' => '', + 'default' => $list_header_hooks + ), + array( + 'type' => 'text', + 'label' => $this->l('Hooks in content'), + 'name' => 'APPAGEBUILDER_CONTENT_HOOK', + 'class' => '', + 'default' => $list_content_hooks + ), + array( + 'type' => 'text', + 'label' => $this->l('Hooks in footer'), + 'name' => 'APPAGEBUILDER_FOOTER_HOOK', + 'class' => '', + 'default' => $list_footer_hooks + ), + array( + 'type' => 'text', + 'label' => $this->l('Hooks in product-footer'), + 'name' => 'APPAGEBUILDER_PRODUCT_HOOK', + 'class' => '', + 'default' => $list_product_hooks + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'name' => 'html_content_de', + 'html_content' => ' + + + + + ', + ), + ), + 'submit' => array( + 'id' => 'btn-save-appagebuilder', + 'title' => $this->l('Save'), + ) + ); + + $form_extrafield = array( + + 'legend' => array( + 'title' => $this->l('Extrafield Settings'), + 'icon' => 'icon-cogs' + ), + 'input' => array( + array( + 'type' => 'html', + 'name' => 'default_html', + 'name' => 'dump_name', + 'html_content' => '
' + .$this->l('This config is only apply for advance user.') + .'
We will create new fileds for category and product, then you can use it to show in layout
' + .'
Have 2 type of database: 1. text and 2. editor
' + .'
When you change data of this field, all data of extrafied will lost
' + .'
', + ), + array( + 'type' => 'text', + 'label' => $this->l('Product Extra Text Field'), + 'name' => 'APPAGEBUILDER_PRODUCT_TEXTEXTRA', + 'class' => '', + 'desc' => $this->l('Do not contain space and special charactor. Example: sub-name, sub-title'), + 'default' => '' + ), + array( + 'type' => 'text', + 'label' => $this->l('Product Extra Editor Field'), + 'name' => 'APPAGEBUILDER_PRODUCT_EDITOREXTRA', + 'class' => '', + 'desc' => $this->l('Do not contain space and special charactor. Example: sub-name, sub-title'), + 'default' => '' + ), + array( + 'type' => 'text', + 'label' => $this->l('Category Extra Editor Field'), + 'name' => 'APPAGEBUILDER_CATEGORY_TEXTEXTRA', + 'class' => '', + 'desc' => $this->l('Do not contain space and special charactor. Example: sub-name, sub-title'), + 'default' => '' + ), + array( + 'type' => 'text', + 'label' => $this->l('Category Extra Editor Field'), + 'name' => 'APPAGEBUILDER_CATEGORY_EDITOREXTRA', + 'class' => '', + 'desc' => $this->l('Do not contain space and special charactor. Example: sub-name, sub-title'), + 'default' => '' + ) + ), + 'submit' => array( + 'id' => 'btn-save-extrafield', + 'title' => $this->l('Save'), + ) + ); + $fields_form = array( + 'form' => $form_general + ); + $fields_form1 = array( + 'form' => $form_extrafield + ); + $data = $this->getConfigFieldsValues($form_general, $form_extrafield); + // Check existed the folder root store resources of module + $path_img = apPageHelper::getImgThemeDir(); + if (!file_exists($path_img)) { + mkdir($path_img, 0755, true); + } + $helper = new HelperForm(); + $helper->show_toolbar = false; + $helper->table = $this->table; + $lang = new Language((int)Configuration::get('PS_LANG_DEFAULT')); + $helper->default_form_language = $lang->id; + $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? + Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0; + $helper->identifier = $this->identifier; + $helper->submit_action = 'submitApPageBuilder'; + $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false) + .'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name; + $helper->token = Tools::getAdminTokenLite('AdminModules'); + $helper->tpl_vars = array( + 'fields_value' => $data, + 'languages' => $this->context->controller->getLanguages(), + 'id_language' => $this->context->language->id + ); + return $helper->generateForm(array($fields_form, $fields_form1)); + } + + private function renderListAllHook($arr) + { + $html = ''; + if ($arr) { + foreach ($arr as $item) { + $html .= "$item"; + } + } + return $html; + } + + public function hookPagebuilderConfig($param) + { + $cf = $param['configName']; + if ($cf == 'profile' || $cf == 'header' || $cf == 'footer' || $cf == 'content' || $cf == 'product' || $cf == 'product_builder') { + #GET DETAIL PROFILE + $cache_name = 'pagebuilderConfig'.'|'.$param['configName']; + $cache_id = $this->getCacheId($cache_name); + if (!$this->isCached('module:appagebuilder/views/templates/hook/config.tpl', $cache_id)) { + $ap_type = $cf; + + if ($cf == 'profile') { + $ap_type = 'id_appagebuilder_profiles'; + } else if ($cf == 'product_builder') { + $ap_type = 'plist_key'; + } + $this->smarty->assign( + array( + 'ap_cfdata' => $this->getConfigData($cf), + 'ap_cf' => $cf, + 'ap_type' => $ap_type, + 'ap_controller' => apPageHelper::getPageName(), + 'ap_current_url' => Context::getContext()->link->getPageLink('index', true), + ) + ); + } + return $this->display(__FILE__, 'config.tpl', $cache_id); + } + + if (!$this->product_active) { + $this->product_active = ApPageBuilderProductsModel::getActive(); + } + if ($cf == 'productClass') { + // validate module + return $this->product_active['class']; + } + if ($cf == 'productKey') { + $tpl_file = apPageHelper::getConfigDir('theme_profiles') . $this->product_active['plist_key'].'.tpl'; + if (is_file($tpl_file)) { + return $this->product_active['plist_key']; + } + return; + } + //nghiatd + if ($cf == 'productLayout') { + $id_product = Tools::getValue('id_product'); + if ($id_product) { + $id_shop = Context::getContext()->shop->id; + $sql = 'SELECT page from `'._DB_PREFIX_.'appagebuilder_page` where id_product = \''.(int)$id_product.'\' AND id_shop = \''.(int)$id_shop.'\''; + $layout = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql); + return $layout; + } else { + return ''; + } + } + if ($cf == 'categoryLayout') { + $id_category = Tools::getValue('id_category'); + if ($id_category) { + $id_shop = Context::getContext()->shop->id; + $sql = 'SELECT page from `'._DB_PREFIX_.'appagebuilder_page` where id_category = \''.(int)$id_category.'\' AND id_shop = \''.(int)$id_shop.'\''; + $layout = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql); + return $layout; + } else { + return ''; + } + } + //DONGND:: get class of category layout + if ($cf == 'classCategoryLayout') { + $id_category = Tools::getValue('id_category'); + if ($id_category) { + $id_shop = Context::getContext()->shop->id; + $sql = 'SELECT pr.`class` from `'._DB_PREFIX_.'appagebuilder_page` pa INNER JOIN `'._DB_PREFIX_.'appagebuilder_products` pr ON (pa.`page` = pr.`plist_key`) where pa.id_category = \''.(int)$id_category.'\' AND pa.id_shop = \''.(int)$id_shop.'\''; + $class_category_layout = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql); + return $class_category_layout; + } else { + return ''; + } + } + } + + public function getConfigData($cf) + { + if ($cf == 'profile') { + $id_lang = (int)Context::getContext()->language->id; + $sql = 'SELECT p.`id_appagebuilder_profiles` AS `id`, p.`name`, ps.`active`, pl.friendly_url FROM `'._DB_PREFIX_.'appagebuilder_profiles` p ' + .' INNER JOIN `'._DB_PREFIX_.'appagebuilder_profiles_shop` ps ON (ps.`id_appagebuilder_profiles` = p.`id_appagebuilder_profiles`)' + .' INNER JOIN `'._DB_PREFIX_.'appagebuilder_profiles_lang` pl ON (pl.`id_appagebuilder_profiles` = p.`id_appagebuilder_profiles`) AND pl.id_lang='.(int)$id_lang + .' WHERE ps.id_shop='.(int)Context::getContext()->shop->id; + } else if ($cf == 'product_builder') { + $sql = 'SELECT p.`plist_key` AS `id`, p.`name`, ps.`active`' + .' FROM `'._DB_PREFIX_.'appagebuilder_products` p ' + .' INNER JOIN `'._DB_PREFIX_.'appagebuilder_products_shop` ps ' + .' ON (ps.`id_appagebuilder_products` = p.`id_appagebuilder_products`)' + .' WHERE ps.id_shop='.(int)Context::getContext()->shop->id; + } else { + $sql = 'SELECT p.`id_appagebuilder_positions` AS `id`, p.`name`' + .' FROM `'._DB_PREFIX_.'appagebuilder_positions` p ' + .' INNER JOIN `'._DB_PREFIX_.'appagebuilder_positions_shop` ps ' + .' ON (ps.`id_appagebuilder_positions` = p.`id_appagebuilder_positions`)' + .' WHERE p.`position` = \''.PSQL($cf).'\' AND ps.id_shop='.(int)Context::getContext()->shop->id; + } + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); + foreach ($result as &$val) { + if ($cf == 'profile') { + $val['active'] = 0; + if ($val['id'] == $this->profile_data['id_appagebuilder_profiles']) { + $val['active'] = 1; + } + } else if ($cf == 'product_builder') { + if (Tools::getIsset('plist_key')) { + $val['active'] = 0; + if ($val['id'] == Tools::getValue('plist_key')) { + $val['active'] = 1; + } + } + } else { + $val['active'] = 0; + if (Tools::getIsset($cf)) { + if ($val['id'] == Tools::getValue($cf)) { + $val['active'] = 1; + } + } else { + if ($val['id'] == $this->profile_data[$cf]) { + $val['active'] = 1; + } + } + } + } + return $result; + } + + public function getConfigFieldsValues($form_general, $form_extrafield) + { + $this->context->controller->addCss(apPageHelper::getCssDir().'style.css'); + $result = array(); + + foreach ($form_general['input'] as $form) { + //$form['name'] = isset($form['name']) ? $form['name'] : ''; + if (Configuration::hasKey($form['name'])) { + $result[$form['name']] = Tools::getValue($form['name'], Configuration::get($form['name'])); + } else { + $result[$form['name']] = Tools::getValue($form['name'], isset($form['default']) ? $form['default'] : ''); + } + } + + foreach ($form_extrafield['input'] as $form) { + //$form['name'] = isset($form['name']) ? $form['name'] : ''; + if (Configuration::hasKey($form['name'])) { + $result[$form['name']] = Configuration::get($form['name']); + } else { + $result[$form['name']] = Tools::getValue($form['name'], isset($form['default']) ? $form['default'] : ''); + } + } + + $result['APPAGEBUILDER_LOAD_TCOUNT'] = '
'; + $result['APPAGEBUILDER_LOAD_TTRAN'] = ''; + $result['APPAGEBUILDER_LOAD_TIMG'] = '
'; + $result['APPAGEBUILDER_LOAD_TPN'] = ''; + + return $result; + } + + /** + * Widget ApTab + */ + public function fontContent($assign, $tpl_name) + { + // Setting live edit mode + $assign['apLiveEdit'] = ''; + $assign['apLiveEditEnd'] = ''; + $is_live = Tools::getIsset('ap_live_edit') ? Tools::getValue('ap_live_edit') : ''; + if ($is_live) { + $live_token = Tools::getIsset('liveToken') ? Tools::getValue('liveToken') : ''; + if (!$this->checkLiveEditAccess($live_token)) { + Tools::redirect('index.php?controller=404'); + } + $cookie = new Cookie('url_live_back'); + $url_edit_profile = $cookie->variable_name; + + $id_profile = ApPageBuilderProfilesModel::getIdProfileFromRewrite(); + $cookie = new Cookie('ap_id_profile'); + if (!$id_profile) { + if ($cookie->variable_name) { + $url_edit_profile .= '&id_appagebuilder_profiles='.$cookie->variable_name; + } + } else { + $id_profile = ''; + // Restor id_profile to cookie + $cookie = new Cookie('ap_id_profile'); + $cookie->setExpire(time() + 60 * 60); + $cookie->variable_name = $id_profile; + $cookie->write(); + $url_edit_profile .= '&id_appagebuilder_profiles='.$id_profile; + } + $assign['urlEditProfile'] = $url_edit_profile; + $assign['isLive'] = $is_live; + $assign['apLiveEdit'] = '
Edit'; + $assign['apLiveEditEnd'] = '
'; + } + + if ($assign) { + foreach ($assign as $key => $ass) { + $this->smarty->assign(array($key => $ass)); + } + } + $override_folder = ''; + if (isset($assign['formAtts']['override_folder']) && $assign['formAtts']['override_folder'] != '') + { + $override_folder = $assign['formAtts']['override_folder']; + } + $tpl_file = apPageHelper::getTemplate($tpl_name, $override_folder); + $content = $this->display(__FILE__, $tpl_file); + return $content; + } + + public function checkLiveEditAccess($live_token) + { + $cookie = new Cookie('ap_token'); + return $live_token === $cookie->variable_name; + } + + /** + * $page_number = 0, $nb_products = 10, $count = false, $order_by = null, $order_way = null + */ + public function getProductsFont($params) + { + $id_lang = $this->context->language->id; + $context = Context::getContext(); + //assign value from params + $p = isset($params['page_number']) ? $params['page_number'] : 1; + if ($p < 0) { + $p = 1; + } + $n = isset($params['nb_products']) ? $params['nb_products'] : 10; + if ($n < 1) { + $n = 10; + } + $order_by = isset($params['order_by']) ? Tools::strtolower($params['order_by']) : 'position'; + $order_way = isset($params['order_way']) ? $params['order_way'] : 'ASC'; + $random = false; + if ($order_way == 'random') { + $random = true; + } + $get_total = isset($params['get_total']) ? $params['get_total'] : false; + $order_by_prefix = false; + if ($order_by == 'id_product' || $order_by == 'date_add' || $order_by == 'date_upd') { + $order_by_prefix = 'product_shop'; + } else if ($order_by == 'reference') { + $order_by_prefix = 'p'; + } else if ($order_by == 'name') { + $order_by_prefix = 'pl'; + } elseif ($order_by == 'manufacturer') { + $order_by_prefix = 'm'; + $order_by = 'name'; + } elseif ($order_by == 'position') { + $order_by = 'date_add'; + $order_by_prefix = 'product_shop'; +// $order_by_prefix = 'cp'; + } + if ($order_by == 'price') { + $order_by = 'orderprice'; + } + $active = 1; + if (!Validate::isBool($active) || !Validate::isOrderBy($order_by)) { + die(Tools::displayError()); + } + //build where + $where = ''; + $sql_join = ''; + $sql_group = ''; + + $value_by_categories = isset($params['value_by_categories']) ? $params['value_by_categories'] : 0; + if ($value_by_categories) { + $id_categories = isset($params['categorybox']) ? $params['categorybox'] : ''; + $id_categories = apPageHelper::addonValidInt( $id_categories ); # We validate id_categories in apPageHelper::addonValidInt function . This function is used at any where + + if (isset($params['category_type']) && $params['category_type'] == 'default') { + $where .= ' AND product_shop.`id_category_default` IN ('.pSQL($id_categories).')'; + } else { + $sql_join .= ' INNER JOIN '._DB_PREFIX_.'category_product cp ON (cp.id_product= p.`id_product` )'; + + $where .= ' AND cp.`id_category` IN ('.pSQL($id_categories).')'; + $sql_group = ' GROUP BY p.id_product'; + } + } + $value_by_supplier = isset($params['value_by_supplier']) ? $params['value_by_supplier'] : 0; + if ($value_by_supplier && isset($params['supplier'])) { + $id_suppliers = apPageHelper::addonValidInt( $params['supplier'] ); # We validate id_categories in apPageHelper::addonValidInt function. This function is used at any where + $where .= ' AND p.id_supplier IN ('.pSQL($id_suppliers).')'; + } + $value_by_product_id = isset($params['value_by_product_id']) ? $params['value_by_product_id'] : 0; + if ($value_by_product_id && isset($params['product_id'])) { + $temp = explode(',', $params['product_id']); + foreach ($temp as $key => $value) { + // validate module + $temp[$key] = (int)$value; + } + + $product_id = implode(',', array_map('intval', $temp)); + $where .= ' AND p.id_product '.(strpos($product_id, ',') === false ? '= '.(int)$product_id : 'IN ('.pSQL($product_id).')'); + } + + $value_by_manufacture = isset($params['value_by_manufacture']) ? $params['value_by_manufacture'] : 0; + if ($value_by_manufacture && isset($params['manufacture'])) { + $id_manufactures = apPageHelper::addonValidInt( $params['manufacture'] ); # We validate id_categories in apPageHelper::addonValidInt function. This function is used at any where + $where .= ' AND p.id_manufacturer IN ('.pSQL($id_manufactures).')'; + } + $product_type = isset($params['product_type']) ? $params['product_type'] : ''; + $value_by_product_type = isset($params['value_by_product_type']) ? $params['value_by_product_type'] : 0; + if ($value_by_product_type && $product_type == 'new_product') { + $where .= ' AND product_shop.`date_add` > "'.date('Y-m-d', strtotime('-'.(Configuration::get('PS_NB_DAYS_NEW_PRODUCT') ? + (int)Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY')).'"'; + } + //home feature + if ($value_by_product_type && $product_type == 'home_featured') { + $ids = array(); + $category = new Category(Context::getContext()->shop->getCategory(), (int)Context::getContext()->language->id); + $result = $category->getProducts((int)Context::getContext()->language->id, 1, $n*($p+1), 'position'); // Load more product $n*$p, hidden + foreach ($result as $product) { + $ids[$product['id_product']] = 1; + } + $ids = array_keys($ids); + sort($ids); + $ids = count($ids) > 0 ? implode(',', $ids) : 'NULL'; + $where .= ' AND p.`id_product` IN ('.$ids.')'; + } + //special or price drop + if ($value_by_product_type && $product_type == 'price_drop') { + $current_date = date('Y-m-d H:i:s'); + $id_address = $context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}; + $ids = Address::getCountryAndState($id_address); + $id_country = $ids['id_country'] ? $ids['id_country'] : Configuration::get('PS_COUNTRY_DEFAULT'); + $id_country = (int)$id_country; + $ids_product = SpecificPrice::getProductIdByDate($context->shop->id, $context->currency->id, $id_country, $context->customer->id_default_group, $current_date, $current_date, 0, false); + $tab_id_product = array(); + foreach ($ids_product as $product) { + if (is_array($product)) { + $tab_id_product[] = (int)$product['id_product']; + } else { + $tab_id_product[] = (int)$product; + } + } + $where .= ' AND p.`id_product` IN ('.((is_array($tab_id_product) && count($tab_id_product)) ? implode(', ', $tab_id_product) : 0).')'; + } + + $sql = 'SELECT p.*, product_shop.*, p.`reference`, stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity, + product_attribute_shop.id_product_attribute, + product_attribute_shop.minimal_quantity AS product_attribute_minimal_quantity, + pl.`description`, pl.`description_short`, pl.`available_now`, + pl.`available_later`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, + image_shop.`id_image`, + il.`legend`, m.`name` AS manufacturer_name, cl.`name` AS category_default, + DATEDIFF(product_shop.`date_add`, DATE_SUB(NOW(), + INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? (int)Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' + DAY)) > 0 AS new, product_shop.price AS orderprice'; + + if ($value_by_product_type && $product_type == 'best_sellers') { + $sql .= ' FROM `'._DB_PREFIX_.'product_sale` ps'; + $sql .= ' LEFT JOIN `'._DB_PREFIX_.'product` p ON ps.`id_product` = p.`id_product`'; + } else { + $sql .= ' FROM `'._DB_PREFIX_.'product` p'; + } + + $sql .= ' INNER JOIN '._DB_PREFIX_.'product_shop product_shop ON (product_shop.id_product = p.id_product AND product_shop.id_shop = '.(int)$context->shop->id.') + LEFT JOIN '._DB_PREFIX_.'product_attribute_shop product_attribute_shop ON p.`id_product` = product_attribute_shop.`id_product` AND product_attribute_shop.`default_on` = 1 AND product_attribute_shop.id_shop='.(int)$context->shop->id.' + '.ProductCore::sqlStock('p', 'product_attribute_shop', false, $context->shop).' + LEFT JOIN '._DB_PREFIX_.'category_lang cl ON (product_shop.`id_category_default` = cl.`id_category` AND cl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('cl').') + LEFT JOIN '._DB_PREFIX_.'product_lang pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').') + LEFT JOIN '._DB_PREFIX_.'image_shop image_shop ON (image_shop.id_product = p.id_product AND image_shop.id_shop = '.(int)$context->shop->id.' AND image_shop.cover=1) + LEFT JOIN '._DB_PREFIX_.'image_lang il ON (image_shop.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.') + LEFT JOIN '._DB_PREFIX_.'manufacturer m ON m.`id_manufacturer` = p.`id_manufacturer`'; + $sql .= $sql_join; + + $sql .= ' WHERE product_shop.`id_shop` = '.(int)$context->shop->id.' + AND product_shop.`active` = 1 + AND product_shop.`visibility` IN ("both", "catalog")' + .$where; + + $sql .= $sql_group; + + if ($random === true) { + // $sql .= ' ORDER BY product_shop.date_add '.(!$get_total ? ' LIMIT '.(int)$n : ''); + $sql .= ' ORDER BY RAND() '.(!$get_total ? ' LIMIT '.(int)$n : ''); + } else { + $order_way = Validate::isOrderWay($order_way) ? Tools::strtoupper($order_way) : 'ASC'; // $order_way Validate::isOrderWay() + $sql .= ' ORDER BY '.(!empty($order_by_prefix) ? '`'.pSQL($order_by_prefix).'`.' : '').'`'.bqSQL($order_by).'` '.pSQL($order_way) + .(!$get_total ? ' LIMIT '.(((int)$p - 1) * (int)$n).','.(int)$n : ''); + } + + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); + + if ($order_by == 'orderprice') { + Tools::orderbyPrice($result, $order_way); + } + if (!$result) { + return array(); + } + /* Modify SQL result */ + $this->context->controller->addColorsToProductList($result); + return Product::getProductsProperties($id_lang, $result); + } + + //DONGND:: register hook back-end + public function hookActionAdminControllerSetMedia() + { + Media::addJsDef( + array( + 'appagebuilder_module_dir' => $this->_path, + 'appagebuilder_listshortcode_url' => $this->context->link->getAdminLink('AdminApPageBuilderShortcode').'&get_listshortcode=1', + ) + ); + Configuration::updateValue('shortcode_url_add', $this->context->link->getAdminLink('AdminApPageBuilderShortcode')); + + $this->autoRestoreSampleData(); + } + + public function hookdisplayHeader() + { + apPageHelper::autoUpdateModule(); + + if ( Tools::getIsset('leo_support_team') && (int)Tools::getValue('leo_support_team') == 1) { + Configuration::updateValue('LEO_SUPPORT_TEAM', '1'); + die('update'); + }elseif( Tools::getIsset('leo_support_team') && (int)Tools::getValue('leo_support_team') == 0){ + Configuration::updateValue('LEO_SUPPORT_TEAM', '0'); + die('update'); + } + + if (isset(Context::getContext()->controller->controller_type) && in_array(Context::getContext()->controller->controller_type, array('front', 'modulefront'))) { + # WORK AT FRONTEND + apPageHelper::loadShortCode(_PS_THEME_DIR_); + + $this->profile_data = ApPageBuilderProfilesModel::getActiveProfile('index'); + $this->profile_param = Tools::jsonDecode($this->profile_data['params'], true); + $this->setFullwidthHook(); + + # FIX 1.7 + apPageHelper::setGlobalVariable($this->context); + } + + + if (Configuration::get('APPAGEBUILDER_LOAD_WAYPOINTS')) { + $uri = apPageHelper::getCssDir().'animate.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + + $uri = apPageHelper::getJsDir().'waypoints.min.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 8000)); + } + if (Configuration::get('APPAGEBUILDER_LOAD_INSTAFEED')) { + $uri = apPageHelper::getJsDir().'instafeed.min.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 8000)); + } + if (Configuration::get('APPAGEBUILDER_LOAD_STELLAR')) { + $uri = apPageHelper::getJsDir().'jquery.stellar.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 8000)); + } + if (Configuration::get('APPAGEBUILDER_LOAD_OWL')) { + $uri = apPageHelper::getCssDir().'owl.carousel.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + $uri = apPageHelper::getCssDir().'owl.theme.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + + $uri = apPageHelper::getJsDir().'owl.carousel.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 8000)); + } + + if (Configuration::get('APPAGEBUILDER_LOAD_SWIPER')) { + $uri = apPageHelper::getCssDir().'swiper.min.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + + $uri = apPageHelper::getJsDir().'swiper.min.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 8000)); + } + + //DONGND:: add jquery plugin images loaded + $uri = apPageHelper::getJsDir().'imagesloaded.pkgd.min.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 8000)); + + //slick + $uri = apPageHelper::getJsDir().'slick.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 8000)); + + $uri = apPageHelper::getCssDir().'slick-theme.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + + $uri = apPageHelper::getCssDir().'slick.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + + // zoom + if (Configuration::get('APPAGEBUILDER_LOAD_PRODUCTZOOM')) { + $uri = apPageHelper::getJsDir().'jquery.elevateZoom-3.0.8.min.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 8000)); + } + + $product_list_image = Configuration::get('APPAGEBUILDER_LOAD_IMG'); + $product_one_img = Configuration::get('APPAGEBUILDER_LOAD_TRAN'); + $category_qty = Configuration::get('APPAGEBUILDER_LOAD_PN'); + $productCdown = Configuration::get('APPAGEBUILDER_LOAD_COUNT'); +// $productColor = Configuration::get('APPAGEBUILDER_LOAD_ACOLOR'); + $productColor = false; + $ajax_enable = $product_list_image || $product_one_img || $category_qty || $productCdown || $productColor; + $this->smarty->assign(array( + 'ajax_enable' => $ajax_enable, + 'product_list_image' => $product_list_image, + 'product_one_img' => $product_one_img, + 'category_qty' => $category_qty, + 'productCdown' => $productCdown, + 'productColor' => $productColor + )); + $this->context->controller->addJqueryPlugin('fancybox'); + if ($productCdown) { + $uri = apPageHelper::getJsDir().'countdown.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 80)); + } + if ($product_list_image) { + $this->context->controller->addJqueryPlugin(array('scrollTo', 'serialScroll')); + } + + // add js for html5 youtube video + if (Configuration::get('APPAGEBUILDER_LOAD_HTML5VIDEO')) { + $uri = apPageHelper::getCssDir().'mediaelementplayer.min.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + + $uri = apPageHelper::getJsDir().'mediaelement-and-player.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 8000)); + } + //add js,css for full page js + if (Configuration::get('APPAGEBUILDER_LOAD_FULLPAGEJS')) { + $uri = apPageHelper::getCssDir().'jquery.fullPage.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + + $uri = apPageHelper::getJsDir().'jquery.fullPage.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 8000)); + } + // add js, css for Image360 + if (Configuration::get('APPAGEBUILDER_LOAD_IMAGE360')) { + $uri = apPageHelper::getCssDir().'ApImage360.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + + $uri = apPageHelper::getJsDir().'ApImage360.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 8000)); + $this->context->controller->addJqueryUI('ui.slider'); + } + // add js, css for ImageHotPot + if (Configuration::get('APPAGEBUILDER_LOAD_IMAGEHOTPOT')) { + $uri = apPageHelper::getCssDir().'ApImageHotspot.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + + $uri = apPageHelper::getJsDir().'ApImageHotspot.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 8000)); + } + // add js Cookie : jquery.cooki-plugin.js + if (Configuration::get('APPAGEBUILDER_LOAD_COOKIE')) { + $this->context->controller->addJqueryPlugin('cooki-plugin'); + } + + $uri = apPageHelper::getCssDir().'styles.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + + //DONGND:: add unique css file, css of module for all theme, no need override + $uri = apPageHelper::getCssDir().'unique.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + + $uri = apPageHelper::getJsDir().'script.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 8000)); + if (!$this->product_active) { + $this->product_active = ApPageBuilderProductsModel::getActive(); + } + $this->smarty->smarty->assign(array('productClassWidget' => $this->product_active['class'])); + + $tpl_file = apPageHelper::getConfigDir('theme_profiles') . $this->product_active['plist_key'].'.tpl'; + + if (is_file($tpl_file)) { + $this->smarty->smarty->assign(array('productProfileDefault' => $this->product_active['plist_key'])); + } + // In the case not exist: create new cache file for template + if (!$this->isCached('module:appagebuilder/views/templates/hook/header.tpl', $this->getCacheId('displayHeader'))) { + if (!$this->hook_index_data) { + $model = new ApPageBuilderModel(); + $this->hook_index_data = $model->getAllItems($this->profile_data, 1, $this->default_language['id_lang']); + } + $this->smarty->assign(array( + 'homeSize' => Image::getSize(ImageType::getFormattedName('home')), + 'mediumSize' => Image::getSize(ImageType::getFormattedName('medium')) + )); + } + + # LEOTEMCP + $isRTL = $this->context->language->is_rtl; + $leoRTL = $this->context->language->is_rtl; + if ($leoRTL && version_compare(Configuration::get('PS_VERSION_DB'), '1.7.3.0', '>=')) { + $directory = _PS_ALL_THEMES_DIR_._THEME_NAME_; + $allFiles = Tools::scandir($directory, 'css', '', true); + $rtl_file = false; + foreach ($allFiles as $key => $file) { + if (Tools::substr(rtrim($file, '.css'), -4) == '_rtl') { + $rtl_file = true; + break; + } + } + + if ($rtl_file) { + $leoRTL = false; // to remove class RTL +// $this->context->controller->unregisterStylesheet('theme-rtl'); + @unlink(_PS_ALL_THEMES_DIR_._THEME_NAME_.'/assets/css/rtl_rtl.css'); // Remove file rtl_rtl.css + $this->context->controller->registerStylesheet('theme-rtl', '/assets/css/rtl.css', array('media' => 'all', 'priority' => 900)); + } + } +// $id_shop = $this->context->shop->id; +// $helper = LeoFrameworkHelper::getInstance(); + + $this->themeCookieName = $this->getConfigName('PANEL_CONFIG'); + $panelTool = $this->getConfig('PANELTOOL'); + $backGroundValue = ''; + + //DONGND:: get product detail layout + $list_productdetail_layout = array(); + + if ($panelTool) { + # ENABLE PANEL TOOL + $uri = apPageHelper::getCssDir().'colorpicker/css/colorpicker.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + $uri = apPageHelper::getCssDir().'paneltool.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + + $uri = apPageHelper::getJsDir().'colorpicker/js/colorpicker.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 8000)); + $uri = apPageHelper::getJsDir().'paneltool.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 8000)); + $this->context->controller->addJqueryPlugin('cooki-plugin'); + + $skin = $this->getPanelConfig('default_skin'); + $layout_mode = $this->getPanelConfig('layout_mode'); + $enable_fheader = (int)$this->getPanelConfig('enable_fheader'); + + $backGroundValue = array( + 'attachment' => array('scroll', 'fixed', 'local', 'initial', 'inherit'), + 'repeat' => array('repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'initial', 'inherit'), + 'position' => array('left top', 'left center', 'left bottom', 'right top', 'right center', 'right bottom', 'center top', 'center center', 'center bottom') + ); + + //DONGND:: check table exist + $check_table = Db::getInstance()->executeS('SELECT table_name FROM INFORMATION_SCHEMA.tables WHERE TABLE_SCHEMA = "'._DB_NAME_.'" AND TABLE_NAME = "'._DB_PREFIX_.'appagebuilder_details"'); + + if (count($check_table) > 0) { + if (Tools::getValue('id_product')) { + $id_product = Tools::getValue('id_product'); + } else { + $sql = 'SELECT p.`id_product` + FROM `'._DB_PREFIX_.'product` p + '.Shop::addSqlAssociation('product', 'p').' + AND product_shop.`visibility` IN ("both", "catalog") + AND product_shop.`active` = 1 + ORDER BY p.`id_product` ASC'; + $first_product = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql); + $id_product = $first_product['id_product']; + } + $sql = 'SELECT a.* + FROM `'._DB_PREFIX_.'appagebuilder_details` as a + INNER JOIN `'._DB_PREFIX_.'appagebuilder_details_shop` ps ON (ps.`id_appagebuilder_details` = a.`id_appagebuilder_details`) WHERE ps.id_shop='.(int)$this->context->shop->id; + $list_productdetail = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); + + if ($id_product && count($list_productdetail) > 1) { + foreach ($list_productdetail as $key => $list_productdetail_item) { + $product_layout_link = ''; + $product_layout_link = $this->context->link->getProductLink($id_product, null, null, null, null, null, (int)Product::getDefaultAttribute((int)$id_product)); + $product_layout_link = str_replace('.html', '.html?layout='.$list_productdetail_item['plist_key'], $product_layout_link); + $list_productdetail[$key]['product_layout_link'] = $product_layout_link; + } + $list_productdetail_layout = $list_productdetail; + } + } + } else { + $skin = $this->getConfig('default_skin'); + $layout_mode = $this->getConfig('layout_mode'); + $enable_fheader = $this->getConfig('enable_fheader'); + if (apPageHelper::getPageName() == 'category') { + $this->context->controller->addJqueryPlugin('cooki-plugin'); + } + } + +// if ($this->getConfig('ENABLE_CUSTOMFONT')) { +// # CUSTOM FONT +// $uri = apPageHelper::getCssDir().'fonts-cuttom.css'; +// $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); +// } + if ($this->getConfig('ENABLE_LOADFONT')) { + # CUSTOM FONT + $uri = apPageHelper::getCssDir().'fonts-cuttom2.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + } + + $layout_width_val = ''; + $layout_width = $this->getConfig('layout_width'); + if (trim($layout_width) != 'auto' && trim($layout_width) != '') { + $layout_width = (int)$layout_width; + $layout_width_val = ''; + if (is_numeric($layout_width)) { + # validate module + $layout_width_val .= ''; + } + } + + $load_css_type = $this->getConfig('load_css_type'); + $css_skin = array(); + $css_custom = array(); + if ($load_css_type) { + # Load Css With Prestashop Standard - YES + if (!$this->getConfig('enable_responsive')) { + $uri = apPageHelper::getCssDir().'non-responsive.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + } + + # LOAD SKIN CSS IN MODULE + $uri = apPageHelper::getCssDir().'skins/'.$skin.'/skin.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + $uri = apPageHelper::getCssDir().'skins/'.$skin.'/custom-rtl.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + + # LOAD CUSTOM CSS + if ($this->context->getMobileDevice() != false && !$this->getConfig('enable_responsive')) { + $uri = apPageHelper::getCssDir().'mobile.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + } + + # LOAD POSITIONS AND PROFILES + $this->loadResouceForProfile(); + + # LOAD PATTERN + if ($profile = $this->getConfig('c_profile')) { + $uri = apPageHelper::getCssDir().'patterns/'.$profile.'.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + } + } else { + # Load Css With Prestashop Standard - NO + if (!$this->getConfig('enable_responsive')) { + $uri = apPageHelper::getCssDir().'non-responsive.css'; + $skinFileUrl = apPageHelper::getFullPathCss($uri); + if ($skinFileUrl !== false) { + $css_skin[] = ''; + } + } + + # LOAD SKIN CSS IN TPL + $uri = apPageHelper::getCssDir().'skins/'.$skin.'/skin.css'; + $skinFileUrl = apPageHelper::getFullPathCss($uri); + if ($skinFileUrl !== false) { + $css_skin[] = ''; + } + $uri = apPageHelper::getCssDir().'skins/'.$skin.'/custom-rtl.css'; + $skinFileUrl = apPageHelper::getFullPathCss($uri); + if ($leoRTL && $skinFileUrl !== false) { + $css_skin[] = ''; + } + + # LOAD CUSTOM CSS + if ($this->context->getMobileDevice() != false && !$this->getConfig('enable_responsive')) { + $uri = apPageHelper::getCssDir().'mobile.css'; + $skinFileUrl = apPageHelper::getFullPathCss($uri); + if ($skinFileUrl !== false) { + $css_skin[] = ''; + } + } + + # LOAD POSITIONS AND PROFILES + $this->loadResouceForProfile(); + + # LOAD PATTERN + if ($profile = $this->getConfig('c_profile')) { + $uri = apPageHelper::getCssDir().'patterns/'.$profile.'.css'; + $skinFileUrl = apPageHelper::getFullPathCss($uri); + if ($skinFileUrl !== false) { + $css_skin[] = ''; + } + } + } + + if ($this->context->language->is_rtl) { + # OVERRIDE CORE, LOAD RTL.CSS FILE AT BOTTOM + $this->context->controller->registerStylesheet('theme-rtl', '/assets/css/rtl.css', ['media' => 'all', 'priority' => 9000]); + } + + $ps = array( + 'LEO_THEMENAME' => _THEME_NAME_, + 'LEO_PANELTOOL' => $panelTool, + 'LEO_SUBCATEGORY' => $this->getConfig('subcategory'), + 'LEO_DEFAULT_SKIN' => $skin, + 'LEO_LAYOUT_MODE' => $layout_mode, + 'BACKGROUNDVALUE' => $backGroundValue, + 'LAYOUT_WIDTH' => $layout_width_val, + 'LOAD_CSS_TYPE' => $load_css_type, + 'LEO_CSS' => $css_custom, + 'LEO_SKIN_CSS' => $css_skin, + 'IS_RTL' => $isRTL, + 'LEO_RTL' => $leoRTL, + 'USE_PTABS' => $this->getConfig('ENABLE_PTAB'), + 'USE_FHEADER' => $enable_fheader, + 'LEO_COOKIE_THEME' => $this->themeCookieName, + 'LEO_BACKTOP' => $this->getConfig('backtop'), + 'apPageHelper' => apPageHelper::getInstance(), + 'leoConfiguration' => new Configuration(), + 'list_productdetail_layout' => $list_productdetail_layout, + ); + + Media::addJsDefL('LEO_COOKIE_THEME', $this->themeCookieName); + $this->context->smarty->assign($ps); + + $page_name = apPageHelper::getPageName(); + $page = $this->smarty->smarty->getVariable('page')->value; + if (isset($this->profile_data['meta_title']) && $this->profile_data['meta_title'] && $page_name == 'index') { + $page['meta']['title'] = $this->profile_data['meta_title']; + } + if (isset($this->profile_data['meta_description']) && $this->profile_data['meta_description'] && $page_name == 'index') { + $page['meta']['description'] = $this->profile_data['meta_description']; + } + if (isset($this->profile_data['meta_keywords']) && $this->profile_data['meta_keywords'] && $page_name == 'index') { + $page['meta']['keywords'] = $this->profile_data['meta_keywords']; + } + $this->smarty->smarty->assign('page', $page); + + # REPLACE LINK FOR MULILANGUAGE + $controller = Dispatcher::getInstance()->getController(); + if ($controller == 'appagebuilderhome') { + Media::addJsDef(array('approfile_multilang_url' => ApPageBuilderProfilesModel::getAllProfileRewrite($this->profile_data['id_appagebuilder_profiles']))); + } + + if ($controller == 'sitemap') { + $profile_model = new ApPageBuilderProfilesModel(); + $profiles = $profile_model->getAllProfileByShop(); + foreach ($profiles as $key => $profile) { + if (!isset($profile['friendly_url']) || !$profile['friendly_url']) { + unset($profiles[$key]); + } + } + $this->smarty->smarty->assign('simap_ap_profiles', $profiles); + } + + $this->header_content = $this->display(__FILE__, 'header.tpl'); + return $this->header_content; + } + + //DONGND:: build shortcode by hook + public function hookDisplayApSC($params) + { + if (isset($params['sc_key']) && $params['sc_key'] != '') { + return $this->processShortCode($params['sc_key']); + } + } + + //DONGND:: build shortcode by embedded in content + public function buildShortCode($content) + { + //DONGND:: validate module + $result = preg_replace_callback( + '~\[ApSC(.*?)\[\/ApSC\]~', + function ($matches_tmp) { + preg_match_all("~sc_key=(.*?)\]~", $matches_tmp[1], $tmp); + return self::processShortCode($tmp[1][0]); + }, + $content + ); + return $result; + } + + //DONGN:: get list short code for tinymce + public function getListShortCodeForEditor() + { + $this->smarty->smarty->assign(array( + 'js_dir' => _PS_JS_DIR_, + 'appagebuilder_module_dir' => $this->_path, + 'shortcode_url_add' => Configuration::get('shortcode_url_add').'&addappagebuilder_shortcode', + 'shortcode_url' => Configuration::get('shortcode_url_add'), + 'list_shortcode' => ApPageBuilderShortcodeModel::getListShortCode(), + )); + return $this->display(__FILE__, 'list_shortcode.tpl'); + } + + private function processShortCode($shortcode_key) + { + $disable_cache = false; + if (!Configuration::get('PS_SMARTY_CACHE')) { + $disable_cache = true; + } + + $cache_id = $this->getCacheId('apshortcode', $shortcode_key); + if ($disable_cache || !$this->isCached($this->templateFile, $cache_id)) { + $shortcode_html = ''; + $shortcode_obj = ApPageBuilderShortcodeModel::getShortCode($shortcode_key); + if (isset($shortcode_obj['id_appagebuilder']) && $shortcode_obj['id_appagebuilder'] != '' && $shortcode_obj['id_appagebuilder'] != 0) { + $shortcode_code = ApPageBuilderShortcodeModel::getAllItems($shortcode_obj['id_appagebuilder'], 1); + + if (!empty($shortcode_code)) { + if (empty(ApShortCodesBuilder::$shortcode_tags)) { + apPageHelper::loadShortCode(_PS_THEME_DIR_); + } + + apPageHelper::setGlobalVariable($this->context); + + // ApShortCodesBuilder::$is_front_office = 1; + // ApShortCodesBuilder::$is_gen_html = 1; + // ApShortCodesBuilder::$profile_param = array(); + $ap_helper = new ApShortCodesBuilder(); + // ApShortCodesBuilder::$hook_name = 'apshortcode'; + + $shortcode_html = $ap_helper->parse($shortcode_code['apshortcode']); + } + } + $this->smarty->assign(array('apContent' => $shortcode_html)); + } + return $this->display(__FILE__, 'appagebuilder.tpl', $cache_id); + } + + private function processHook($hook_name, $params = 'null') + { + $disable_cache_hook = isset($this->profile_param['disable_cache_hook']) ? $this->profile_param['disable_cache_hook'] : ApPageSetting::getCacheHook(3); + $disable_cache = false; + if (isset($disable_cache_hook[$hook_name]) && $disable_cache_hook[$hook_name]) { + $disable_cache = true; + } + if (Tools::isSubmit('submitNewsletter')) { + $disable_cache = true; + } + if (!Configuration::get('PS_SMARTY_CACHE')) { + $disable_cache = true; + } + $is_live = Tools::getIsset('ap_live_edit') ? Tools::getValue('ap_live_edit') : ''; + if ($is_live) { + $disable_cache = true; + } + + $cache_id = $this->getCacheId($hook_name); + $cover_hook_live = ''; + if ($disable_cache || !$this->isCached($this->templateFile, $cache_id)) { + if ($disable_cache) { + $cache_id = null; + } + if ($is_live) { + $token = Tools::getIsset('ap_edit_token') ? Tools::getValue('ap_edit_token') : ''; + $admin_dir = Tools::getIsset('ad') ? Tools::getValue('ad') : ''; + $controller = 'AdminApPageBuilderHome'; + $id_lang = Context::getContext()->language->id; + $id_profile = ApPageBuilderProfilesModel::getIdProfileFromRewrite(); + $params = array('token' => $token, 'id_appagebuilder_profiles' => $id_profile); + $current_link = _PS_BASE_URL_.__PS_BASE_URI__; + $url_design_layout = $current_link.$admin_dir.'/'.Dispatcher::getInstance()->createUrl($controller, $id_lang, $params, false); + $cover_hook_live = '
Hook: '.Tools::strtoupper($hook_name).'
'; + } + $model = new ApPageBuilderModel(); + if (!$this->hook_index_data) { + $this->hook_index_data = $model->getAllItems($this->profile_data, 1, $this->default_language['id_lang']); + } + if (!isset($this->hook_index_data[$hook_name]) || trim($this->hook_index_data[$hook_name]) == '') { + # NOT DATA BUT SET VARIABLE TO SET CACHE + $this->smarty->assign(array('apContent' => '')); + return $cover_hook_live.$this->fetch( $this->templateFile, $cache_id); + } + $ap_content = $model->parseData($hook_name, $this->hook_index_data[$hook_name], $this->profile_param); + if ($is_live) { + $ap_content = '
'.$ap_content.'
'; + } + $this->smarty->assign(array('apContent' => $ap_content)); + } + return $cover_hook_live.$this->fetch( $this->templateFile, $cache_id); + } + + public function hookDisplayBanner($params) + { + return $this->processHook('displayBanner', $params); + } + + public function hookDisplayNav1($params) + { + return $this->processHook('displayNav1', $params); + } + + public function hookDisplayNav2($params) + { + return $this->processHook('displayNav2', $params); + } + + public function hookDisplayNavFullWidth($params) + { + return $this->processHook('displayNavFullWidth', $params); + } + + public function hookDisplayTop($params) + { + return $this->processHook('displayTop', $params); + } + + public function hookDisplaySlideshow($params) + { + return $this->processHook('displaySlideshow', $params); + } + + public function hookDisplayRightColumn($params) + { + return $this->processHook('displayRightColumn', $params); + } + + public function hookDisplayLeftColumn($params) + { + return $this->processHook('displayLeftColumn', $params); + } + + public function hookDisplayHome($params) + { + return $this->processHook('displayHome', $params); + } + + public function hookDisplayFooterBefore($params) + { + return $this->processHook('displayFooterBefore', $params); + } + + public function hookDisplayFooter($params) + { + return $this->processHook('displayFooter', $params);//.$this->header_content; + } + + public function hookDisplayFooterAfter($params) + { + return $this->processHook('displayFooterAfter', $params); + } + + public function hookDisplayFooterProduct($params) + { + return $this->processHook('displayFooterProduct', $params); + } + + public function hookDisplayRightColumnProduct($params) + { + return $this->processHook('displayRightColumnProduct', $params); + } + + public function hookDisplayLeftColumnProduct($params) + { + return $this->processHook('displayLeftColumnProduct', $params); + } + + public function hookdisplayProductButtons($params) + { + return $this->processHook('displayProductButtons', $params); + } + + public function hookDisplayReassurance($params) + { + return $this->processHook('displayReassurance', $params); + } + + public function hookDisplayLeoProfileProduct($params) + { + apPageHelper::setGlobalVariable($this->context); + $html = ''; + $tpl_file = ''; + + if (isset($params['ony_global_variable'])) { + # {hook h='displayLeoProfileProduct' ony_global_variable=true} + return $html; + } + + if (!isset($params['product'])) { + return 'Not exist product to load template'; + } else if (isset($params['profile'])) { + # {hook h='displayLeoProfileProduct' product=$product profile=$productProfileDefault} + $tpl_file = apPageHelper::getConfigDir('theme_profiles') . $params['profile'].'.tpl'; + } else if (isset($params['load_file'])) { + # {hook h='displayLeoProfileProduct' product=$product load_file='templates/catalog/_partials/miniatures/product.tpl'} + $tpl_file = _PS_ALL_THEMES_DIR_._THEME_NAME_.'/' . $params['load_file']; + } else if (isset($params['typeProduct'])) { + //DONGND:: load default product tpl when do not have product profile + if ($params['product']['productLayout'] != '') { + $tpl_file = apPageHelper::getConfigDir('theme_details') . $params['product']['productLayout'].'.tpl'; + } else { + $tpl_file = _PS_ALL_THEMES_DIR_._THEME_NAME_.'/templates/catalog/product.tpl'; + } + } + + if (empty($tpl_file)) { + return 'Not exist profile to load template'; + } + + Context::getContext()->smarty->assign(array( + 'product' => $params['product'], + )); + $html .= Context::getContext()->smarty->fetch($tpl_file); + return $html; + } + + public function hookActionShopDataDuplication() + { + $this->clearHookCache(); + } + + /** + * Register hook again to after install/change any theme + */ + public function hookActionObjectShopUpdateAfter() + { + // Retrieve hooks used by the module +// $sql = 'SELECT `id_hook` FROM `'._DB_PREFIX_.'hook_module` WHERE `id_module` = '.(int)$this->id; +// $result = Db::getInstance()->executeS($sql); +// foreach ($result as $row) { +// $this->unregisterHook((int)$row['id_hook']); +// $this->unregisterExceptions((int)$row['id_hook']); +// } + } + + /** + * FIX BUG 1.7.3.3 : install theme lose hook displayHome, displayLeoProfileProduct + * because ajax not run hookActionAdminBefore(); + */ + public function autoRestoreSampleData() + { + if(Hook::isModuleRegisteredOnHook($this, 'actionAdminBefore', (int)Context::getContext()->shop->id)) { + $theme_manager = new stdclass(); + $theme_manager->theme_manager = 'theme_manager'; + $this->hookActionAdminBefore(array( + 'controller' => $theme_manager, + )); + } + } + + /** + * Run only one when install/change Theme_of_Leo + */ + public function hookActionAdminBefore($params) + { + $this->unregisterHook('actionAdminBefore'); + if (isset($params) && isset($params['controller']) && isset($params['controller']->theme_manager)) { + // Validate : call hook from theme_manager + } else { + // Other module call this hook -> duplicate data + return; + } + + + # FIX : update Prestashop by 1-Click module -> NOT NEED RESTORE DATABASE + $ap_version = Configuration::get('AP_CURRENT_VERSION'); + if ($ap_version != false) { + $ps_version = Configuration::get('PS_VERSION_DB'); + $versionCompare = version_compare($ap_version, $ps_version); + if ($versionCompare != 0) { + // Just update Prestashop + Configuration::updateValue('AP_CURRENT_VERSION', $ps_version); + return; + } + } + + + # WHENE INSTALL THEME, INSERT HOOK FROM DATASAMPLE IN THEME + $hook_from_theme = false; + if (file_exists(_PS_MODULE_DIR_.'appagebuilder/libs/LeoDataSample.php')) { + require_once(_PS_MODULE_DIR_.'appagebuilder/libs/LeoDataSample.php'); + $sample = new Datasample(); + if ($sample->processHook($this->name)) { + $hook_from_theme = true; + }; + } + + # INSERT HOOK FROM MODULE_DATASAMPLE + if ($hook_from_theme == false) { + $this->registerLeoHook(); + } + + # WHEN INSTALL MODULE, NOT NEED RESTORE DATABASE IN THEME + $install_module = (int)Configuration::get('AP_INSTALLED_APPAGEBUILDER', 0); + if ($install_module) { + Configuration::updateValue('AP_INSTALLED_APPAGEBUILDER', '0'); // next : allow restore sample + return; + } + + # INSERT DATABASE FROM THEME_DATASAMPLE + if (file_exists(_PS_MODULE_DIR_.'appagebuilder/libs/LeoDataSample.php')) { + require_once(_PS_MODULE_DIR_.'appagebuilder/libs/LeoDataSample.php'); + $sample = new Datasample(); + $sample->processImport($this->name); + } + + # REMOVE FILE INDEX.PHP FOR TRANSLATE + if (file_exists(_PS_MODULE_DIR_.'appagebuilder/libs/setup.php')) { + require_once(_PS_MODULE_DIR_.'appagebuilder/libs/setup.php'); + ApPageSetup::processTranslateTheme(); + } + + # REMOVE SUPPORT TEAM FIX LINK CSS, JS + Configuration::updateValue('LEO_SUPPORT_TEAM', '0'); + } + + protected function getCacheId($hook_name = null, $shortcode_key = null) + { + $cache_array = array(); + $cache_array[] = $this->name; + if (ApPageBuilderProfilesModel::getIdProfileFromRewrite() && !$shortcode_key) { + $cache_array[] = 'profile_'.ApPageBuilderProfilesModel::getIdProfileFromRewrite(); + } + + $cache_array[] = $hook_name; + if ($this->profile_param && isset($this->profile_param[$hook_name]) && $this->profile_param[$hook_name]) { + //$cache_array[] = $hook_name; + $current_page = apPageHelper::getPageName(); + //show ocurrentPagenly in controller + if (isset($this->profile_param[$hook_name][$current_page])) { + $cache_array[] = $current_page; + if ($current_page != 'index' && $cache_id = ApPageSetting::getControllerId($current_page, $this->profile_param[$hook_name][$current_page])) { + $cache_array[] = $cache_id; + } + } elseif (isset($this->profile_param[$hook_name]['productCarousel'])) { + $random = round(rand(1, max(Configuration::get('APPAGEBUILDER_PRODUCT_MAX_RANDOM'), 1))); + $cache_array[] = "p_carousel_$random"; + } else if (isset($this->profile_param[$hook_name]['exception']) && in_array($cache_array, $this->profile_param[$hook_name]['exception'])) { + //show but not in controller + $cache_array[] = $current_page; + } + } + if (Configuration::get('PS_SSL_ENABLED')) { + $cache_array[] = 'SSL_'.(int)Tools::usingSecureMode(); + } + if (Shop::isFeatureActive()) { + $cache_array[] = 'shop_'.(int)$this->context->shop->id; + } + if (Group::isFeatureActive()) { + $cache_array[] = 'c_group_'.(int)GroupCore::getCurrent()->id; + } + if (Language::isMultiLanguageActivated()) { + $cache_array[] = 'la_'.(int)$this->context->language->id; + } + if (Currency::isMultiCurrencyActivated()) { + $cache_array[] = 'curcy_'.(int)$this->context->currency->id; + } + $cache_array[] = 'ctry_'.(int)$this->context->country->id; + if (Tools::getValue('plist_key')&& Tools::getIsset('leopanelchange')) { + $cache_array[] = 'plist_key_'.Tools::getValue('plist_key'); + } + if (Tools::getValue('header') && Tools::getIsset('leopanelchange') && (in_array($hook_name, ApPageSetting::getHook('header')) || $hook_name == 'pagebuilderConfig|header')) { + $cache_array[] = 'header_'.Tools::getValue('header'); + } + if (Tools::getValue('content')&& Tools::getIsset('leopanelchange') && (in_array($hook_name, ApPageSetting::getHook('content')) || $hook_name == 'pagebuilderConfig|content')) { + $cache_array[] = 'content_'.Tools::getValue('content'); + } + if (Tools::getValue('product')&& Tools::getIsset('leopanelchange') && (in_array($hook_name, ApPageSetting::getHook('product')) || $hook_name == 'pagebuilderConfig|product')) { + $cache_array[] = 'product_'.Tools::getValue('product'); + } + if (Tools::getValue('footer') && Tools::getIsset('leopanelchange') && (in_array($hook_name, ApPageSetting::getHook('footer')) || $hook_name == 'pagebuilderConfig|footer')) { + $cache_array[] = 'footer_'.Tools::getValue('footer'); + } + + //DONGND:: update cache for shortcode + if ($shortcode_key) { + $cache_array[] = 'shortcodekey_'.$shortcode_key; + } + + return implode('|', $cache_array); + } + + /** + * Overide function isCached of Module.php + * @param type $template + * @param type $cache_id + * @param type $compile_id + * @return boolean + */ +// public function isCached($template, $cache_id = null, $compile_id = null) +// { +// if (version_compare(_PS_VERSION_, '1.7.4.0', '>=') || version_compare(Configuration::get('PS_VERSION_DB'), '1.7.4.0', '>=')) { +// // FIX TEMP +// return false; +// } +// if (Tools::getIsset('live_edit')) { +// return false; +// } +// Tools::enableCache(); +// $is_cached = $this->getCurrentSubTemplate($this->getTemplatePath($template), $cache_id, $compile_id); +// $is_cached = $is_cached->isCached($this->getTemplatePath($template), $cache_id, $compile_id); +// Tools::restoreCacheSettings(); +// return $is_cached; +// } + + /** + * This function base on the function getCurrentSubTemplate of Module.php (not overide) + * @param type $template + * @param type $cache_id + * @param type $compile_id + * @return type + */ +// protected function getCurrentSubTemplate($template, $cache_id = null, $compile_id = null) +// { +// if (!isset($this->current_subtemplate[$template.'_'.$cache_id.'_'.$compile_id])) { +// $this->current_subtemplate[$template.'_'.$cache_id.'_'.$compile_id] = $this->context->smarty->createTemplate($this->getTemplatePath($template), $cache_id, $compile_id, $this->smarty); +// } +// return $this->current_subtemplate[$template.'_'.$cache_id.'_'.$compile_id]; +// } + + /** + * Overide function display of Module.php + * @param type $file + * @param type $template + * @param null $cache_id + * @param type $compile_id + * @return type + */ + public function display($file, $template, $cache_id = null, $compile_id = null) + { + if (($overloaded = Module::_isTemplateOverloadedStatic(basename($file, '.php'), $template)) === null) { + return sprintf($this->l('No template found "%s"'), $template); + } else { + if (Tools::getIsset('live_edit')) { + $cache_id = null; + } + $this->smarty->assign(array( + 'module_dir' => __PS_BASE_URI__.'modules/'.basename($file, '.php').'/', + 'module_template_dir' => ($overloaded ? _THEME_DIR_ : __PS_BASE_URI__).'modules/'.basename($file, '.php').'/', + 'allow_push' => $this->allow_push + )); + if ($cache_id !== null) { + Tools::enableCache(); + } + $result = $this->getCurrentSubTemplate($template, $cache_id, $compile_id)->fetch(); + if ($cache_id !== null) { + Tools::restoreCacheSettings(); + } + $this->resetCurrentSubTemplate($template, $cache_id, $compile_id); + return $result; + } + } + + public function clearHookCache() + { +// $this->_clearCache('appagebuilder.tpl', $this->name); + $this->_clearCache($this->templateFile); # CLEAR CACHE ALL HOOKS + } + + //DONGND:: add clear cache for shortcode + public function clearShortCodeCache($shortcode_key) + { + $cache_id = $this->getCacheId('apshortcode', $shortcode_key); + + $this->_clearCache('appagebuilder.tpl', $cache_id); + } + + public function hookCategoryAddition() + { + $this->clearHookCache(); + } + + public function hookCategoryUpdate() + { + $this->clearHookCache(); + } + + public function hookCategoryDeletion() + { + $this->clearHookCache(); + } + + public function hookAddProduct() + { + $this->clearHookCache(); + } + + public function hookUpdateProduct() + { + $this->clearHookCache(); + } + + public function hookDeleteProduct() + { + $this->clearHookCache(); + } + + public function hookDisplayBackOfficeHeader() + { + apPageHelper::autoUpdateModule(); + if (method_exists($this->context->controller, 'addJquery')) { + // validate module + $this->context->controller->addJquery(); + } + //DONGND:: fix home page config with theme of leotheme, redirect to profile page + if (get_class($this->context->controller) == 'AdminPsThemeCustoConfigurationController' && _THEME_NAME_ != 'default') { + Media::addJsDef( + array( + 'ap_profile_url' => $this->context->link->getAdminLink('AdminApPageBuilderProfiles'), + 'ap_profile_txt_redirect' => $this->l('You are using a theme from Leotheme. Please access this link to use this feature easily'), + 'ap_check_theme_name' => _THEME_NAME_ + ) + ); + } + $this->context->controller->addCss(apPageHelper::getCssAdminDir().'admin/style.css'); + $this->context->controller->addJS(apPageHelper::getJsAdminDir().'admin/setting.js'); + if (!apPageHelper::isRelease()) { + Media::addJsDef(array('js_ap_dev' => 1)); + } + } + + public function loadResouceForProfile() + { + $profile = $this->profile_data; + $arr = array(); + if ($profile['header']) { + $arr[] = $profile['header']; + } + if ($profile['content']) { + $arr[] = $profile['content']; + } + if ($profile['footer']) { + $arr[] = $profile['footer']; + } + if ($profile['product']) { + $arr[] = $profile['product']; + } + if (count($arr) > 0) { + $model = new ApPageBuilderProfilesModel(); + $list_positions = $model->getPositionsForProfile($arr); + if ($list_positions) { + foreach ($list_positions as $item) { + $name = $item['position'].$item['position_key']; + + $uri = apPageHelper::getCssDir().'positions/'.$name.'.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + + $uri = apPageHelper::getJsDir().'positions/'.$name.'.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 8000)); + } + } + } + + $uri = apPageHelper::getCssDir().'profiles/'.$profile['profile_key'].'.css'; + $this->context->controller->registerStylesheet(sha1($uri), $uri, array('media' => 'all', 'priority' => 8000)); + + $uri = apPageHelper::getJsDir().'profiles/'.$profile['profile_key'].'.js'; + $this->context->controller->registerJavascript(sha1($uri), $uri, array('position' => 'bottom', 'priority' => 8000)); + } + + public function getProfileData() + { + return $this->profile_data; + } + + public function setFullwidthHook() + { + if (isset(Context::getContext()->controller->controller_type) && in_array(Context::getContext()->controller->controller_type, array('front', 'modulefront'))) { + # frontend + $page_name = apPageHelper::getPageName(); + if ($page_name == 'index' || $page_name == 'appagebuilderhome') { + $this->context->smarty->assign(array( + 'fullwidth_hook' => isset($this->profile_param['fullwidth_index_hook']) ? $this->profile_param['fullwidth_index_hook'] : ApPageSetting::getIndexHook(3), + )); + } else { + $this->context->smarty->assign(array( + 'fullwidth_hook' => isset($this->profile_param['fullwidth_other_hook']) ? $this->profile_param['fullwidth_other_hook'] : ApPageSetting::getOtherHook(3), + )); + } + } + } + + /** + * Get Grade By product + * + * @return array Grades + */ + public static function getGradeByProducts($list_product) + { + $list_product = apPageHelper::addonValidInt( $list_product ); # We validate id_categories in apPageHelper::addonValidInt function . This function is used at any where + $validate = Configuration::get('PRODUCT_COMMENTS_MODERATE'); + $id_lang = (int)Context::getContext()->language->id; + + return (Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' + SELECT pc.`id_product_comment`, pcg.`grade`, pccl.`name`, pcc.`id_product_comment_criterion`, pc.`id_product` + FROM `'._DB_PREFIX_.'product_comment` pc + LEFT JOIN `'._DB_PREFIX_.'product_comment_grade` pcg ON (pcg.`id_product_comment` = pc.`id_product_comment`) + LEFT JOIN `'._DB_PREFIX_.'product_comment_criterion` pcc ON (pcc.`id_product_comment_criterion` = pcg.`id_product_comment_criterion`) + LEFT JOIN `'._DB_PREFIX_.'product_comment_criterion_lang` pccl ON (pccl.`id_product_comment_criterion` = pcg.`id_product_comment_criterion`) + WHERE pc.`id_product` in ('.pSQL($list_product).') + AND pccl.`id_lang` = '.(int)$id_lang. + ($validate == '1' ? ' AND pc.`validate` = 1' : ''))); + } + + /** + * Return number of comments and average grade by products + * + * @return array Info + */ + public static function getGradedCommentNumber($list_product) + { + $list_product = apPageHelper::addonValidInt( $list_product ); # We validate id_categories in apPageHelper::addonValidInt function . This function is used at any where + $validate = (int)Configuration::get('PRODUCT_COMMENTS_MODERATE'); + + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' + SELECT COUNT(pc.`id_product`) AS nbr, pc.`id_product` + FROM `'._DB_PREFIX_.'product_comment` pc + WHERE `id_product` in ('.pSQL($list_product).')'.($validate == '1' ? ' AND `validate` = 1' : '').' + AND `grade` > 0 GROUP BY pc.`id_product`'); + return $result; + } + + public static function getByProduct($id_product) + { + $id_lang = (int)Context::getContext()->language->id; + + if (!Validate::isUnsignedId($id_product) || !Validate::isUnsignedId($id_lang)) { + die(Tools::displayError()); + } + $alias = 'p'; + $table = ''; + // check if version > 1.5 to add shop association + if (version_compare(_PS_VERSION_, '1.5', '>')) { + $table = '_shop'; + $alias = 'ps'; + } + return Db::getInstance()->executeS(' + SELECT pcc.`id_product_comment_criterion`, pccl.`name` + FROM `'._DB_PREFIX_.'product_comment_criterion` pcc + LEFT JOIN `'._DB_PREFIX_.'product_comment_criterion_lang` pccl + ON (pcc.id_product_comment_criterion = pccl.id_product_comment_criterion) + LEFT JOIN `'._DB_PREFIX_.'product_comment_criterion_product` pccp + ON (pcc.`id_product_comment_criterion` = pccp.`id_product_comment_criterion` AND pccp.`id_product` = '.(int)$id_product.') + LEFT JOIN `'._DB_PREFIX_.'product_comment_criterion_category` pccc + ON (pcc.`id_product_comment_criterion` = pccc.`id_product_comment_criterion`) + LEFT JOIN `'._DB_PREFIX_.'product'.bqSQL($table).'` '.bqSQL($alias).' + ON ('.bqSQL($alias).'.id_category_default = pccc.id_category AND '.bqSQL($alias).'.id_product = '.(int)$id_product.') + WHERE pccl.`id_lang` = '.(int)$id_lang.' + AND ( + pccp.id_product IS NOT NULL + OR ps.id_product IS NOT NULL + OR pcc.id_product_comment_criterion_type = 1 + ) + AND pcc.active = 1 + GROUP BY pcc.id_product_comment_criterion + '); + } + + public function hookProductMoreImg($list_pro) + { + $id_lang = Context::getContext()->language->id; + //get product info + $product_list = $this->getProducts($list_pro, $id_lang); + + $this->smarty->assign(array( + 'homeSize' => Image::getSize(ImageType::getFormattedName('home')), + 'mediumSize' => Image::getSize(ImageType::getFormattedName('medium')) + )); + + $obj = array(); + foreach ($product_list as $product) { + $this->smarty->assign('product', $product); + $obj[] = array('id' => $product['id_product'], 'content' => ($this->display(__FILE__, 'product.tpl'))); + } + return $obj; + } + + public function hookProductOneImg($list_pro) + { + $protocol_link = (Configuration::get('PS_SSL_ENABLED') || Tools::usingSecureMode()) ? 'https://' : 'http://'; + $use_ssl = ((isset($this->ssl) && $this->ssl && Configuration::get('PS_SSL_ENABLED')) || Tools::usingSecureMode()) ? true : false; + $protocol_content = ($use_ssl) ? 'https://' : 'http://'; + $link = new Link($protocol_link, $protocol_content); + + $id_lang = Context::getContext()->language->id; + $where = ' WHERE i.`id_product` IN ('.$list_pro.') AND (ish.`cover`=0 OR ish.`cover` IS NULL) AND ish.`id_shop` = '.Context::getContext()->shop->id; + $order = ' ORDER BY i.`id_product`,`position`'; + $limit = ' LIMIT 0,1'; + //get product info + $list_img = $this->getAllImages($id_lang, $where, $order, $limit); + $saved_img = array(); + $obj = array(); + $this->smarty->assign(array( + 'homeSize' => Image::getSize(ImageType::getFormattedName('home')), + 'mediumSize' => Image::getSize(ImageType::getFormattedName('medium')), + 'smallSize' => Image::getSize(ImageType::getFormattedName('small')) + )); + + $image_name = 'home'; + $image_name .= '_default'; + foreach ($list_img as $product) { + if (!in_array($product['id_product'], $saved_img)) { + $obj[] = array( + 'id' => $product['id_product'], + 'content' => ($link->getImageLink($product['link_rewrite'], $product['id_image'], $image_name)), + 'name' => $product['name'], + ); + } + $saved_img[] = $product['id_product']; + } + return $obj; + } + + public function hookProductCdown($leo_pro_cdown) + { + $id_lang = Context::getContext()->language->id; + $product_list = $this->getProducts($leo_pro_cdown, $id_lang); + $obj = array(); + foreach ($product_list as $product) { + $this->smarty->assign('product', $product); + $obj[] = array('id' => $product['id_product'], 'content' => ($this->display(__FILE__, 'cdown.tpl'))); + } + return $obj; + } + + public function hookProductColor($leo_pro_color) + { + $id_lang = Context::getContext()->language->id; + $colors = array(); + $leo_customajax_color = Configuration::get('APPAGEBUILDER_COLOR'); + if ($leo_customajax_color) { + $arrs = explode(',', $leo_customajax_color); + foreach ($arrs as $arr) { + $items = explode(':', $arr); + $colors[$items[0]] = $items[1]; + } + } + $this->smarty->assign(array( + 'colors' => $colors, + )); + $product_list = $this->getProducts($leo_pro_color, $id_lang); + $obj = array(); + foreach ($product_list as $product) { + $this->smarty->assign('product', $product); + $obj[] = array('id' => $product['id_product'], 'content' => ($this->display(__FILE__, 'color.tpl'))); + } + return $obj; + } + + public function hookModuleRoutes($params) + { + $routes = array(); + $model = new ApPageBuilderProfilesModel(); + $allProfileArr = $model->getAllProfileByShop(); + foreach ($allProfileArr as $allProfileItem) { + if (isset($allProfileItem['friendly_url']) && $allProfileItem['friendly_url']) { + $routes['module-appagebuilder-'.$allProfileItem['friendly_url']] = array( + 'controller' => 'appagebuilderhome', + 'rule' => $allProfileItem['friendly_url'].'.html', + 'keywords' => array( + ), + 'params' => array( + 'fc' => 'module', + 'module' => 'appagebuilder' + ) + ); + } + } + return $routes; + } + + public function getProducts($product_list, $id_lang, $colors = array()) + { + $product_list = apPageHelper::addonValidInt( $product_list ); # We validate id_categories in apPageHelper::addonValidInt function . This function is used at any where + $context = Context::getContext(); + $id_address = $context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}; + $ids = Address::getCountryAndState($id_address); + $id_country = ($ids['id_country'] ? $ids['id_country'] : Configuration::get('PS_COUNTRY_DEFAULT')); + $sql = 'SELECT p.*, product_shop.*, pl.* , m.`name` AS manufacturer_name, s.`name` AS supplier_name,sp.`id_specific_price` + FROM `'._DB_PREFIX_.'product` p + '.Shop::addSqlAssociation('product', 'p').' + LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` '.Shop::addSqlRestrictionOnLang('pl').') + LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON (m.`id_manufacturer` = p.`id_manufacturer`) + LEFT JOIN `'._DB_PREFIX_.'supplier` s ON (s.`id_supplier` = p.`id_supplier`) + LEFT JOIN `'._DB_PREFIX_.'specific_price` sp ON (sp.`id_product` = p.`id_product` + AND sp.`id_shop` IN(0, '.(int)$context->shop->id.') + AND sp.`id_currency` IN(0, '.(int)$context->currency->id.') + AND sp.`id_country` IN(0, '.(int)$id_country.') + AND sp.`id_group` IN(0, '.(int)$context->customer->id_default_group.') + AND sp.`id_customer` IN(0, '.(int)$context->customer->id.') + AND sp.`reduction` > 0 + ) + WHERE pl.`id_lang` = '.(int)$id_lang. + ' AND p.`id_product` in ('.pSQL($product_list).')'; + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); + + if ($product_list) { + $tmp_img = array(); + $cover_img = array(); + $where = ' WHERE i.`id_product` IN ('.pSQL($product_list).') AND ish.`id_shop` = '.Context::getContext()->shop->id; + $order = ' ORDER BY i.`id_product`,`position`'; + + switch (Configuration::get('LEO_MINFO_SORT')) { + case 'position2': + break; + case 'random': + $order = ' ORDER BY RAND()'; + break; + default: + $order = ' ORDER BY i.`id_product`,`position` DESC'; + } + + $list_img = $this->getAllImages($id_lang, $where, $order); + foreach ($list_img as $val) { + $tmp_img[$val['id_product']][$val['id_image']] = $val; + if ($val['cover'] == 1) { + $cover_img[$val['id_product']] = $val['id_image']; + } + } + } + $now = date('Y-m-d H:i:s'); + $finish = $this->l('Expired'); + foreach ($result as &$val) { + $time = false; + if (isset($tmp_img[$val['id_product']])) { + $val['images'] = $tmp_img[$val['id_product']]; + $val['id_image'] = $cover_img[$val['id_product']]; + } else { + $val['images'] = array(); + } + + $val['specific_prices'] = self::getSpecificPriceById($val['id_specific_price']); + if (isset($val['specific_prices']['from']) && $val['specific_prices']['from'] > $now) { + $time = strtotime($val['specific_prices']['from']); + $val['finish'] = $finish; + $val['check_status'] = 0; + $val['lofdate'] = Tools::displayDate($val['specific_prices']['from']); + } elseif (isset($val['specific_prices']['to']) && $val['specific_prices']['to'] > $now) { + $time = strtotime($val['specific_prices']['to']); + $val['finish'] = $finish; + $val['check_status'] = 1; + $val['lofdate'] = Tools::displayDate($val['specific_prices']['to']); + } elseif (isset($val['specific_prices']['to']) && $val['specific_prices']['to'] == '0000-00-00 00:00:00') { + $val['js'] = 'unlimited'; + $val['finish'] = $this->l('Unlimited'); + $val['check_status'] = 1; + $val['lofdate'] = $this->l('Unlimited'); + } else if (isset($val['specific_prices']['to'])) { + $time = strtotime($val['specific_prices']['to']); + $val['finish'] = $finish; + $val['check_status'] = 2; + $val['lofdate'] = Tools::displayDate($val['specific_prices']['from']); + } + if ($time) { + $val['js'] = array( + 'month' => date('m', $time), + 'day' => date('d', $time), + 'year' => date('Y', $time), + 'hour' => date('H', $time), + 'minute' => date('i', $time), + 'seconds' => date('s', $time) + ); + } + } + unset($colors); + return Product::getProductsProperties($id_lang, $result); + } + + public static function getSpecificPriceById($id_specific_price) + { + if (!SpecificPrice::isFeatureActive()) { + return array(); + } + + $res = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow(' + SELECT * + FROM `'._DB_PREFIX_.'specific_price` sp + WHERE `id_specific_price` ='.(int)$id_specific_price); + + return $res; + } + + public function getAllImages($id_lang, $where, $order) + { + $id_shop = Context::getContext()->shop->id; + $sql = 'SELECT DISTINCT i.`id_product`, ish.`cover`, i.`id_image`, il.`legend`, i.`position`,pl.`link_rewrite`, pl.`name` + FROM `'._DB_PREFIX_.'image` i + LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (i.`id_product` = pl.`id_product`) AND pl.`id_lang` = '.(int)$id_lang.' + LEFT JOIN `'._DB_PREFIX_.'image_shop` ish ON (ish.`id_image` = i.`id_image` AND ish.`id_shop` = '.(int)$id_shop.') + LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')'.pSql($where).' '.pSQL($order); + return Db::getInstance()->executeS($sql); + } + + // show category and tags of product + public function hookdisplayProductInformation($params) + { + $return = ''; + $product_id = $params['product']->id; + $category_id = $params['product']->id_category_default; + $cat = new Category($category_id, $this->context->language->id); + $product_tags = Tag::getProductTags($product_id); + $product_tags = $product_tags[(int)$this->context->cookie->id_lang]; + $return .= '
Category: '.$cat->name.'.
'; + $return .= '
'; + $return .= 'Tag: '; + if ($product_tags && count($product_tags) > 1) { + $count = 0; + foreach ($product_tags as $tag) { + $return .= ''.$tag.''; + if ($count < count($product_tags) - 1) { + $return .= ','; + } else { + $return .= '.'; + } + $count++; + } + } + $return .= '
'; + return $return; + } + + /** + * alias from apPageHelper::getConfig() + */ + public function getConfigName($name) + { + return apPageHelper::getConfigName($name); + } + + /** + * alias from apPageHelper::getConfig() + */ + public function getConfig($name) + { + return apPageHelper::getConfig($name); + } + + /** + * get Value of configuration based on actived theme + */ + public function getPanelConfig($key, $default = '', $id_lang = null) + { + if (Tools::getIsset($key)) { + # validate module + return Tools::getValue($key); + } + + $cookie = LeoFrameworkHelper::getCookie(); + + if (isset($cookie[$this->themeCookieName.'_'.$key])) { + return $cookie[$this->themeCookieName.'_'.$key]; + } + + unset($default); + return Configuration::get($this->getConfigName($key), $id_lang); + } + + public function generateLeoHtmlMessage() + { + $html = ''; + if (count($this->_confirmations)) { + foreach ($this->_confirmations as $string) { + $html .= $this->displayConfirmation($string); + } + } + if (count($this->_errors)) { + $html .= $this->displayError($this->_errors); + } + if (count($this->_warnings)) { + $html .= $this->displayWarning($this->_warnings); + } + return $html; + } + + /** + * Common method + * Resgister all hook for module + */ + public function registerLeoHook() + { + $res = true; + $res &= $this->registerHook('header'); + $res &= $this->registerHook('actionShopDataDuplication'); + $res &= $this->registerHook('displayBackOfficeHeader'); + $res &= $this->registerHook('moduleroutes'); + foreach (ApPageSetting::getHook('all') as $value) { + $res &= $this->registerHook($value); + } + # register hook to show when paging + $this->registerHook('pagebuilderConfig'); + + # register hook to show category and tags of product + $this->registerHook('displayProductInformation'); + + # register hook again to after install/change theme + $this->registerHook('actionObjectShopUpdateAfter'); + + # Multishop create new shop + $this->registerHook('actionAdminShopControllerSaveAfter'); + + $this->registerHook('displayProductButtons'); + $this->registerHook('displayReassurance'); + $this->registerHook('displayLeoProfileProduct'); + # MoveEndHeader + $this->registerHook('actionModuleRegisterHookAfter'); + #select product layout + $this->registerHook('actionObjectProductUpdateAfter'); + $this->registerHook('displayAdminProductsExtra'); + #select category layout + $this->registerHook('actionObjectCategoryUpdateAfter'); + $this->registerHook('displayBackOfficeCategory'); + + //DONGND:: register hook for apshortcode + $this->registerHook('displayApSC'); + $this->registerHook('actionAdminControllerSetMedia'); + return $res; + } + + /** + * @Action Create new shop, choose theme then auto restore datasample. + */ + public function hookActionAdminShopControllerSaveAfter($param) + { + if (Tools::getIsset('controller') !== false && Tools::getValue('controller') == 'AdminShop' + && Tools::getIsset('submitAddshop') !== false && Tools::getValue('submitAddshop') + && Tools::getIsset('theme_name') !== false && Tools::getValue('theme_name')) { + $shop = $param['return']; + + if (file_exists(_PS_MODULE_DIR_.'appagebuilder/libs/LeoDataSample.php')) { + require_once(_PS_MODULE_DIR_.'appagebuilder/libs/LeoDataSample.php'); + $sample = new Datasample(); + apPageHelper::$id_shop = $shop->id; + $sample->_id_shop = $shop->id; + $sample->processImport('appagebuilder'); + } + } + } + + public function hookDisplayBackOfficeCategory($params) + { + + if (Validate::isLoadedObject($category = new Category((int)Tools::getValue('id_category')))) { + // validate module + unset($category); + + $id_shop = Context::getContext()->shop->id; + + $category_layouts = array(); + $id_category = Tools::getValue('id_category'); + + if (is_dir(apPageHelper::getConfigDir('theme_profiles'))) { + //DONGND:: fix get list product list via database + $sql = 'SELECT * FROM '._DB_PREFIX_.'appagebuilder_products p + INNER JOIN '._DB_PREFIX_.'appagebuilder_products_shop ps on(p.id_appagebuilder_products = ps.id_appagebuilder_products) WHERE ps.id_shop='.(int)$id_shop; + $category_layouts = Db::getInstance()->executeS($sql); + } + + $extrafied = array(); + $data_fields = array(); + + if (Configuration::get('APPAGEBUILDER_CATEGORY_TEXTEXTRA') || Configuration::get('APPAGEBUILDER_CATEGORY_EDITOREXTRA')) { + $sql = 'SHOW FIELDS FROM `'._DB_PREFIX_.'appagebuilder_extracat' .'`'; + $result = Db::getInstance()->executeS($sql); + + $rows = Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'appagebuilder_extracat' .'` WHERE id_category="'.(int)$id_category.'" AND id_shop="'.(int)$id_shop.'"'); + + foreach ($result as $value) { + if ($value['Field'] != 'id_category' && $value['Field'] != 'id_shop' && $value['Field'] != 'id_lang') { + $extrafied[$value['Field']] = $value['Type']; + foreach ($rows as $row) { + $data_fields[$value['Field']][$row['id_lang']] = $row[$value['Field']]; + } + } + } + } + + $this->context->smarty->assign(array( + 'category_layouts' => $category_layouts, + 'apextras' => $extrafied, + 'id_lang_default' => $this->default_language['id_lang'], + 'languages' => $this->languages, + 'data_fields' => $data_fields, + 'current_layout' => Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('SELECT page from `'._DB_PREFIX_.'appagebuilder_page` where id_category = \''.(int)$id_category.'\' AND id_shop = \''.(int)$id_shop.'\'') + )); + + return $this->display(__FILE__, 'categoryExtra.tpl'); + } + } + + public function hookActionObjectCategoryUpdateAfter($params) + { + $id_category = Tools::getValue('id_category'); + //DONGND:: fix when change status category at category list (BO) + if (isset($id_category) && $id_category) { + $aplayout = Tools::getValue('aplayout'); + $id_shop = Context::getContext()->shop->id; + $sql = 'SELECT page from `'._DB_PREFIX_.'appagebuilder_page` where id_category = \''.(int)$id_category.'\' AND id_shop = \''.(int)$id_shop.'\''; + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql); + + if ($result) { + if ($aplayout == 'default') { + Db::getInstance()->execute('DELETE from `'._DB_PREFIX_.'appagebuilder_page` where id_category = \''.(int)$id_category.'\' and id_shop=\''.(int)$id_shop.'\''); + } else { + Db::getInstance()->execute('UPDATE `'._DB_PREFIX_.'appagebuilder_page` set page = \''.pSQL($aplayout).'\' where id_category = \''.(int)$id_category.'\' and id_shop=\''.(int)$id_shop.'\''); + } + } else { + if ($aplayout != 'default') { + Db::getInstance()->execute('INSERT INTO `'._DB_PREFIX_.'appagebuilder_page` (`id_product`,`id_category`,`page`,`id_shop`) VALUES (0,'.(int)$id_category.',\''.pSQL($aplayout).'\','.(int)$id_shop.')'); + } + } + if (Configuration::get('APPAGEBUILDER_CATEGORY_TEXTEXTRA') || Configuration::get('APPAGEBUILDER_CATEGORY_EDITOREXTRA')) { + //save for extrafield + $sql = 'SHOW FIELDS FROM `'._DB_PREFIX_.'appagebuilder_extracat' .'`'; + $result = Db::getInstance()->executeS($sql); + $extrafied = array(); + foreach ($result as $value) { + if ($value['Field'] != 'id_category' && $value['Field'] != 'id_shop' && $value['Field'] != 'id_lang') { + $extrafied[] = $value['Field']; + } + } + if ($extrafied) { + foreach ($this->languages as $lang) { + $checkExist = Db::getInstance()->getValue('SELECT COUNT(*) FROM `'._DB_PREFIX_.'appagebuilder_extracat' .'` WHERE id_shop="'.(int)$id_shop.'" AND id_category = "'.(int)$id_category.'" AND id_lang="'.(int)$lang['id_lang'].'"'); + if ($checkExist) { + $sql = ''; + foreach ($extrafied as $value) { + $sql .= (($sql=='')?'':','). '`'.bqSQL($value).'`="'.pSQL(Tools::getValue($value.'_'.$lang['id_lang'])).'"'; + } + $sql = 'UPDATE `'._DB_PREFIX_.'appagebuilder_extracat' .'` SET '.$sql.' WHERE id_shop="'.(int)$id_shop.'" AND id_category = "'.(int)$id_category.'" AND id_lang="'.(int)$lang['id_lang'].'"'; + } else { + $sql = 'INSERT INTO `'._DB_PREFIX_.'appagebuilder_extracat' .'` (`id_category`, `id_shop`, `id_lang`'; + $sql1 = ' VALUES ("'.(int)$id_category.'","'.(int)$id_shop.'","'.(int)$lang['id_lang'].'"'; + foreach ($extrafied as $value) { + $sql .= ',`'.bqSQL($value).'`'; + $sql1 .= ',"'.((Tools::getValue($value.'_'.$lang['id_lang'])=='')? pSQL(Tools::getValue($value.'_'.$this->default_language['id_lang'])) : pSQL(Tools::getValue($value.'_'.$lang['id_lang']))).'"'; + } + $sql = $sql.')'.$sql1.')'; + } + //echo $sql.'
'; + Db::getInstance()->execute($sql); + } + } + } + } + //die; + } + + public function hookfilterCategoryContent($params) + { + $id_category = Tools::getValue('id_category'); + $id_shop = Context::getContext()->shop->id; + + if (Configuration::get('APPAGEBUILDER_CATEGORY_TEXTEXTRA') || Configuration::get('APPAGEBUILDER_CATEGORY_EDITOREXTRA')) { + $rows = Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'appagebuilder_extracat' .'` WHERE id_category="'.(int)$id_category.'" AND id_shop="'.(int)$id_shop.'" AND id_lang="'.(int)$this->default_language['id_lang'].'"'); + foreach ($rows as $value) { + foreach ($value as $k => $v) { + if ($k != 'id_category' && $k != 'id_shop' && $k != 'id_lang') { + $params['object'][$k] = $v; + } + } + } + } + + //layout + $sql = 'SELECT page from `'._DB_PREFIX_.'appagebuilder_page` where id_category = \''.(int)$id_category.'\' AND id_shop = \''.(int)$id_shop.'\''; + $layout = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql); + $params['object']['categoryLayout'] = $layout; + + return $params; + } + + public function hookActionObjectProductUpdateAfter($params) + { + $id_product = Tools::getValue('id_product'); + + //DONGND:: fix when change status product at product list (BO) + if (isset($id_product) && $id_product) { + $aplayout = Tools::getValue('aplayout'); + $id_shop = Context::getContext()->shop->id; + $sql = 'SELECT * from `'._DB_PREFIX_.'appagebuilder_page` WHERE id_product = '.(int)$id_product.' AND id_shop = '.(int)$id_shop; + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql); + + if ($result) { + if ($aplayout == 'default') { + Db::getInstance()->execute('DELETE from `'._DB_PREFIX_.'appagebuilder_page` WHERE id_product = '.(int)$id_product.' and id_shop='.(int)$id_shop); + } else { + Db::getInstance()->execute('UPDATE `'._DB_PREFIX_.'appagebuilder_page` SET page = "'.pSQL($aplayout).'" WHERE id_product = '.(int)$id_product.' and id_shop='.(int)$id_shop); + } + } else { + if ($aplayout != 'default') { + Db::getInstance()->execute('INSERT INTO `'._DB_PREFIX_.'appagebuilder_page` (`id_product`,`id_category`,`page`,`id_shop`) VALUES ('.(int)$id_product.',0,\''.pSQL($aplayout).'\','.(int)$id_shop.')'); + } + } + + if (Configuration::get('APPAGEBUILDER_PRODUCT_TEXTEXTRA') || Configuration::get('APPAGEBUILDER_PRODUCT_EDITOREXTRA')) { + //save for extrafield + $sql = 'SHOW FIELDS FROM `'._DB_PREFIX_.'appagebuilder_extrapro' .'`'; + $result = Db::getInstance()->executeS($sql); + $extrafied = array(); + foreach ($result as $value) { + if ($value['Field'] != 'id_product' && $value['Field'] != 'id_shop' && $value['Field'] != 'id_lang') { + $extrafied[] = $value['Field']; + } + } + if ($extrafied) { + $form = Tools::getValue('form'); + $tab_hooks = $form['tab_hooks']; + foreach ($this->languages as $lang) { + $checkExist = Db::getInstance()->getValue('SELECT COUNT(*) FROM `'._DB_PREFIX_.'appagebuilder_extrapro' .'` WHERE id_shop="'.(int)$id_shop.'" AND id_product = "'.(int)$id_product.'" AND id_lang="'.(int)$lang['id_lang'].'"'); + if ($checkExist) { + $sql = ''; + foreach ($extrafied as $value) { + $sql .= (($sql=='')?'':',').'`'.bqSQL($value).'`="'.pSQL($tab_hooks[$value][$lang['id_lang']]).'"'; + } + $sql = 'UPDATE `'._DB_PREFIX_.'appagebuilder_extrapro' .'` SET '.$sql.' WHERE id_shop="'.(int)$id_shop.'" AND id_product = "'.(int)$id_product.'" AND id_lang="'.(int)$lang['id_lang'].'"'; + } else { + $sql = 'INSERT INTO `'._DB_PREFIX_.'appagebuilder_extrapro' .'` (`id_product`, `id_shop`, `id_lang`'; + $sql1 = ' VALUES ("'.(int)$id_product.'","'.(int)$id_shop.'","'.(int)$lang['id_lang'].'"'; + foreach ($extrafied as $value) { + $sql .= ',`'.bqSQL($value).'`'; + $sql1 .= ',"'.pSQL(($tab_hooks[$value][$lang['id_lang']]=='')?pSQL($tab_hooks[$value][$this->default_language['id_lang']]) : pSQL($tab_hooks[$value][$lang['id_lang']])).'"'; + } + $sql = $sql.')'.$sql1.')'; + } + //echo $sql; + Db::getInstance()->execute($sql); + } + } + } + } + } + + public function hookDisplayAdminProductsExtra($params) + { + if (Validate::isLoadedObject($product = new Product((int)$params['id_product']))) { + // validate module + unset($product); + + $id_shop = Context::getContext()->shop->id; + $extrafied = array(); + $data_fields = array(); + + if (Configuration::get('APPAGEBUILDER_PRODUCT_TEXTEXTRA') || Configuration::get('APPAGEBUILDER_PRODUCT_EDITOREXTRA')) { + $sql = 'SHOW FIELDS FROM `'._DB_PREFIX_.'appagebuilder_extrapro' .'`'; + $result = Db::getInstance()->executeS($sql); + + $rows = Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'appagebuilder_extrapro' .'` WHERE id_product="'.(int)$params['id_product'].'" AND id_shop="'.(int)$id_shop.'"'); + + foreach ($result as $value) { + if ($value['Field'] != 'id_product' && $value['Field'] != 'id_shop' && $value['Field'] != 'id_lang') { + $extrafied[$value['Field']] = $value['Type']; + foreach ($rows as $row) { + $data_fields[$value['Field']][$row['id_lang']] = $row[$value['Field']]; + } + } + } + } +// $product_layouts = array(); + $sql = 'SELECT a.`plist_key`, a.`name` FROM `'._DB_PREFIX_.'appagebuilder_details` AS a INNER JOIN `'._DB_PREFIX_.'appagebuilder_details_shop` AS b ON a.`id_appagebuilder_details` = b.`id_appagebuilder_details' .'` WHERE b.id_shop= "'.(int)$id_shop.'"'; + $list = Db::getInstance()->executeS($sql); + + $this->context->smarty->assign(array( + 'product_layouts' => $list, +// 'default_plist' => $default_plist, + 'id_product' => (int)Tools::getValue('id_product'), + 'apextras' => $extrafied, + 'languages' => $this->languages, + 'data_fields' => $data_fields, + 'default_language' => $this->default_language, + 'current_layout' => Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('SELECT page from `'._DB_PREFIX_.'appagebuilder_page` where id_product = \''.(int)$params['id_product'].'\' AND id_shop = \''.(int)$id_shop.'\'') + )); + + return $this->display(__FILE__, 'productExtra.tpl'); + } + } + + public function hookfilterProductContent($params) + { + $id_product = Tools::getValue('id_product'); + $id_shop = Context::getContext()->shop->id; + //extra fields + if (Configuration::get('APPAGEBUILDER_PRODUCT_TEXTEXTRA') || Configuration::get('APPAGEBUILDER_PRODUCT_EDITOREXTRA')) { + $rows = Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'appagebuilder_extrapro' .'` WHERE id_product="'.(int)$id_product.'" AND id_shop="'.(int)$id_shop.'" AND id_lang="'.(int)$this->default_language['id_lang'].'"'); + + foreach ($rows as $value) { + foreach ($value as $k => $v) { + if ($k != 'id_product' && $k != 'id_shop' && $k != 'id_lang') { + $params['object'][$k] = $v; + } + } + } + } + //DONGND:: get layout of product detail by parameter in URL + if (Tools::getValue('layout')) { + $sql = 'SELECT a.`plist_key` FROM `'._DB_PREFIX_.'appagebuilder_details` AS a INNER JOIN `'._DB_PREFIX_.'appagebuilder_details_shop` AS b ON a.`id_appagebuilder_details` = b.`id_appagebuilder_details' .'` WHERE b.`id_shop` = "'.(int)$id_shop.'" AND a.`plist_key` = "'.pSQL(Tools::getValue('layout')).'"'; + $layout = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql); + if ($layout) { + $params['object']['productLayout'] = $layout; + return $params; + } + } + //layout + $sql = 'SELECT page from `'._DB_PREFIX_.'appagebuilder_page` where id_product = \''.(int)$id_product.'\' AND id_shop = \''.(int)$id_shop.'\''; + $layout = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql); + //get default + if (!$layout) { + $sql = 'SELECT a.`plist_key` FROM `'._DB_PREFIX_.'appagebuilder_details` AS a INNER JOIN `'._DB_PREFIX_.'appagebuilder_details_shop` AS b ON a.`id_appagebuilder_details` = b.`id_appagebuilder_details' .'` WHERE b.`id_shop` = "'.(int)$id_shop.'" AND b.`active` = 1'; + $layout = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql); + } + $params['object']['productLayout'] = $layout; + + return $params; + } + + /** + * PERMISSION ACCOUNT demo@demo.com + */ + public function getPermission($variable, $employee = null) + { + if($variable == 'configure') + { + // Allow see form if permission is : configure, view + $configure = Module::getPermissionStatic($this->id, 'configure', $employee); + $view = Module::getPermissionStatic($this->id, 'view', $employee); + return ($configure || $view); + } + + return Module::getPermissionStatic($this->id, $variable, $employee); + } + + /** + * PERMISSION ACCOUNT demo@demo.com + */ + public function access($action) + { + $employee = null; + return Module::getPermissionStatic($this->id, $action, $employee); + } +} diff --git a/modules/appagebuilder/classes/ApPageBuilderDetailsModel.php b/modules/appagebuilder/classes/ApPageBuilderDetailsModel.php new file mode 100644 index 00000000..02a11465 --- /dev/null +++ b/modules/appagebuilder/classes/ApPageBuilderDetailsModel.php @@ -0,0 +1,145 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/shortcodes.php'); +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageSetting.php'); + +class ApPageBuilderDetailsModel extends ObjectModel +{ + public $name; + public $params; + public $type; + public $active; + public $plist_key; + public $class_detail; + public $url_img_preview; + /** + * @see ObjectModel::$definition + */ + public static $definition = array( + 'table' => 'appagebuilder_details', + 'primary' => 'id_appagebuilder_details', + 'multilang' => false, + 'multishop' => true, + 'fields' => array( + 'name' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255), + 'plist_key' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255), + 'type' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'), + 'active' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'), + 'params' => array('type' => self::TYPE_HTML), + 'class_detail' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255), + 'url_img_preview' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255), + ) + ); + + public function getAllProductProfileByShop() + { + $context = Context::getContext(); + $id_shop = $context->shop->id; + $where = ' WHERE id_shop='.(int)$id_shop; + $sql = 'SELECT p.*, ps.* + FROM '._DB_PREFIX_.'appagebuilder_details p + INNER JOIN '._DB_PREFIX_.'appagebuilder_details_shop ps ON (ps.id_appagebuilder_details = p.id_appagebuilder_details)' + .$where; + return Db::getInstance()->executes($sql); + } + + public function __construct($id = null, $id_lang = null, $id_shop = null, Context $context = null) + { + // validate module + unset($context); + parent::__construct($id, $id_lang, $id_shop); + } + + public function add($autodate = true, $null_values = false) + { + $id_shop = apPageHelper::getIDShop(); + $res = parent::add($autodate, $null_values); + $res &= Db::getInstance()->execute(' + INSERT INTO `'._DB_PREFIX_.'appagebuilder_details_shop` (`id_shop`, `id_appagebuilder_details`) + VALUES('.(int)$id_shop.', '.(int)$this->id.')'); + if (Db::getInstance()->getValue('SELECT COUNT(p.`id_appagebuilder_details`) AS total FROM `' + ._DB_PREFIX_.'appagebuilder_details` p INNER JOIN `' + ._DB_PREFIX_.'appagebuilder_details_shop` ps ON(p.id_appagebuilder_details = ps.id_appagebuilder_details) WHERE id_shop=' + .(int)$id_shop) <= 1) { + $this->deActiveAll(); + } else if ($this->active) { + $this->deActiveAll(); + } + return $res; + } + + public function toggleStatus() + { + $this->deActiveAll(); + return true; + } + + public function deActiveAll() + { + $context = Context::getContext(); + $id_shop = $context->shop->id; + $sql = 'UPDATE '._DB_PREFIX_.'appagebuilder_details_shop SET active=0 where id_shop='.(int)$id_shop; + Db::getInstance()->execute($sql); + $where = ' WHERE ps.id_shop='.(int)$id_shop." AND ps.id_appagebuilder_details = '".(int)$this->id."'"; + Db::getInstance()->execute('UPDATE `'._DB_PREFIX_.'appagebuilder_details_shop` ps set ps.active = 1 '.$where); + } + + public static function getActive() + { + $id_shop = Context::getContext()->shop->id; + if (Tools::getIsset('plist_key') && Tools::getValue('plist_key')) { + // validate module + $where = " p.plist_key='".pSQL(Tools::getValue('plist_key'))."' and ps.id_shop=".(int)$id_shop; + } else { + // validate module + $where = ' ps.active=1 and ps.id_shop='.(int)$id_shop; + } + + $sql = 'SELECT * FROM '._DB_PREFIX_.'appagebuilder_details p + INNER JOIN '._DB_PREFIX_.'appagebuilder_details_shop ps on(p.id_appagebuilder_details = ps.id_appagebuilder_details) WHERE ' + .pSQL($where); + return Db::getInstance()->getRow($sql); + } + + public function delete() + { + $result = parent::delete(); + + if ($result) { + if (isset($this->def['multishop']) && $this->def['multishop'] == true) { + # DELETE RECORD FORM TABLE _SHOP + $id_shop_list = Shop::getContextListShopID(); + if (count($this->id_shop_list)) { + $id_shop_list = $this->id_shop_list; + } + + $id_shop_list = array_map('intval', $id_shop_list); + //DONGND:: fix sql + $id_shop_list = implode(', ', $id_shop_list); + + Db::getInstance()->delete($this->def['table'].'_shop', '`'.$this->def['primary'].'`='. + (int)$this->id.' AND id_shop IN ('.pSQL($id_shop_list).')'); + } + } + + return $result; + } +} diff --git a/modules/appagebuilder/classes/ApPageBuilderHookModel.php b/modules/appagebuilder/classes/ApPageBuilderHookModel.php new file mode 100644 index 00000000..6df194ad --- /dev/null +++ b/modules/appagebuilder/classes/ApPageBuilderHookModel.php @@ -0,0 +1,58 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageBuilderProfilesModel.php'); + +class ApPageBuilderHookModel +{ + public $profile_data; + public $profile_param; + public $hook; + + public function create() + { + $this->profile_data = ApPageBuilderProfilesModel::getActiveProfile('index'); + $this->profile_param = Tools::jsonDecode($this->profile_data['params'], true); + $this->fullwidth_index_hook = $this->fullwidthIndexHook(); + $this->fullwidth_other_hook = $this->fullwidthOtherHook(); + return $this; + } + + public function fullwidthIndexHook() + { + return isset($this->profile_param['fullwidth_index_hook']) ? $this->profile_param['fullwidth_index_hook'] : ApPageSetting::getIndexHook(3); + } + + public function fullwidthOtherHook() + { + return isset($this->profile_param['fullwidth_other_hook']) ? $this->profile_param['fullwidth_other_hook'] : ApPageSetting::getOtherHook(3); + } + + public function fullwidthHook($hook_name, $page) + { + if ($page == 'index') { + // validate module + return isset($this->fullwidth_index_hook[$hook_name]) ? $this->fullwidth_index_hook[$hook_name] : 0; + } else { + # other page + return isset($this->fullwidth_other_hook[$hook_name]) ? $this->fullwidth_other_hook[$hook_name] : 0; + } + } +} diff --git a/modules/appagebuilder/classes/ApPageBuilderModel.php b/modules/appagebuilder/classes/ApPageBuilderModel.php new file mode 100644 index 00000000..acbf76a3 --- /dev/null +++ b/modules/appagebuilder/classes/ApPageBuilderModel.php @@ -0,0 +1,404 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/shortcodes.php'); +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageSetting.php'); + +class ApPageBuilderModel extends ObjectModel +{ + public $hook_name; + public $params; + public $id_appagebuilder_positions; + public $id_appagebuilder_shortcode; + /** + * @see ObjectModel::$definition + */ + public static $definition = array( + 'table' => 'appagebuilder', + 'primary' => 'id_appagebuilder', + 'multilang' => true, + 'multishop' => true, + 'fields' => array( + 'hook_name' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255), + 'id_appagebuilder_positions' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), + 'params' => array('type' => self::TYPE_HTML, 'lang' => true), + 'id_appagebuilder_shortcode' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), + ) + ); + + public function __construct($id = null, $id_lang = null, $id_shop = null, Context $context = null) + { + # validate module + unset($context); + parent::__construct($id, $id_lang, $id_shop); + } + + //DONGND:: get id by id shortcode + public static function getIdByIdShortCode($id_shortcode) + { + if (!$id_shortcode) { + return false; + } + $sql = 'SELECT id_appagebuilder FROM '._DB_PREFIX_.'appagebuilder WHERE id_appagebuilder_shortcode = ' . (int)$id_shortcode; + $result = Db::getInstance()->getRow($sql); + + if (!$result) { + return false; + } + + return $result['id_appagebuilder']; + } + + public function getIdbyHookName($hook_name, $position_id) + { + $context = Context::getContext(); + $id_shop = (int)$context->shop->id; + $sql = 'SELECT p.id_appagebuilder + FROM '._DB_PREFIX_.'appagebuilder p + LEFT JOIN '._DB_PREFIX_.'appagebuilder_shop ps ON (ps.id_appagebuilder = p.id_appagebuilder) + WHERE ps.id_shop = '.(int)$id_shop.' + AND hook_name=\''.pSql($hook_name).'\' + AND p.id_appagebuilder_positions='.(int)$position_id.' ORDER BY p.id_appagebuilder'; + $result = Db::getInstance()->executeS($sql); + if (!$result) { + return false; + } + + foreach ($result as $value) { + $sql = 'DELETE FROM '._DB_PREFIX_.'appagebuilder_shop + WHERE id_appagebuilder IN(SELECT id_appagebuilder + FROM '._DB_PREFIX_.'appagebuilder + WHERE hook_name=\''.pSql($hook_name).'\' + AND id_appagebuilder_positions='.(int)$position_id.' + AND id_appagebuilder != '.(int)$value['id_appagebuilder'].')'; + Db::getInstance()->execute($sql); + + $sql = 'DELETE FROM '._DB_PREFIX_.'appagebuilder + WHERE hook_name=\''.pSql($hook_name).'\' + AND id_appagebuilder_positions='.(int)$position_id.' + AND id_appagebuilder != '.(int)$value['id_appagebuilder']; + Db::getInstance()->execute($sql); + + return $value['id_appagebuilder']; + } + } + + public function getIdbyHookNameAndProfile($hook_name, $profile, $id_lang) + { + $context = Context::getContext(); + $id_shop = (int)$context->shop->id; + + //$id_lang = (int)$id_lang; + if (!$profile->header && !$profile->content && !$profile->footer && !$profile->product) { + return array(); + } + + $arr = array($profile->header, $profile->content, $profile->footer, $profile->product); + + $sql = 'SELECT p.id_appagebuilder, pl.params + FROM '._DB_PREFIX_.'appagebuilder p + LEFT JOIN '._DB_PREFIX_.'appagebuilder_shop ps ON (ps.id_appagebuilder = p.id_appagebuilder AND id_shop='.(int)$id_shop.') + LEFT JOIN '._DB_PREFIX_.'appagebuilder_lang pl ON (p.id_appagebuilder = pl.id_appagebuilder AND pl.id_lang='.(int)$id_lang.') + WHERE p.`hook_name`=\''.$hook_name.'\' + AND ps.id_shop='.(int)$id_shop.' + AND pl.id_lang='.(int)$id_lang.' + AND p.id_appagebuilder_positions IN ('. pSQL(implode(',', array_map('intval', $arr))).') + ORDER BY p.id_appagebuilder'; + return Db::getInstance()->getRow($sql); + } + + /** + * getListPositisionByType + * @param type $type = {all, header, content, footer, product} + * @return type + */ + public function getListPositisionByType($type = 'all', $id_shop = null) + { + $str = Tools::strtolower($type); + $sql = 'SELECT p.* FROM `'._DB_PREFIX_.'appagebuilder_positions` p' + .' INNER JOIN `'._DB_PREFIX_.'appagebuilder_positions_shop` ps ON (p.id_appagebuilder_positions = ps.id_appagebuilder_positions)'; + if ($type != 'all') { + $sql .= ' WHERE p.position=\''.pSQL($str).'\' AND ps.id_shop='.(int)$id_shop; + } + + return Db::getInstance()->executeS($sql, 1); + } + + public function add($autodate = true, $null_values = false) + { + $id_shop = apPageHelper::getIDShop(); + $res = parent::add($autodate, $null_values); + $res &= Db::getInstance()->execute(' + INSERT INTO `'._DB_PREFIX_.'appagebuilder_shop` (`id_shop`, `id_appagebuilder`) + VALUES('.(int)$id_shop.', '.(int)$this->id.')'); + return $res; + } + + public function save($null_values = false, $autodate = true) + { + # validate module + unset($null_values); + unset($autodate); + $context = Context::getContext(); + $this->id_shop = $context->shop->id; + return parent::save(); + } + + public function parseData($hook_name, $data, $profile_param) + { + ApShortCodesBuilder::$is_front_office = 1; + ApShortCodesBuilder::$is_gen_html = 1; + ApShortCodesBuilder::$profile_param = $profile_param; + $ap_helper = new ApShortCodesBuilder(); + ApShortCodesBuilder::$hook_name = $hook_name; + $result = $ap_helper->parse($data); + return $result; + } + + /** + * Get all item by position include information: hooks postion and data + * @param type $pos + * @param type $id_position + * @param type $id_profile + * @param type $is_font + * @param type $id_lang + * @return type + */ + public function getAllItemsByPosition($pos, $id_position, $id_profile = 0, $is_font = 0, $id_lang = 0) + { + $context = Context::getContext(); + $id_shop = (int)$context->shop->id; + $id_position = (int)$id_position; + $id_profile = (int)$id_profile; + $where = ' WHERE ps.id_shop='.(int)$id_shop.' AND pp.id_appagebuilder_positions='.(int)$id_position; + if ($id_profile) { + $where .= ' AND ppr.id_appagebuilder_profiles='.(int)$id_profile; + } + if ($id_lang) { + $where .= ' AND pl.id_lang = '.(int)$id_lang; + } else { +// $id_lang = $context->language->id; // default in admin account + $id_lang = (int)Configuration::get('PS_LANG_DEFAULT'); // default at frontend + } + $sql = 'SELECT p.*, pl.params, pl.id_lang + FROM `'._DB_PREFIX_.'appagebuilder` p + LEFT JOIN `'._DB_PREFIX_.'appagebuilder_shop` ps ON (ps.id_appagebuilder = p.id_appagebuilder) + LEFT JOIN `'._DB_PREFIX_.'appagebuilder_lang` pl ON (pl.id_appagebuilder = p.id_appagebuilder) + LEFT JOIN `'._DB_PREFIX_.'appagebuilder_positions` pp ON (p.id_appagebuilder_positions=pp.id_appagebuilder_positions) + LEFT JOIN `'._DB_PREFIX_.'appagebuilder_profiles` ppr ON (ppr.`'.bqSQL($pos).'`=pp.id_appagebuilder_positions) + '.pSql($where).' ORDER BY p.id_appagebuilder'; + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); + + $id_langs = Language::getLanguages(true, false, true); + # FIX - Only get language data valid + foreach ($result as $key => $val) { + if (isset($val['id_lang']) && !in_array($val['id_lang'], $id_langs)) { + unset($result[$key]); + } + } + + $data_lang = array(); + if ($is_font) { + foreach ($result as $row) { + $data_lang[$row['hook_name']] = $row['params']; + } + return $data_lang; + } + $ap_helper = new ApShortCodesBuilder(); + ApShortCodesBuilder::$is_front_office = $is_font; + ApShortCodesBuilder::$is_gen_html = 1; + foreach ($result as $row) { + if (isset($data_lang[$row['id_appagebuilder']])) { + $data_lang[$row['id_appagebuilder']]['params'][$row['id_lang']] = $row['params']; + } else { + $data_lang[$row['id_appagebuilder']] = array( + 'id' => $row['id_appagebuilder'], + 'hook_name' => $row['hook_name'], + ); + $data_lang[$row['id_appagebuilder']]['params'][$row['id_lang']] = $row['params']; + } + } + //$data_hook = array_flip(ApPageSetting::getHookHome()); + $hook_config = Configuration::get('APPAGEBUILDER_' . Tools::strtoupper($pos).'_HOOK'); + $hook_config = explode(',', $hook_config ? $hook_config : ApPageSetting::getHook($pos)); + $data_hook = array_flip($hook_config); + foreach ($data_lang as $row) { + //process params + foreach ($row['params'] as $key => $value) { + ApShortCodesBuilder::$lang_id = $key; + if ($key == $id_lang) { + ApShortCodesBuilder::$is_gen_html = 1; + $row['content'] = $ap_helper->parse($value); + } else { + ApShortCodesBuilder::$is_gen_html = 0; + $ap_helper->parse($value); + } + } + $data_hook[$row['hook_name']] = $row; + } + return array('content' => $data_hook, 'dataForm' => ApShortCodesBuilder::$data_form); + } + + /** + * Get all items - datas of all hooks by shop Id, lang Id for front-end or back-end + * @param type $list_pos_id array + */ + public function getAllItemsByPositionId($list_pos_id) + { + if ($list_pos_id) { + $sql = 'SELECT DISTINCT(id_appagebuilder) as id FROM `'._DB_PREFIX_.'appagebuilder` p + WHERE id_appagebuilder_positions IN('. pSQL(implode(',', array_map('intval', $list_pos_id))).')'; + return Db::getInstance()->executes($sql); + } + return array(); + } + + /** + * Get all items - datas of all hooks by shop Id, lang Id for front-end or back-end + * @param type $id_profiles + * @param type $is_font (=0: for back-end; =1: for front-end) + * @param type $id_lang + * @return type + */ + public function getAllItems($profile, $is_font = 0, $id_lang = 0) + { + //print_r("Input: $id_profiles - $is_font - $id_lang"); 2-1-1 + $context = Context::getContext(); +// $id_profiles = (int)$profile['id_appagebuilder_profiles']; + $id_shop = (int)$context->shop->id; + $id_lang = $id_lang ? (int)$id_lang : (int)$context->language->id; + if (!$profile['header'] && !$profile['content'] && !$profile['footer'] && !$profile['product']) { + return array(); + } + + $arr = array($profile['header'], $profile['content'], $profile['footer'], $profile['product']); + + $sql = 'SELECT p.*, pl.params, pl.id_lang + FROM '._DB_PREFIX_.'appagebuilder p + LEFT JOIN '._DB_PREFIX_.'appagebuilder_shop ps ON (ps.id_appagebuilder = p.id_appagebuilder AND id_shop='.(int)$id_shop.') + LEFT JOIN '._DB_PREFIX_.'appagebuilder_lang pl ON (pl.id_appagebuilder = p.id_appagebuilder) + WHERE + pl.id_lang='.(int)$id_lang.' + AND ps.id_shop='.(int)$id_shop.' + AND p.id_appagebuilder_positions IN ('. pSQL(implode(',', array_map('intval', $arr))).') + ORDER BY p.id_appagebuilder'; + + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); + $data_lang = array(); + if ($is_font) { + foreach ($result as $row) { + $data_lang[$row['hook_name']] = $row['params']; + } + return $data_lang; + } + $ap_helper = new ApShortCodesBuilder(); + ApShortCodesBuilder::$is_front_office = $is_font; + ApShortCodesBuilder::$is_gen_html = 1; + foreach ($result as $row) { + if (isset($data_lang[$row['id_appagebuilder']])) { + $data_lang[$row['id_appagebuilder']]['params'][$row['id_lang']] = $row['params']; + } else { + $data_lang[$row['id_appagebuilder']] = array( + 'id' => $row['id_appagebuilder'], + 'hook_name' => $row['hook_name'], + ); + $data_lang[$row['id_appagebuilder']]['params'][$row['id_lang']] = $row['params']; + } + } + $data_hook = array_flip(ApPageSetting::getHookHome()); + foreach ($data_lang as $row) { + //process params + foreach ($row['params'] as $key => $value) { + ApShortCodesBuilder::$lang_id = $key; + if ($key == $id_lang) { + ApShortCodesBuilder::$is_gen_html = 1; + $row['content'] = $ap_helper->parse($value); + } else { + ApShortCodesBuilder::$is_gen_html = 0; + $ap_helper->parse($value); + } + } + $data_hook[$row['hook_name']] = $row; + } + + return array('content' => $data_hook, 'dataForm' => ApShortCodesBuilder::$data_form); + } + + public function getAllStoreByShop() + { + return Store::getStores((int)Context::getContext()->language->id); +// $context = Context::getContext(); +// $id_shop = (int)$context->shop->id; +// $id_lang = (int)$context->language->id; +// //$where = ' WHERE id_shop="'.$id_shop.'"'; +// $sql = ' +// SELECT a.*, cl.name country, st.name state +// FROM '._DB_PREFIX_.'store a +// LEFT JOIN '._DB_PREFIX_.'country_lang cl +// ON (cl.id_country = a.id_country +// AND cl.id_lang = '.(int)$id_lang.') +// LEFT JOIN '._DB_PREFIX_.'state st +// ON (st.id_state = a.id_state) +// WHERE a.id_store IN ( +// SELECT sa.id_store +// FROM '._DB_PREFIX_.'store_shop sa +// WHERE sa.id_shop = '.(int)$id_shop.' +// )'; +// return Db::getInstance()->executes($sql); + } + + public function findOtherProfileUsePosition($id_position, $id_profile) + { + $sql = 'SELECT * FROM '._DB_PREFIX_.'appagebuilder_profiles ap + WHERE (ap.`header`='.(int)$id_position.' OR ap.`content`='.(int)$id_position.' + OR ap.`footer`='.(int)$id_position.' OR ap.`product`='.(int)$id_position.') + AND ap.`id_appagebuilder_profiles`<>'.(int)$id_profile; + return Db::getInstance()->executes($sql); + } + + public function updateAppagebuilderLang($id, $id_lang, $params) + { + //can not use psql, because pramram is import function + $data = array('params' => $params); + Db::getInstance()->update('appagebuilder_lang', $data, 'id_appagebuilder='.(int)$id.' AND id_lang='.(int)$id_lang); + } + + public function delete() + { + $result = parent::delete(); + + if ($result) { + if (isset($this->def['multishop']) && $this->def['multishop'] == true) { + # DELETE RECORD FORM TABLE _SHOP + $id_shop_list = Shop::getContextListShopID(); + if (count($this->id_shop_list)) { + $id_shop_list = $this->id_shop_list; + } + + $id_shop_list = array_map('intval', $id_shop_list); + + Db::getInstance()->delete($this->def['table'].'_shop', '`'.$this->def['primary'].'`='. + (int)$this->id.' AND id_shop IN ('. pSQL(implode(', ', $id_shop_list)).')'); + } + } + + return $result; + } +} diff --git a/modules/appagebuilder/classes/ApPageBuilderPositionsModel.php b/modules/appagebuilder/classes/ApPageBuilderPositionsModel.php new file mode 100644 index 00000000..385842e0 --- /dev/null +++ b/modules/appagebuilder/classes/ApPageBuilderPositionsModel.php @@ -0,0 +1,149 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +require_once(_PS_MODULE_DIR_.'appagebuilder/libs/Helper.php'); +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/shortcodes.php'); +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageSetting.php'); + +class ApPageBuilderPositionsModel extends ObjectModel +{ + public $name; + public $params; + public $position; + public $position_key; + /** + * @see ObjectModel::$definition + */ + public static $definition = array( + 'table' => 'appagebuilder_positions', + 'primary' => 'id_appagebuilder_positions', + 'multilang' => false, + 'multishop' => true, + 'fields' => array( + 'name' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255), + 'position' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255), + 'position_key' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255), + 'params' => array('type' => self::TYPE_HTML) + ) + ); + + public function __construct($id = null, $id_lang = null, $id_shop = null, Context $context = null) + { + // validate module + unset($context); + parent::__construct($id, $id_lang, $id_shop); +// Shop::addTableAssociation($this->table, array('type' => 'shop')); // Delete with all table_shop, Insert all shop. Remove + } + + public static function getProfileUsingPosition($id) + { + $id = (int)$id; + $sql = 'SELECT * FROM `'._DB_PREFIX_.'appagebuilder_profiles` P + WHERE + P.`header`='.(int)$id.' + OR P.`content`='.(int)$id.' + OR P.`footer`='.(int)$id.' + OR P.`product`='.(int)$id; + return Db::getInstance()->executes($sql); + } + + public function add($autodate = true, $null_values = false) + { + $id_shop = apPageHelper::getIDShop(); + $res = parent::add($autodate, $null_values); + $res &= Db::getInstance()->execute(' + INSERT INTO `'._DB_PREFIX_.'appagebuilder_positions_shop` (`id_shop`, `id_appagebuilder_positions`) + VALUES('.(int)$id_shop.', '.(int)$this->id.')'); + return $res; + } + + public function addAuto($data) + { + $id_shop = apPageHelper::getIDShop(); + + $sql = 'INSERT INTO `'._DB_PREFIX_.'appagebuilder_positions` (name, position, position_key) + VALUES("'.pSQL($data['name']).'", "'.pSQL($data['position']).'", "'.pSQL($data['position_key']).'")'; + Db::getInstance()->execute($sql); + + $id = Db::getInstance()->Insert_ID(); + + Db::getInstance()->execute('INSERT INTO `'._DB_PREFIX_.'appagebuilder_positions_shop` (`id_shop`, `id_appagebuilder_positions`) + VALUES('.(int)$id_shop.', '.(int)$id.')'); + return $id; + } + + public static function getAllPosition() + { + $sql = 'SELECT * FROM `'._DB_PREFIX_.'appagebuilder_positions`'; + return Db::getInstance()->getRow($sql); + } + + public static function getPositionById($id) + { + $sql = 'SELECT * FROM `'._DB_PREFIX_.'appagebuilder_positions` WHERE id_appagebuilder_positions='.(int)$id; + return Db::getInstance()->getRow($sql); + } + + public static function updateName($id, $name) + { + $id = (int)$id; + if ($id && $name) { + $sql = 'UPDATE '._DB_PREFIX_.'appagebuilder_positions SET name=\''.pSQL($name).'\' WHERE id_appagebuilder_positions='.(int)$id; + return Db::getInstance()->execute($sql); + } + return false; + } + + public function delete() + { + $result = parent::delete(); + + if ($result) { + if (isset($this->def['multishop']) && $this->def['multishop'] == true) { + # DELETE RECORD FORM TABLE _SHOP + $id_shop_list = Shop::getContextListShopID(); + if (count($this->id_shop_list)) { + $id_shop_list = $this->id_shop_list; + } + + $id_shop_list = array_map('intval', $id_shop_list); + + Db::getInstance()->delete($this->def['table'].'_shop', '`'.$this->def['primary'].'`='. + (int)$this->id.' AND id_shop IN ('. pSQL(implode(', ', $id_shop_list)).')'); + } + + # DELETE DATA AT OTHER TABLE + $sql = 'SELECT id_appagebuilder FROM '._DB_PREFIX_.'appagebuilder WHERE id_appagebuilder_positions = ' . (int)$this->id; + $rows = Db::getInstance()->executes($sql); + + foreach ($rows as $row) { + $obj = new ApPageBuilderModel($row['id_appagebuilder']); + $obj->delete(); + } + + # Profile not use this position + if (in_array($this->position, array('header', 'content', 'footer', 'product'))) { + $sql = 'UPDATE '._DB_PREFIX_.'appagebuilder_profiles SET `'.bqSQL($this->position).'`=0 WHERE `'.bqSQL($this->position).'`='.(int)$this->id; + Db::getInstance()->execute($sql); + } + } + return $result; + } +} diff --git a/modules/appagebuilder/classes/ApPageBuilderProductsModel.php b/modules/appagebuilder/classes/ApPageBuilderProductsModel.php new file mode 100644 index 00000000..218c4d08 --- /dev/null +++ b/modules/appagebuilder/classes/ApPageBuilderProductsModel.php @@ -0,0 +1,140 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/shortcodes.php'); +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageSetting.php'); + +class ApPageBuilderProductsModel extends ObjectModel +{ + public $name; + public $params; + public $type; + public $active; + public $plist_key; + public $class; + /** + * @see ObjectModel::$definition + */ + public static $definition = array( + 'table' => 'appagebuilder_products', + 'primary' => 'id_appagebuilder_products', + 'multilang' => false, + 'multishop' => true, + 'fields' => array( + 'name' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255), + 'plist_key' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255), + 'type' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'), + 'active' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'), + 'params' => array('type' => self::TYPE_HTML), + 'class' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255), + ) + ); + + public function getAllProductProfileByShop() + { + $context = Context::getContext(); + $id_shop = $context->shop->id; + $where = ' WHERE id_shop='.(int)$id_shop; + $sql = 'SELECT p.*, ps.* + FROM '._DB_PREFIX_.'appagebuilder_products p + INNER JOIN '._DB_PREFIX_.'appagebuilder_products_shop ps ON (ps.id_appagebuilder_products = p.id_appagebuilder_products)' + .$where; + return Db::getInstance()->executes($sql); + } + + public function __construct($id = null, $id_lang = null, $id_shop = null, Context $context = null) + { + // validate module + unset($context); + parent::__construct($id, $id_lang, $id_shop); + } + + public function add($autodate = true, $null_values = false) + { + $id_shop = apPageHelper::getIDShop(); + $res = parent::add($autodate, $null_values); + $res &= Db::getInstance()->execute(' + INSERT INTO `'._DB_PREFIX_.'appagebuilder_products_shop` (`id_shop`, `id_appagebuilder_products`) + VALUES('.(int)$id_shop.', '.(int)$this->id.')'); + if (Db::getInstance()->getValue('SELECT COUNT(p.`id_appagebuilder_products`) AS total FROM `' + ._DB_PREFIX_.'appagebuilder_products` p INNER JOIN `' + ._DB_PREFIX_.'appagebuilder_products_shop` ps ON(p.id_appagebuilder_products = ps.id_appagebuilder_products) WHERE id_shop=' + .(int)$id_shop) <= 1) { + $this->deActiveAll(); + } else if ($this->active) { + $this->deActiveAll(); + } + return $res; + } + + public function toggleStatus() + { + $this->deActiveAll(); + return true; + } + + public function deActiveAll() + { + $context = Context::getContext(); + $id_shop = $context->shop->id; + $sql = 'UPDATE '._DB_PREFIX_.'appagebuilder_products_shop SET active=0 where id_shop='.(int)$id_shop; + Db::getInstance()->execute($sql); + $where = ' WHERE ps.id_shop='.(int)$id_shop." AND ps.id_appagebuilder_products = '".(int)$this->id."'"; + Db::getInstance()->execute('UPDATE `'._DB_PREFIX_.'appagebuilder_products_shop` ps set ps.active = 1 '.$where); + } + + public static function getActive() + { + $id_shop = (int)Context::getContext()->shop->id; + if (Tools::getIsset('plist_key') && Tools::getValue('plist_key')) { + // validate module + $where = " p.plist_key='".pSQL(Tools::getValue('plist_key'))."' and ps.id_shop=".(int)$id_shop; + } else { + // validate module + $where = ' ps.active=1 and ps.id_shop='.(int)$id_shop; + } + + $sql = 'SELECT * FROM '._DB_PREFIX_.'appagebuilder_products p + INNER JOIN '._DB_PREFIX_.'appagebuilder_products_shop ps on(p.id_appagebuilder_products = ps.id_appagebuilder_products) WHERE '.$where; + return Db::getInstance()->getRow($sql); + } + + public function delete() + { + $result = parent::delete(); + + if ($result) { + if (isset($this->def['multishop']) && $this->def['multishop'] == true) { + # DELETE RECORD FORM TABLE _SHOP + $id_shop_list = Shop::getContextListShopID(); + if (count($this->id_shop_list)) { + $id_shop_list = $this->id_shop_list; + } + + $id_shop_list = array_map('intval', $id_shop_list); + + Db::getInstance()->delete($this->def['table'].'_shop', '`'.$this->def['primary'].'`='. + (int)$this->id.' AND id_shop IN ('.pSQL(implode(', ', $id_shop_list)).')'); + } + } + + return $result; + } +} diff --git a/modules/appagebuilder/classes/ApPageBuilderProfilesModel.php b/modules/appagebuilder/classes/ApPageBuilderProfilesModel.php new file mode 100644 index 00000000..1a1e43ac --- /dev/null +++ b/modules/appagebuilder/classes/ApPageBuilderProfilesModel.php @@ -0,0 +1,437 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/shortcodes.php'); +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageSetting.php'); + +class ApPageBuilderProfilesModel extends ObjectModel +{ + public $name; + public $friendly_url; + public $meta_title; + public $meta_description; + public $meta_keywords; + public $group_box; + public $params; + public $page; + public $profile_key; + public $header; + public $content; + public $footer; + public $product; + public $active; + /** + * @see ObjectModel::$definition + */ + public static $definition = array( + 'table' => 'appagebuilder_profiles', + 'primary' => 'id_appagebuilder_profiles', + 'multilang' => true, + 'multishop' => true, + 'fields' => array( + 'name' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255), + 'friendly_url' => array('type' => self::TYPE_STRING, 'size' => 255, 'lang' => true, 'validate' => 'isLinkRewrite'), + 'meta_title' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255, 'lang' => true), + 'meta_description' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255, 'lang' => true), + 'meta_keywords' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255, 'lang' => true), + 'group_box' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255), + 'page' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255), + 'profile_key' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255), + 'header' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), + 'content' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), + 'footer' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), + 'product' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), + 'params' => array('type' => self::TYPE_HTML) + ) + ); + + public function __construct($id = null, $id_lang = null, $id_shop = null, Context $context = null) + { + // validate module + unset($context); + parent::__construct($id, $id_lang, $id_shop); + $this->loadDataShop(); + } + + public function loadDataShop() + { + if ($this->def['multishop'] == true) { + $sql = 'SELECT * FROM ' ._DB_PREFIX_.$this->def['table'] . '_shop WHERE ' .$this->def['primary'] . ' =' .(int)$this->id; + $this->data_shop = Db::getInstance()->getRow($sql); + + if (isset($this->data_shop['active'])) { + $this->active = $this->data_shop['active']; + } + } + } + + public function toggleStatus() + { + $this->deActiveAll($this->page); + return true; + } + + public function deActiveAll($page) + { + // validate module + unset($page); + $id_shop = apPageHelper::getIDShop(); + //$where = ' WHERE ps.id_shop='.$id_shop." AND ps.id_appagebuilder_profiles != '".(int)$this->id."'"; + $where = ' WHERE ps.id_shop='.(int)$id_shop; + Db::getInstance()->execute('UPDATE `'._DB_PREFIX_.'appagebuilder_profiles_shop` ps set ps.active = 0 '.$where); + $where = ' WHERE ps.id_shop='.$id_shop." AND ps.id_appagebuilder_profiles = '".(int)$this->id."'"; + Db::getInstance()->execute('UPDATE `'._DB_PREFIX_.'appagebuilder_profiles_shop` ps set ps.active = 1 '.$where); + } + + public function getAllProfileByShop() + { + try { + $context = Context::getContext(); + $id_shop = $context->shop->id; + $id_lang = $context->language->id; +// $where = ' WHERE id_shop='.(int)$id_shop.' AND id_lang='.(int)$id_lang; + $sql = 'SELECT p.*, ps.*,pl.friendly_url + FROM '._DB_PREFIX_.'appagebuilder_profiles p + INNER JOIN '._DB_PREFIX_.'appagebuilder_profiles_lang pl ON (p.id_appagebuilder_profiles = pl.id_appagebuilder_profiles) + INNER JOIN '._DB_PREFIX_.'appagebuilder_profiles_shop ps ON (ps.id_appagebuilder_profiles = p.id_appagebuilder_profiles) + WHERE id_shop='.(int)$id_shop.' AND id_lang='.(int)$id_lang; + return Db::getInstance()->executes($sql); + } catch (Exception $exc) { + return array(); // OLD MODULE, NOT NEED SHOW DATA + } + } + + public function add($autodate = true, $null_values = false) + { + $id_shop = apPageHelper::getIDShop(); + $res = parent::add($autodate, $null_values); + $res &= Db::getInstance()->execute(' + INSERT INTO `'._DB_PREFIX_.'appagebuilder_profiles_shop` (`id_shop`, `id_appagebuilder_profiles`) + VALUES('.(int)$id_shop.', '.(int)$this->id.')'); + if (Db::getInstance()->getValue('SELECT COUNT(p.`id_appagebuilder_profiles`) AS total FROM `'._DB_PREFIX_.'appagebuilder_profiles` p + INNER JOIN `'._DB_PREFIX_.'appagebuilder_profiles_shop` ps ON(p.id_appagebuilder_profiles = ps.id_appagebuilder_profiles) + WHERE id_shop='.(int)$id_shop) <= 1) { + $this->deActiveAll($this->page); + } else if ($this->active) { + $this->deActiveAll($this->page); + } + return $res; + } + + public function update($null_values = false) + { + // validate module + unset($null_values); + if ($this->active) { + $this->deActiveAll($this->page); + } + + return parent::update(); + } + + public function getProfilesInPage($id = 0) + { + $context = Context::getContext(); + $id_shop = $context->shop->id; + $where = ' WHERE ps.id_shop='.(int)$id_shop." AND p.page='".pSQL($this->page)."'"; + if ($id) { + $where .= ' AND p.id_appagebuilder_profiles !='.(int)$id; + } + $inner_join = 'INNER JOIN `'._DB_PREFIX_.'appagebuilder_profiles_shop` ps ON (ps.id_appagebuilder_profiles = p.id_appagebuilder_profiles)'; + $sql = 'SELECT p.* from `'._DB_PREFIX_.'appagebuilder_profiles` p '.$inner_join.$where; + return Db::getInstance()->executes($sql); + } + + public static function getActiveProfile($page) + { + // validate module + unset($page); + + # Fix bug http://screencast.com/t/flCEjya6 + $updatePositions = Tools::getValue('action'); + $ajax = Tools::getValue('ajax'); + if ($updatePositions == 'updatePositions' && $ajax == '1') { + return null; + } + + $result = null; + $is_use_co = Configuration::get('APPAGEBUILDER_COOKIE_PROFILE'); + $context = Context::getContext(); + $id_shop = $context->shop->id; + $id_profile = ApPageBuilderProfilesModel::getIdProfileFromRewrite(); + # SET PROFILE FOLLOW GROUP_CUSTOMER + $current_group_id = Group::getCurrent()->id; + if (isset($current_group_id) && $current_group_id == 3) { + $customer = Context::getContext()->customer; + $sql = 'SELECT id_group FROM `'._DB_PREFIX_.'customer_group` WHERE id_customer='.(int)$customer->id; + $array_group_id = Db::getInstance()->executeS($sql); + foreach ($array_group_id as $group_id) { + if ($group_id !=1 && $group_id !=2 && $group_id !=3) { + $current_group_id = $group_id['id_group']; + } + } + } + $model = new ApPageBuilderProfilesModel(); + $list_profiles = $model->getAllProfileByShop(); + if ($list_profiles) { + foreach ($list_profiles as $profile) { + $group_boxs = $profile['group_box']; + $aray_group_box = explode(',', $group_boxs); + foreach ($aray_group_box as $group_box) { + if (isset($current_group_id) && $current_group_id == $group_box) { + $profile_current = $profile['id_appagebuilder_profiles']; + } + } + } + } + if (isset($profile_current) && $profile_current != "") { + $id_profile = $profile_current; + } + //check cookie + if ($is_use_co) { + if (!$id_profile && $context->cookie->ap_profile) { + $id_profile = $context->cookie->ap_profile; + } else { + $context->cookie->ap_profile = $id_profile; + } + } + + $id_lang = $context->language->id; + $cache_id = 'ApPageBuilderProfilesModel::getActiveProfile_'.md5((int)$id_profile.(int)$id_lang.(int)$id_shop); + if (!Cache::isStored($cache_id)) { + if ($id_profile) { + $where = ' WHERE ps.id_shop='.(int)$id_shop.' AND p.id_appagebuilder_profiles='.(int)$id_profile; + } else { + $where = ' WHERE ps.id_shop='.(int)$id_shop.' AND ps.active=1 '; + } + $inner_join = ' INNER JOIN `'._DB_PREFIX_.'appagebuilder_profiles_lang` pl ON (pl.id_appagebuilder_profiles = p.id_appagebuilder_profiles) AND id_lang='.(int)$id_lang; + $inner_join .= ' INNER JOIN `'._DB_PREFIX_.'appagebuilder_profiles_shop` ps ON (ps.id_appagebuilder_profiles = p.id_appagebuilder_profiles)'; + $sql = 'SELECT p.*, pl.* from `'._DB_PREFIX_.'appagebuilder_profiles` p '.$inner_join.$where; + $result = Db::getInstance()->getRow($sql); + Cache::store($cache_id, $result); + } else { + $result = Cache::retrieve($cache_id); + } + foreach (array('header', 'content', 'footer', 'product') as $val) { + $pos_key = 'ap_'.$val; + if (Tools::getIsset($val)) { + $result[$val] = Tools::getValue($val); + + if (Tools::isSubmit('controller') && Tools::getValue('controller') === 'AdminNewsletterPro') { + // Conflict with Newsletter Pro module + } else { + $context->cookie->{$pos_key} = $result[$val]; + } + } else if ($is_use_co && $context->cookie->{$pos_key}) { + $result[$val] = $context->cookie->{$pos_key}; + } + } + + return $result; + } + + public function getProfile($id) + { + $sql = 'SELECT * FROM `'._DB_PREFIX_.'appagebuilder_profiles` WHERE id_appagebuilder_profiles='.(int)$id; + $object = Db::getInstance()->getRow($sql); + return $object ? $object : null; + } + + public function duplicateProfile($id, $name, $profile_key, $id_shop) + { + $new_id = 0; + $sql = 'SELECT * FROM `'._DB_PREFIX_.'appagebuilder_profiles` WHERE id_appagebuilder_profiles='.(int)$id; + $object_duplicated = Db::getInstance()->getRow($sql); + if ($object_duplicated) { + $sql = 'INSERT INTO `'._DB_PREFIX_.'appagebuilder_profiles`(name, profile_key, page) VALUES("' + .pSQL($name).pSQL($object_duplicated['name']).'", "'.pSQL($profile_key).'", "index")'; + Db::getInstance()->execute($sql); + $new_id = Db::getInstance()->Insert_ID(); + $sql = 'INSERT INTO `'._DB_PREFIX_.'appagebuilder_profiles_shop`(id_appagebuilder_profiles, id_shop, active) VALUES(' + .(int)$new_id.', '.(int)$id_shop.', 0)'; + Db::getInstance()->execute($sql); + return $new_id; + } + return 0; + } + + public function customDuplicateObject($message) + { + $object_duplicated = parent::duplicateObject(); + $object_duplicated->active = 0; + $object_duplicated->name = $message.' '.$object_duplicated->name; + return $object_duplicated; + } + + public function save($null_values = false, $autodate = true) + { + // validate module + unset($null_values); + unset($autodate); + $context = Context::getContext(); + $this->id_shop = $context->shop->id; + if ($this->active) { + $this->deActiveAll($this->page); + } + return parent::save(); + } + + public static function deleteById($id) + { + $id = (int)$id; + $sql = 'SELECT * FROM `'._DB_PREFIX_.'appagebuilder_profiles` WHERE id_appagebuilder_profiles='.(int)$id; + $object_duplicated = Db::getInstance()->getRow($sql); + if ($object_duplicated) { + $sql = 'DELETE FROM `'._DB_PREFIX_.'appagebuilder_profiles` WHERE id_appagebuilder_profiles='.(int)$id; + Db::getInstance()->execute($sql); + $sql = 'DELETE FROM `'._DB_PREFIX_.'appagebuilder_profiles_lang` WHERE id_appagebuilder_profiles='.(int)$id; + Db::getInstance()->execute($sql); + $sql = 'DELETE FROM `'._DB_PREFIX_.'appagebuilder_profiles_shop` WHERE id_appagebuilder_profiles='.(int)$id; + Db::getInstance()->execute($sql); + return $object_duplicated; + } + return array(); + } + + public function getPositionsForProfile($id_positions) + { + if ($id_positions) { + $id_positions = implode(',', array_map('intval', $id_positions)); + $sql = 'SELECT * FROM `'._DB_PREFIX_.'appagebuilder_positions` WHERE id_appagebuilder_positions IN('.pSQL($id_positions).')'; + return Db::getInstance()->executes($sql); + } + return array(); + } + + public function delete($params = array()) + { + $result = parent::delete(); + + if ($result) { + if (isset($this->def['multishop']) && $this->def['multishop'] == true) { + # DELETE RECORD FORM TABLE _SHOP + $id_shop_list = Shop::getContextListShopID(); + if (count($this->id_shop_list)) { + $id_shop_list = $this->id_shop_list; + } + + $id_shop_list = array_map('intval', $id_shop_list); + + Db::getInstance()->delete($this->def['table'].'_shop', '`'.$this->def['primary'].'`='. + (int)$this->id.' AND id_shop IN ('.pSQL(implode(', ', $id_shop_list)).')'); + + if (isset($params['import_sample']) && $params['import_sample'] == true) { + $position = new ApPageBuilderPositionsModel((int)$this->header); + $position->delete(); + $position = new ApPageBuilderPositionsModel((int)$this->content); + $position->delete(); + $position = new ApPageBuilderPositionsModel((int)$this->footer); + $position->delete(); + $position = new ApPageBuilderPositionsModel((int)$this->product); + $position->delete(); + } + } + } + + return $result; + } + + /** + * $id_profile = ApPageBuilderProfilesModel::getIdProfileFromRewrite(); + */ + public static function getIdProfileFromRewrite($linkRewrive = '') + { + static $id_appagebuilder_profiles = null; + + if ($id_appagebuilder_profiles === null) { + $context = Context::getContext(); + $id_shop = (int)$context->shop->id; + $id_lang = (int)$context->language->id; + + # ACCESS BY id_appagebuilder_profiles + $id_temp = Tools::getIsset('id_appagebuilder_profiles') ? Tools::getValue('id_appagebuilder_profiles') : false; + if ($id_temp !== false) { + $id_appagebuilder_profiles = $id_temp; + return $id_appagebuilder_profiles; + } + + # ACCESS BY friendly_url + $linkRewrive = explode('/', $_SERVER['REQUEST_URI']); + $linkRewrive = rtrim(end($linkRewrive), '.html'); + if (strpos($linkRewrive, '?')) { + // REMOVE ? FROM URL + $temp_str = explode("?", $linkRewrive); + $linkRewrive = $temp_str[0]; + $linkRewrive = rtrim($linkRewrive, '.html'); + } + if (!empty($linkRewrive)) { + $sql = 'SELECT p.`id_appagebuilder_profiles` FROM `'._DB_PREFIX_.'appagebuilder_profiles` p'; + $sql .= ' INNER JOIN `'._DB_PREFIX_.'appagebuilder_profiles_lang` pl ON(pl.id_appagebuilder_profiles = p.id_appagebuilder_profiles AND pl.friendly_url=\''.pSQL($linkRewrive).'\' AND id_lang='.(int)$id_lang.' ) '; + $sql .= ' INNER JOIN `'._DB_PREFIX_.'appagebuilder_profiles_shop` ps ON(ps.id_appagebuilder_profiles = p.id_appagebuilder_profiles AND ps.id_shop ='.(int)$id_shop.')'; + + $id_appagebuilder_profiles = Db::getInstance()->getValue($sql); + return $id_appagebuilder_profiles; + } + + + + # ACESS BY active_profile + $where = ' WHERE ps.id_shop='.(int)$id_shop.' AND ps.active=1 '; + + $inner_join = ' INNER JOIN `'._DB_PREFIX_.'appagebuilder_profiles_lang` pl ON (pl.id_appagebuilder_profiles = p.id_appagebuilder_profiles) AND id_lang='.(int)$id_lang; + $inner_join .= ' INNER JOIN `'._DB_PREFIX_.'appagebuilder_profiles_shop` ps ON (ps.id_appagebuilder_profiles = p.id_appagebuilder_profiles)'; + $sql = 'SELECT p.id_appagebuilder_profiles, p.name, p.profile_key, pl.id_lang, ps.id_shop, ps.active from `'._DB_PREFIX_.'appagebuilder_profiles` p '.$inner_join.$where; + + $active_profile = Db::getInstance()->getRow($sql); + + if ($active_profile) { + return $active_profile['id_appagebuilder_profiles']; + } + + return false; + } + return $id_appagebuilder_profiles; + } + + public static function getAllProfileRewrite($id_profile = null) + { + if ($id_profile) { + $id_shop = Context::getContext()->shop->id; + + if ($id_profile) { + $where = ' WHERE ps.id_shop='.(int)$id_shop.' AND p.id_appagebuilder_profiles='.(int)$id_profile; + } + + $inner_join = ' INNER JOIN `'._DB_PREFIX_.'appagebuilder_profiles_lang` pl ON (pl.id_appagebuilder_profiles = p.id_appagebuilder_profiles)'; + $inner_join .= ' INNER JOIN `'._DB_PREFIX_.'appagebuilder_profiles_shop` ps ON (ps.id_appagebuilder_profiles = p.id_appagebuilder_profiles)'; + $sql = 'SELECT p.id_appagebuilder_profiles, p.name, pl.id_lang, pl.friendly_url from `'._DB_PREFIX_.'appagebuilder_profiles` p '.$inner_join.$where; + $result = Db::getInstance()->executeS($sql); + + foreach ($result as $key => $value) { + $result[$key]['iso_code'] = Language::getIsoById($result[$key]['id_lang']); + } + // validate module + unset($value); + + return $result; + } + return array(); + } +} diff --git a/modules/appagebuilder/classes/ApPageBuilderShortcodeModel.php b/modules/appagebuilder/classes/ApPageBuilderShortcodeModel.php new file mode 100644 index 00000000..da513fee --- /dev/null +++ b/modules/appagebuilder/classes/ApPageBuilderShortcodeModel.php @@ -0,0 +1,276 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageSetting.php'); + +class ApPageBuilderShortcodeModel extends ObjectModel +{ + public $shortcode_key; + // public $id_appagebuilder; + public $shortcode_name; + public $active = true; + /** + * @see ObjectModel::$definition + */ + public static $definition = array( + 'table' => 'appagebuilder_shortcode', + 'primary' => 'id_appagebuilder_shortcode', + 'multilang' => true, + 'multishop' => true, + 'fields' => array( + 'shortcode_key' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255), + // 'id_appagebuilder' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), + + 'shortcode_name' => array('type' => self::TYPE_STRING, 'validate' => 'isString', 'size' => 255, 'lang' => true, 'required' => true), + + 'active' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'), + ) + ); + + public function __construct($id = null, $id_lang = null, $id_shop = null, Context $context = null) + { + // validate module + unset($context); + parent::__construct($id, $id_lang, $id_shop); + } + + public function add($autodate = true, $null_values = false) + { + $id_shop = apPageHelper::getIDShop(); + $res = parent::add($autodate, $null_values); + + $res &= Db::getInstance()->execute(' + INSERT INTO `'._DB_PREFIX_.'appagebuilder_shortcode_shop` (`id_shop`, `id_appagebuilder_shortcode`, `active`) + VALUES('.(int)$id_shop.', '.(int)$this->id.', '.(int)$this->active.')'); + return $res; + } + + public function update($nullValues = false) + { + $id_shop = apPageHelper::getIDShop(); + $res = parent::update($nullValues); + + $res &= Db::getInstance()->execute(' + UPDATE `'._DB_PREFIX_.'appagebuilder_shortcode_shop` ps set ps.active = '.(int)$this->active.' WHERE ps.id_shop='.(int)$id_shop.' AND ps.id_appagebuilder_shortcode = '.(int)$this->id); + + return $res; + } + + public function delete() + { + $result = parent::delete(); + + if ($result) { + if (isset($this->def['multishop']) && $this->def['multishop'] == true) { + # DELETE RECORD FORM TABLE _SHOP + $id_shop_list = Shop::getContextListShopID(); + if (count($this->id_shop_list)) { + $id_shop_list = $this->id_shop_list; + } + + $id_shop_list = array_map('intval', $id_shop_list); + + Db::getInstance()->delete($this->def['table'].'_shop', '`'.$this->def['primary'].'`='. + (int)$this->id.' AND id_shop IN ('.pSQL(implode(', ', $id_shop_list)).')'); + } + + //DONGND:: delete appagebuilder related shortcode + $id_appagebuilder = ApPageBuilderModel::getIdByIdShortCode((int)$this->id); + + if ($id_appagebuilder) { + $obj = new ApPageBuilderModel($id_appagebuilder); + $obj->delete(); + } + } + + return $result; + } + + public function getShortCodeContent($id_appagebuilder = 0, $is_font = 0, $id_lang = 0) + { + $context = Context::getContext(); + $id_shop = (int)$context->shop->id; + $where = ' WHERE ps.id_shop='.(int)$id_shop.' AND p.id_appagebuilder='.(int)$id_appagebuilder; + + if ($id_lang) { + $where .= ' AND pl.id_lang = '.(int)$id_lang; + } else { + $id_lang = $context->language->id; + } + $sql = 'SELECT p.*, pl.params, pl.id_lang + FROM `'._DB_PREFIX_.'appagebuilder` p + LEFT JOIN `'._DB_PREFIX_.'appagebuilder_shop` ps ON (ps.id_appagebuilder = p.id_appagebuilder) + LEFT JOIN `'._DB_PREFIX_.'appagebuilder_lang` pl ON (pl.id_appagebuilder = p.id_appagebuilder) + LEFT JOIN `'._DB_PREFIX_.'appagebuilder_shortcode` pp ON (p.id_appagebuilder_shortcode = pp.id_appagebuilder_shortcode) + + '.pSql($where).' ORDER BY p.id_appagebuilder'; + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); + + // echo '
';
+        // print_r($result);die();
+        $id_langs = Language::getLanguages(true, false, true);
+        # FIX - Only get language data valid
+        foreach ($result as $key => $val) {
+            if (isset($val['id_lang']) && !in_array($val['id_lang'], $id_langs)) {
+                unset($result[$key]);
+            }
+        }
+        
+        $data_lang = array();
+        if ($is_font) {
+            foreach ($result as $row) {
+                $data_lang[$row['hook_name']] = $row['params'];
+            }
+            return $data_lang;
+        }
+        $ap_helper = new ApShortCodesBuilder();
+        ApShortCodesBuilder::$is_front_office = $is_font;
+        ApShortCodesBuilder::$is_gen_html = 1;
+        //DONGND:: check gen for Apshortcode
+        // ApShortCodesBuilder::$check_gen_Apshortcode = 1;
+        foreach ($result as $row) {
+            if (isset($data_lang[$row['id_appagebuilder']])) {
+                $data_lang[$row['id_appagebuilder']]['params'][$row['id_lang']] = $row['params'];
+            } else {
+                $data_lang[$row['id_appagebuilder']] = array(
+                    'id' => $row['id_appagebuilder'],
+                    'hook_name' => $row['hook_name'],
+                );
+                $data_lang[$row['id_appagebuilder']]['params'][$row['id_lang']] = $row['params'];
+            }
+        }
+        //$data_hook = array_flip(ApPageSetting::getHookHome());
+        // $hook_config = Configuration::get('APPAGEBUILDER_' . Tools::strtoupper($pos).'_HOOK');
+        // $hook_config = explode(',', $hook_config ? $hook_config : ApPageSetting::getHook($pos));
+        // $data_hook = array_flip($hook_config);
+        $data_hook = array();
+        // echo '
';
+        // print_r($data_lang);die();
+        foreach ($data_lang as $row) {
+            //process params
+            foreach ($row['params'] as $key => $value) {
+                ApShortCodesBuilder::$lang_id = $key;
+                if ($key == $id_lang) {
+                    ApShortCodesBuilder::$is_gen_html = 1;
+                    $row['content'] = $ap_helper->parse($value);
+                } else {
+                    ApShortCodesBuilder::$is_gen_html = 0;
+                    $ap_helper->parse($value);
+                }
+            }
+            $data_hook[$row['hook_name']] = $row;
+        }
+        
+        return array('content' => $data_hook, 'dataForm' => ApShortCodesBuilder::$data_form);
+    }
+    
+    /**
+     * Get all items - datas of all hooks by shop Id, lang Id for front-end or back-end
+     * @param type $id_profiles
+     * @param type $is_font (=0: for back-end; =1: for front-end)
+     * @param type $id_lang
+     * @return type
+     */
+    public static function getAllItems($id_appagebuilder, $is_font = 0, $id_lang = 0)
+    {
+        //print_r("Input: $id_profiles - $is_font - $id_lang"); 2-1-1
+        $context = Context::getContext();
+//        $id_profiles = (int)$profile['id_appagebuilder_profiles'];
+        $id_shop = (int)$context->shop->id;
+        $id_lang = $id_lang ? (int)$id_lang : (int)$context->language->id;
+
+        $sql = 'SELECT p.*, pl.params, pl.id_lang
+                FROM '._DB_PREFIX_.'appagebuilder p
+                    LEFT JOIN '._DB_PREFIX_.'appagebuilder_shop ps ON (ps.id_appagebuilder = p.id_appagebuilder AND id_shop='.(int)$id_shop.')
+                    LEFT JOIN '._DB_PREFIX_.'appagebuilder_lang pl ON (pl.id_appagebuilder = p.id_appagebuilder)
+                    LEFT JOIN `'._DB_PREFIX_.'appagebuilder_shortcode` pp ON (p.id_appagebuilder_shortcode = pp.id_appagebuilder_shortcode)
+                WHERE
+                    pl.id_lang='.(int)$id_lang.'
+                    AND ps.id_shop='.(int)$id_shop.'
+                    AND p.id_appagebuilder = '.(int)$id_appagebuilder.'
+                ORDER BY p.id_appagebuilder';
+
+        $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
+        //echo '
';print_r($result);die;
+        $data_lang = array();
+        if ($is_font) {
+            foreach ($result as $row) {
+                $data_lang[$row['hook_name']] = $row['params'];
+            }
+            return $data_lang;
+        }
+        $ap_helper = new ApShortCodesBuilder();
+        ApShortCodesBuilder::$is_front_office = $is_font;
+        ApShortCodesBuilder::$is_gen_html = 1;
+        foreach ($result as $row) {
+            if (isset($data_lang[$row['id_appagebuilder']])) {
+                $data_lang[$row['id_appagebuilder']]['params'][$row['id_lang']] = $row['params'];
+            } else {
+                $data_lang[$row['id_appagebuilder']] = array(
+                    'id' => $row['id_appagebuilder'],
+                    'hook_name' => $row['hook_name'],
+                );
+                $data_lang[$row['id_appagebuilder']]['params'][$row['id_lang']] = $row['params'];
+            }
+        }
+        $data_hook = array_flip(ApPageSetting::getHookHome());
+        foreach ($data_lang as $row) {
+            //process params
+            foreach ($row['params'] as $key => $value) {
+                ApShortCodesBuilder::$lang_id = $key;
+                if ($key == $id_lang) {
+                    ApShortCodesBuilder::$is_gen_html = 1;
+                    $row['content'] = $ap_helper->parse($value);
+                } else {
+                    ApShortCodesBuilder::$is_gen_html = 0;
+                    $ap_helper->parse($value);
+                }
+            }
+            $data_hook[$row['hook_name']] = $row;
+        }
+
+        return array('content' => $data_hook, 'dataForm' => ApShortCodesBuilder::$data_form);
+    }
+    
+    public static function getShortCode($shortcode_key)
+    {
+        $id_shop = Context::getContext()->shop->id;
+       
+        $sql = 'SELECT p.*, pp.`id_appagebuilder` FROM `'._DB_PREFIX_.'appagebuilder_shortcode` p
+                INNER JOIN `'._DB_PREFIX_.'appagebuilder_shortcode_shop` ps on(p.`id_appagebuilder_shortcode` = ps.`id_appagebuilder_shortcode`)
+				INNER JOIN `'._DB_PREFIX_.'appagebuilder` pp on(p.`id_appagebuilder_shortcode` = pp.`id_appagebuilder_shortcode`) WHERE
+                p.`shortcode_key` = "'.pSQL($shortcode_key).'" AND ps.`active`= 1 AND ps.`id_shop` = '.(int)$id_shop;
+        
+        return Db::getInstance()->getRow($sql);
+    }
+    
+    public static function getListShortCode()
+    {
+        $id_shop = Context::getContext()->shop->id;
+        $id_lang = Context::getContext()->language->id;
+       
+        $sql = 'SELECT p.*, ps.*, pl.* FROM `'._DB_PREFIX_.'appagebuilder_shortcode` p
+                INNER JOIN `'._DB_PREFIX_.'appagebuilder_shortcode_shop` ps on(p.`id_appagebuilder_shortcode` = ps.`id_appagebuilder_shortcode`)
+                INNER JOIN `'._DB_PREFIX_.'appagebuilder_shortcode_lang` pl on(p.`id_appagebuilder_shortcode` = pl.`id_appagebuilder_shortcode`) WHERE
+                ps.`id_shop` = '.(int)$id_shop.' AND pl.`id_lang` = '.(int)$id_lang;
+
+        return Db::getInstance()->executeS($sql);
+    }
+}
diff --git a/modules/appagebuilder/classes/ApPageSetting.php b/modules/appagebuilder/classes/ApPageSetting.php
new file mode 100644
index 00000000..0e71c8ff
--- /dev/null
+++ b/modules/appagebuilder/classes/ApPageSetting.php
@@ -0,0 +1,1407 @@
+
+ *  @copyright 2007-2015 Apollotheme
+ *  @license   http://apollotheme.com - prestashop template provider
+ */
+
+if (!defined('_PS_VERSION_')) {
+    # module validation
+    exit;
+}
+
+class ApPageSetting
+{
+
+    public static function getHookHome()
+    {
+        return array(
+            'displayTop',
+            'displayLeftColumn',
+            'displayHome',
+            'displayRightColumn',
+            'displayFooter'
+        );
+    }
+    const HOOK_BOXED = 0;
+    const HOOK_FULWIDTH_INDEXPAGE = 1;
+    const HOOK_FULWIDTH_OTHERPAGE = 1;
+    const ROW_BOXED = 0;
+    const ROW_FULWIDTH_INDEXPAGE = 1;
+    const HOOK_DISABLE_CACHE = 1;
+    const HOOK_ENABLE_CACHE = 0;
+    /**
+     * hook for fullwidth and boxed
+     */
+    public static function getIndexHook($type = 1)
+    {
+        if (version_compare(_PS_VERSION_, '1.7.1.0', '>=')) {
+            if ($type == 1) {
+                # get name hook
+                return array(
+                    'displayBanner',
+                    'displayNav1',
+                    'displayNav2',
+                    'displayTop',
+                    'displayHome',
+                    'displayFooterBefore',
+                    'displayFooter',
+                    'displayFooterAfter',
+                );
+            } else if ($type == 2) {
+                # get name hook
+                return array(
+                    'displayBanner' => 'displayBanner',
+                    'displayNav1' => 'displayNav1',
+                    'displayNav2' => 'displayNav2',
+                    'displayTop' => 'displayTop',
+                    'displayHome' => 'displayHome',
+                    'displayFooterBefore' => 'displayFooterBefore',
+                    'displayFooter' => 'displayFooter',
+                    'displayFooterAfter' => 'displayFooterAfter',
+                );
+            } else if ($type == 3) {
+                # get default fullwidth or boxed for each hook
+                return array(
+                    'displayBanner' => self::HOOK_BOXED,
+                    'displayNav1' => self::HOOK_BOXED,
+                    'displayNav2' => self::HOOK_BOXED,
+                    'displayTop' => self::HOOK_BOXED,
+                    'displayHome' => self::HOOK_BOXED,
+                    'displayFooterBefore' => self::HOOK_BOXED,
+                    'displayFooter' => self::HOOK_BOXED,
+                    'displayFooterAfter' => self::HOOK_BOXED,
+                );
+            }
+        }
+
+        if ($type == 1) {
+            # get name hook
+            return array(
+                'displayNav1',
+                'displayNav2',
+                'displayTop',
+                'displayHome',
+                'displayFooterBefore',
+                'displayFooter',
+                'displayFooterAfter',
+            );
+        } else if ($type == 2) {
+            # get name hook
+            return array(
+                'displayNav1' => 'displayNav1',
+                'displayNav2' => 'displayNav2',
+                'displayTop' => 'displayTop',
+                'displayHome' => 'displayHome',
+                'displayFooterBefore' => 'displayFooterBefore',
+                'displayFooter' => 'displayFooter',
+                'displayFooterAfter' => 'displayFooterAfter',
+            );
+        } else if ($type == 3) {
+            # get default fullwidth or boxed for each hook
+            return array                (
+                'displayNav1' => self::HOOK_BOXED,
+                'displayNav2' => self::HOOK_BOXED,
+                'displayTop' => self::HOOK_BOXED,
+                'displayHome' => self::HOOK_BOXED,
+                'displayFooterBefore' => self::HOOK_BOXED,
+                'displayFooter' => self::HOOK_BOXED,
+                'displayFooterAfter' => self::HOOK_BOXED,
+            );
+        }
+    }
+
+    /**
+     * hook for fullwidth and boxed
+     */
+    public static function getOtherHook($type = 1)
+    {
+        if (version_compare(_PS_VERSION_, '1.7.1.0', '>=')) {
+            if ($type == 1) {
+                # get name hook
+                return array(
+                    'displayBanner',
+                    'displayNav1',
+                    'displayNav2',
+                    'displayTop',
+                    'displayHome',
+                    'displayFooterBefore',
+                    'displayFooter',
+                    'displayFooterAfter',
+                );
+            } else if ($type == 2) {
+                # get name hook
+                return array(
+                    'displayBanner' => 'displayBanner',
+                    'displayNav1' => 'displayNav1',
+                    'displayNav2' => 'displayNav2',
+                    'displayTop' => 'displayTop',
+                    'displayHome' => 'displayHome',
+                    'displayFooterBefore' => 'displayFooterBefore',
+                    'displayFooter' => 'displayFooter',
+                    'displayFooterAfter' => 'displayFooterAfter',
+                );
+            } else if ($type == 3) {
+                # get default value
+                return array(
+                    'displayBanner' => self::HOOK_BOXED,
+                    'displayNav1' => self::HOOK_BOXED,
+                    'displayNav2' => self::HOOK_BOXED,
+                    'displayTop' => self::HOOK_BOXED,
+                    'displayHome' => self::HOOK_BOXED,
+                    'displayFooterBefore' => self::HOOK_BOXED,
+                    'displayFooter' => self::HOOK_BOXED,
+                    'displayFooterAfter' => self::HOOK_BOXED,
+                );
+            }
+        }
+
+        if ($type == 1) {
+            # get name hook
+            return array(
+                'displayNav1',
+                'displayNav2',
+                'displayTop',
+                'displayHome',
+                'displayFooterBefore',
+                'displayFooter',
+                'displayFooterAfter',
+            );
+        } else if ($type == 2) {
+            # get name hook
+            return array(
+                'displayNav1' => 'displayNav1',
+                'displayNav2' => 'displayNav2',
+                'displayTop' => 'displayTop',
+                'displayHome' => 'displayHome',
+                'displayFooterBefore' => 'displayFooterBefore',
+                'displayFooter' => 'displayFooter',
+                'displayFooterAfter' => 'displayFooterAfter',
+            );
+        } else if ($type == 3) {
+            # get default value
+            return array(
+                'displayNav1' => self::HOOK_BOXED,
+                'displayNav2' => self::HOOK_BOXED,
+                'displayTop' => self::HOOK_BOXED,
+                'displayHome' => self::HOOK_BOXED,
+                'displayFooterBefore' => self::HOOK_BOXED,
+                'displayFooter' => self::HOOK_BOXED,
+                'displayFooterAfter' => self::HOOK_BOXED,
+            );
+        }
+    }
+
+    public static function getCacheHook($type = 1)
+    {
+        if (version_compare(_PS_VERSION_, '1.7.1.0', '>=')) {
+            if ($type == 1) {
+                # get name hook
+                return array(
+                    'displayBanner',
+                    'displayNav1',
+                    'displayNav2',
+                    'displayTop',
+                    'displayHome',
+                    'displayFooterBefore',
+                    'displayFooter',
+                    'displayFooterAfter',
+                );
+            } else if ($type == 2) {
+                # get name hook
+                return array
+                    (
+                    'displayTop' => 'displayTop',
+                    'displayHome' => 'displayHome',
+                    'displayFooter' => 'displayFooter',
+                );
+            } else if ($type == 3) {
+                # get default value
+                return array
+                    (
+                    'displayTop' => self::HOOK_ENABLE_CACHE,
+                    'displayHome' => self::HOOK_ENABLE_CACHE,
+                    'displayFooter' => self::HOOK_ENABLE_CACHE,
+                );
+            }
+        }
+
+        if ($type == 1) {
+            # get name hook
+            return array(
+                'displayNav1',
+                'displayNav2',
+                'displayTop',
+                'displayHome',
+                'displayFooterBefore',
+                'displayFooter',
+                'displayFooterAfter',
+            );
+        } else if ($type == 2) {
+            # get name hook
+            return array
+                (
+                'displayTop' => 'displayTop',
+                'displayHome' => 'displayHome',
+                'displayFooter' => 'displayFooter',
+            );
+        } else if ($type == 3) {
+            # get default value
+            return array
+                (
+                'displayTop' => self::HOOK_ENABLE_CACHE,
+                'displayHome' => self::HOOK_ENABLE_CACHE,
+                'displayFooter' => self::HOOK_ENABLE_CACHE,
+            );
+        }
+    }
+
+    public static function getPositionsName()
+    {
+        return array('header', 'content', 'footer', 'product');
+    }
+
+    /**
+     * Get list hooks by type
+     * @param type $type: string in {all, header, footer, content, product}
+     * @return array
+     */
+    public static function getHook($type = 'all')
+    {
+        $list_hook = array();
+        if (version_compare(_PS_VERSION_, '1.7.1.0', '>=')) {
+            $hook_header_default = array(
+                'displayBanner',
+                'displayNav1',
+                'displayNav2',
+                'displayTop',
+                'displayNavFullWidth',
+            );
+        } else {
+            $hook_header_default = array(
+                'displayNav1',
+                'displayNav2',
+                'displayTop',
+                'displayNavFullWidth',
+            );
+        }
+        $hook_content_default = array(
+            'displayLeftColumn',
+            'displayHome',
+            'displayRightColumn',
+        );
+        $hook_footer_default = array(
+            'displayFooterBefore',
+            'displayFooter',
+            'displayFooterAfter',
+        );
+        $hook_product_default = array(
+            'displayLeftColumnProduct',
+            'displayRightColumnProduct',
+            'displayReassurance',
+            'displayProductButtons',
+            'displayFooterProduct',
+        );
+        if ($type == 'all') {
+            $list_hook = array_merge($hook_header_default, $hook_content_default, $hook_footer_default, $hook_product_default);
+        } else if ($type == 'header') {
+            $list_hook = $hook_header_default;
+        } else if ($type == 'content') {
+            $list_hook = $hook_content_default;
+        } else if ($type == 'footer') {
+            $list_hook = $hook_footer_default;
+        } else if ($type == 'product') {
+            $list_hook = $hook_product_default;
+        }
+        return $list_hook;
+    }
+
+    public static function getProductContainer()
+    {
+        $html = '';
+        $html .= '
' . "\n"; + $html .= '
' . "\n"; + return $html; + } + public static function getProductContainerEnd() + { + $html = ''; + $html .= '
' . "\n"; + $html .= '
' . "\n"; + return $html; + } + + public static function getProductFunctionalButtons() + { + return '
'; + } + + public static function getProductLeftBlock() + { + return '
'; + } + + public static function getProductRightBlock() + { + return '
'; + } + + public static function getProductElementIcon() + { +// return array( +// 'add_to_cart' => 'icon-shopping-cart', +// 'color' => 'icon-circle', +// 'compare' => 'icon-bar-chart', +// 'description' => 'icon-file-text', +// 'display_product_price_block' => 'icon-dollar', +// 'flags' => 'icon-flag', +// 'functional_buttons' => 'icon-puzzle-piece', +// 'name' => 'icon-file', +// 'product_delivery_time' => 'icon-time', +// 'reviews' => 'icon-star', +// 'status' => 'icon-question-sign', +// 'view' => 'icon-eye-open', +// 'quick_view' => 'icon-eye-open', +// 'image_container' => 'icon-picture', +// 'price' => 'icon-money', +// 'wishlist' => 'icon-heart', +// ); + return array( + 'add_to_cart' => 'icon-shopping-cart', + 'add_to_cart_attribute' => 'icon-list', + 'add_to_cart_quantity' => 'icon-sort', + 'product_variants' => 'icon-circle', + 'compare' => 'icon-bar-chart', + 'description' => 'icon-file-text', + 'display_product_price_block' => 'icon-dollar', + 'product_flags' => 'icon-flag', + 'functional_buttons' => 'icon-puzzle-piece', + 'product_name' => 'icon-file', + 'product_delivery_time' => 'icon-time', + 'reviews' => 'icon-star', + 'status' => 'icon-question-sign', + 'view' => 'icon-eye-open', + 'quickview' => 'icon-eye-open', + 'product_thumbnail' => 'icon-picture', + 'product_price_and_shipping' => 'icon-money', + 'wishlist' => 'icon-heart', + 'product_description_short' => 'icon-file-text-o', + 'product_description' => 'icon-file-text', + ); + } + + public static function writeFile($folder, $file, $value) + { + $file = $folder.'/'.$file; + $handle = fopen($file, 'w+'); + fwrite($handle, ($value)); + fclose($handle); + } + + public static function getRandomNumber() + { + return rand() + time(); + } + + public static function returnYesNo() + { + return array( + array( + 'id' => 'active_on', + 'value' => 1, + 'label' => self::l('Enabled') + ), + array( + 'id' => 'active_off', + 'value' => 0, + 'label' => self::l('Disabled') + )); + } + + public static function returnTrueFalse() + { + return array(array( + 'id' => 'active_on', + 'value' => 'true', + 'label' => self::l('Enabled') + ), + array( + 'id' => 'active_off', + 'value' => 'false', + 'label' => self::l('Disabled') + )); + } + + public static function getOrderByBlog() + { + return array( + array( + 'id' => 'id_leoblogcat', 'name' => self::l('Category')), + array( + 'id' => 'id_leoblog_blog', 'name' => self::l('ID')), + array( + 'id' => 'meta_title', 'name' => self::l('Title')), + array( + 'id' => 'date_add', 'name' => self::l('Date add')), + array( + 'id' => 'date_upd', 'name' => self::l('Date update')), + ); + } + + public static function getOrderByManu() + { + return array( + array( + 'id' => 'id_manufacturer', 'name' => self::l('ID')), + array( + 'id' => 'name', 'name' => self::l('Name')), + array( + 'id' => 'date_add', 'name' => self::l('Date add')), + array( + 'id' => 'date_upd', 'name' => self::l('Date update')), + ); + } + + public static function getOrderBy() + { + return array( +// array( +// 'id' => 'position', 'name' => self::l('Position')), // remove to increase speed + array( + 'id' => 'id_product', 'name' => self::l('ID')), + array( + 'id' => 'name', 'name' => self::l('Name')), + array( + 'id' => 'reference', 'name' => self::l('Reference')), + array( + 'id' => 'price', 'name' => self::l('Base price')), + array( + 'id' => 'date_add', 'name' => self::l('Date add')), + array( + 'id' => 'date_upd', 'name' => self::l('Date update')), + ); + } + + public static function getColumnGrid() + { + return array( + 'xl' => self::l('Extra large devices - Desktops (≥1200px)'), + 'lg' => self::l('Large devices - Desktops (≥992px)'), + 'md' => self::l('Medium devices - Tablets (≥768px)'), + 'sm' => self::l('Small devices (≥576px)'), + 'xs' => self::l('Extra small devices (<576px)'), + 'sp' => self::l('Smart Phones (< 480px)'), + ); + } + + public static function l($text) + { + return $text; + } + + public static function getAnimations() + { + return array( + 'none' => array( + 'name' => self::l('Turn off'), + 'query' => array( + array( + 'id' => 'none', + 'name' => self::l('None'), + ) + ) + ), + 'attention_seekers' => array( + 'name' => self::l('Attention Seekers'), + 'query' => array( + array( + 'id' => 'bounce', + 'name' => self::l('bounce'), + ), + array( + 'id' => 'flash', + 'name' => self::l('flash'), + ), array( + 'id' => 'pulse', + 'name' => self::l('pulse'), + ), array( + 'id' => 'rubberBand', + 'name' => self::l('rubberBand'), + ), array( + 'id' => 'shake', + 'name' => self::l('shake'), + ), array( + 'id' => 'swing', + 'name' => self::l('swing'), + ), array( + 'id' => 'tada', + 'name' => self::l('tada'), + ), array( + 'id' => 'wobble', + 'name' => self::l('wobble'), + ) + ) + ), + 'Bouncing_Entrances' => array( + 'name' => self::l('Bouncing Entrances'), + 'query' => array( + array( + 'id' => 'bounceIn', + 'name' => self::l('bounceIn'), + ), + array( + 'id' => 'bounceInDown', + 'name' => self::l('bounceInDown'), + ), + array( + 'id' => 'bounceInLeft', + 'name' => self::l('bounceInLeft'), + ), + array( + 'id' => 'bounceInRight', + 'name' => self::l('bounceInRight'), + ), + array( + 'id' => 'bounceInUp', + 'name' => self::l('bounceInUp'), + ) + ), + ), + 'Bouncing_Exits' => array( + 'name' => self::l('Bouncing Exits'), + 'query' => array( + array( + 'id' => 'bounceOut', + 'name' => self::l('bounceOut'), + ), + array( + 'id' => 'bounceOutDown', + 'name' => self::l('bounceOutDown'), + ), + array( + 'id' => 'bounceOutLeft', + 'name' => self::l('bounceOutLeft'), + ), + array( + 'id' => 'bounceOutRight', + 'name' => self::l('bounceOutRight'), + ), + array( + 'id' => 'bounceOutUp', + 'name' => self::l('bounceOutUp'), + ) + ), + ), + 'Fading_Entrances' => array( + 'name' => self::l('Fading Entrances'), + 'query' => array( + array( + 'id' => 'fadeIn', + 'name' => self::l('fadeIn'), + ), + array( + 'id' => 'fadeInDown', + 'name' => self::l('fadeInDown'), + ), + array( + 'id' => 'fadeInDownBig', + 'name' => self::l('fadeInDownBig'), + ), + array( + 'id' => 'fadeInLeft', + 'name' => self::l('fadeInLeft'), + ), + array( + 'id' => 'fadeInLeftBig', + 'name' => self::l('fadeInLeftBig'), + ), + array( + 'id' => 'fadeInRight', + 'name' => self::l('fadeInRight'), + ), + array( + 'id' => 'fadeInRightBig', + 'name' => self::l('fadeInRightBig'), + ), + array( + 'id' => 'fadeInRight', + 'name' => self::l('fadeInRight'), + ), + array( + 'id' => 'fadeInRightBig', + 'name' => self::l('fadeInRightBig'), + ), + array( + 'id' => 'fadeInUp', + 'name' => self::l('fadeInUp'), + ), + array( + 'id' => 'fadeInUpBig', + 'name' => self::l('fadeInUpBig'), + ), + ), + ), + 'Fading_Exits' => array( + 'name' => self::l('Fading Exits'), + 'query' => array( + array( + 'id' => 'fadeOut', + 'name' => self::l('fadeOut'), + ), + array( + 'id' => 'fadeOutDown', + 'name' => self::l('fadeOutDown'), + ), + array( + 'id' => 'fadeOutDownBig', + 'name' => self::l('fadeOutDownBig'), + ), + array( + 'id' => 'fadeOutLeft', + 'name' => self::l('fadeOutLeft'), + ), + array( + 'id' => 'fadeOutRight', + 'name' => self::l('fadeOutRight'), + ), + array( + 'id' => 'fadeOutRightBig', + 'name' => self::l('fadeOutRightBig'), + ), + array( + 'id' => 'fadeOutUp', + 'name' => self::l('fadeOutUp'), + ), + array( + 'id' => 'fadeOutUpBig', + 'name' => self::l('fadeOutUpBig'), + ) + ), + ), + 'Flippers' => array( + 'name' => self::l('Flippers'), + 'query' => array( + array( + 'id' => 'flip', + 'name' => self::l('flip'), + ), + array( + 'id' => 'flipInX', + 'name' => self::l('flipInX'), + ), + array( + 'id' => 'flipInY', + 'name' => self::l('flipInY'), + ), + array( + 'id' => 'flipOutX', + 'name' => self::l('flipOutX'), + ), + array( + 'id' => 'flipOutY', + 'name' => self::l('flipOutY'), + ) + ), + ), + 'Lightspeed' => array( + 'name' => self::l('Lightspeed'), + 'query' => array( + array( + 'id' => 'lightSpeedIn', + 'name' => self::l('lightSpeedIn'), + ), + array( + 'id' => 'lightSpeedOut', + 'name' => self::l('lightSpeedOut'), + ) + ), + ), + 'Rotating_Entrances' => array( + 'name' => self::l('Rotating Entrances'), + 'query' => array( + array( + 'id' => 'rotateIn', + 'name' => self::l('rotateIn'), + ), + array( + 'id' => 'rotateInDownLeft', + 'name' => self::l('rotateInDownLeft'), + ), + array( + 'id' => 'rotateInDownRight', + 'name' => self::l('rotateInDownRight'), + ), + array( + 'id' => 'rotateInUpLeft', + 'name' => self::l('rotateInUpLeft'), + ), + array( + 'id' => 'rotateInUpRight', + 'name' => self::l('rotateInUpRight'), + ) + ), + ), + 'Rotating_Exits' => array( + 'name' => self::l('Rotating Exits'), + 'query' => array( + array( + 'id' => 'rotateOut', + 'name' => self::l('rotateOut'), + ), + array( + 'id' => 'rotateOutDownLeft', + 'name' => self::l('rotateOutDownLeft'), + ), + array( + 'id' => 'rotateOutDownRight', + 'name' => self::l('rotateOutDownRight'), + ), + array( + 'id' => 'rotateOutUpLeft', + 'name' => self::l('rotateOutUpLeft'), + ), + array( + 'id' => 'rotateOutUpRight', + 'name' => self::l('rotateOutUpRight'), + ) + ), + ), + 'Specials' => array( + 'name' => self::l('Specials'), + 'query' => array( + array( + 'id' => 'hinge', + 'name' => self::l('hinge'), + ), + array( + 'id' => 'rollIn', + 'name' => self::l('rollIn'), + ), + array( + 'id' => 'rollOut', + 'name' => self::l('rollOut'), + ) + ), + ), + 'Zoom Entrances' => array( + 'name' => self::l('Zoom Entrances'), + 'query' => array( + array( + 'id' => 'zoomIn', + 'name' => self::l('zoomIn'), + ), + array( + 'id' => 'zoomInDown', + 'name' => self::l('zoomInDown'), + ), + array( + 'id' => 'zoomInLeft', + 'name' => self::l('zoomInLeft'), + ), + array( + 'id' => 'zoomInRight', + 'name' => self::l('zoomInRight'), + ), + array( + 'id' => 'zoomInUp', + 'name' => self::l('zoomInUp'), + ) + ), + ), + 'Zoom_Exits' => array( + 'name' => self::l('Zoom Exits'), + 'query' => array( + array( + 'id' => 'zoomOut', + 'name' => self::l('zoomOut'), + ), + array( + 'id' => 'zoomOutDown', + 'name' => self::l('zoomOutDown'), + ), + array( + 'id' => 'zoomOutLeft', + 'name' => self::l('zoomOutLeft'), + ), + array( + 'id' => 'zoomOutRight', + 'name' => self::l('zoomOutRight'), + ), + array( + 'id' => 'zoomOutUp', + 'name' => self::l('zoomOutUp'), + ) + ), + ) + ); + } + + //DONGND:: build list animation for group and column + public static function getAnimationsColumnGroup() + { + return array( + 'none' => array( + 'name' => self::l('Turn off'), + 'query' => array( + array( + 'id' => 'none', + 'name' => self::l('None'), + ) + ) + ), + 'Fading_Entrances' => array( + 'name' => self::l('Fading Entrances'), + 'query' => array( + array( + 'id' => 'fadeIn', + 'name' => self::l('fadeIn'), + ), + array( + 'id' => 'fadeInDown', + 'name' => self::l('fadeInDown'), + ), + array( + 'id' => 'fadeInDownBig', + 'name' => self::l('fadeInDownBig'), + ), + array( + 'id' => 'fadeInLeft', + 'name' => self::l('fadeInLeft'), + ), + array( + 'id' => 'fadeInLeftBig', + 'name' => self::l('fadeInLeftBig'), + ), + array( + 'id' => 'fadeInRight', + 'name' => self::l('fadeInRight'), + ), + array( + 'id' => 'fadeInRightBig', + 'name' => self::l('fadeInRightBig'), + ), + array( + 'id' => 'fadeInUp', + 'name' => self::l('fadeInUp'), + ), + array( + 'id' => 'fadeInUpBig', + 'name' => self::l('fadeInUpBig'), + ), + ), + ), + 'Bouncing_Entrances' => array( + 'name' => self::l('Bouncing Entrances'), + 'query' => array( + array( + 'id' => 'bounceIn', + 'name' => self::l('bounceIn'), + ), + array( + 'id' => 'bounceInDown', + 'name' => self::l('bounceInDown'), + ), + array( + 'id' => 'bounceInLeft', + 'name' => self::l('bounceInLeft'), + ), + array( + 'id' => 'bounceInRight', + 'name' => self::l('bounceInRight'), + ), + array( + 'id' => 'bounceInUp', + 'name' => self::l('bounceInUp'), + ) + ), + ), + 'Zoom Entrances' => array( + 'name' => self::l('Zoom Entrances'), + 'query' => array( + array( + 'id' => 'zoomIn', + 'name' => self::l('zoomIn'), + ), + array( + 'id' => 'zoomInDown', + 'name' => self::l('zoomInDown'), + ), + array( + 'id' => 'zoomInLeft', + 'name' => self::l('zoomInLeft'), + ), + array( + 'id' => 'zoomInRight', + 'name' => self::l('zoomInRight'), + ), + array( + 'id' => 'zoomInUp', + 'name' => self::l('zoomInUp'), + ) + ), + ), + 'attention_seekers' => array( + 'name' => self::l('Attention Seekers'), + 'query' => array( + array( + 'id' => 'bounce', + 'name' => self::l('bounce'), + ), + array( + 'id' => 'flash', + 'name' => self::l('flash'), + ), + array( + 'id' => 'pulse', + 'name' => self::l('pulse'), + ), + array( + 'id' => 'rubberBand', + 'name' => self::l('rubberBand'), + ), + array( + 'id' => 'shake', + 'name' => self::l('shake'), + ), + array( + 'id' => 'swing', + 'name' => self::l('swing'), + ), + array( + 'id' => 'tada', + 'name' => self::l('tada'), + ), + array( + 'id' => 'wobble', + 'name' => self::l('wobble'), + ) + ) + ), + 'Flippers' => array( + 'name' => self::l('Flippers'), + 'query' => array( + array( + 'id' => 'flip', + 'name' => self::l('flip'), + ), + array( + 'id' => 'flipInX', + 'name' => self::l('flipInX'), + ), + array( + 'id' => 'flipInY', + 'name' => self::l('flipInY'), + ), + array( + 'id' => 'flipOutX', + 'name' => self::l('flipOutX'), + ), + array( + 'id' => 'flipOutY', + 'name' => self::l('flipOutY'), + ) + ), + ), + 'Lightspeed' => array( + 'name' => self::l('Lightspeed'), + 'query' => array( + array( + 'id' => 'lightSpeedIn', + 'name' => self::l('lightSpeedIn'), + ), + array( + 'id' => 'lightSpeedOut', + 'name' => self::l('lightSpeedOut'), + ) + ), + ), + 'Rotating_Entrances' => array( + 'name' => self::l('Rotating Entrances'), + 'query' => array( + array( + 'id' => 'rotateIn', + 'name' => self::l('rotateIn'), + ), + array( + 'id' => 'rotateInDownLeft', + 'name' => self::l('rotateInDownLeft'), + ), + array( + 'id' => 'rotateInDownRight', + 'name' => self::l('rotateInDownRight'), + ), + array( + 'id' => 'rotateInUpLeft', + 'name' => self::l('rotateInUpLeft'), + ), + array( + 'id' => 'rotateInUpRight', + 'name' => self::l('rotateInUpRight'), + ) + ), + ), + 'Specials' => array( + 'name' => self::l('Specials'), + 'query' => array( + array( + 'id' => 'hinge', + 'name' => self::l('hinge'), + ), + array( + 'id' => 'rollIn', + 'name' => self::l('rollIn'), + ), + array( + 'id' => 'rollOut', + 'name' => self::l('rollOut'), + ) + ), + ), + 'Bouncing_Exits' => array( + 'name' => self::l('Bouncing Exits'), + 'query' => array( + array( + 'id' => 'bounceOut', + 'name' => self::l('bounceOut'), + ), + array( + 'id' => 'bounceOutDown', + 'name' => self::l('bounceOutDown'), + ), + array( + 'id' => 'bounceOutLeft', + 'name' => self::l('bounceOutLeft'), + ), + array( + 'id' => 'bounceOutRight', + 'name' => self::l('bounceOutRight'), + ), + array( + 'id' => 'bounceOutUp', + 'name' => self::l('bounceOutUp'), + ) + ), + ), + 'Fading_Exits' => array( + 'name' => self::l('Fading Exits'), + 'query' => array( + array( + 'id' => 'fadeOut', + 'name' => self::l('fadeOut'), + ), + array( + 'id' => 'fadeOutDown', + 'name' => self::l('fadeOutDown'), + ), + array( + 'id' => 'fadeOutDownBig', + 'name' => self::l('fadeOutDownBig'), + ), + array( + 'id' => 'fadeOutLeft', + 'name' => self::l('fadeOutLeft'), + ), + array( + 'id' => 'fadeOutRight', + 'name' => self::l('fadeOutRight'), + ), + array( + 'id' => 'fadeOutRightBig', + 'name' => self::l('fadeOutRightBig'), + ), + array( + 'id' => 'fadeOutUp', + 'name' => self::l('fadeOutUp'), + ), + array( + 'id' => 'fadeOutUpBig', + 'name' => self::l('fadeOutUpBig'), + ) + ), + ), + 'Rotating_Exits' => array( + 'name' => self::l('Rotating Exits'), + 'query' => array( + array( + 'id' => 'rotateOut', + 'name' => self::l('rotateOut'), + ), + array( + 'id' => 'rotateOutDownLeft', + 'name' => self::l('rotateOutDownLeft'), + ), + array( + 'id' => 'rotateOutDownRight', + 'name' => self::l('rotateOutDownRight'), + ), + array( + 'id' => 'rotateOutUpLeft', + 'name' => self::l('rotateOutUpLeft'), + ), + array( + 'id' => 'rotateOutUpRight', + 'name' => self::l('rotateOutUpRight'), + ) + ), + ), + 'Zoom_Exits' => array( + 'name' => self::l('Zoom Exits'), + 'query' => array( + array( + 'id' => 'zoomOut', + 'name' => self::l('zoomOut'), + ), + array( + 'id' => 'zoomOutDown', + 'name' => self::l('zoomOutDown'), + ), + array( + 'id' => 'zoomOutLeft', + 'name' => self::l('zoomOutLeft'), + ), + array( + 'id' => 'zoomOutRight', + 'name' => self::l('zoomOutRight'), + ), + array( + 'id' => 'zoomOutUp', + 'name' => self::l('zoomOutUp'), + ) + ), + ) + ); + } + + public static function requireShortCode($short_code, $theme_dir = '') + { + if (file_exists($theme_dir.'modules/appagebuilder/classes/shortcodes/'.$short_code)) { + return $theme_dir.'modules/appagebuilder/classes/shortcodes/'.$short_code; + } + if (file_exists(_PS_MODULE_DIR_.'appagebuilder/classes/shortcodes/'.$short_code)) { + return _PS_MODULE_DIR_.'appagebuilder/classes/shortcodes/'.$short_code; + } + return false; + } + + public static function getControllerId($controller, $ids) + { + switch ($controller) { + case 'product': + $current_id = Tools::getValue('id_product'); + if ($current_id == $ids || (is_array($ids) && in_array($current_id, $ids))) { + return $current_id; + } + break; + case 'category': + $current_id = Tools::getValue('id_category'); + if ($current_id == $ids || (is_array($ids) && in_array($current_id, $ids))) { + return $current_id; + } + break; + case 'cms': + $current_id = Tools::getValue('id_cms'); + if ($current_id == $ids || (is_array($ids) && in_array($current_id, $ids))) { + return $current_id; + } + break; + default: + return false; + } + } + + public static function getAllowOverrideHook() + { + return array('rightcolumn', 'leftcolumn', 'home', 'top', 'footer'); + } + + public static function returnWidthList() + { + return array('12', '11', '10', '9.6', '9', '8', '7.2', '7', '6', '4.8', '5', '4', '3', '2.4', '2', '1'); + } + + public static function getDefaultNameImage($type = 'small') + { + $sep = '_'; + $arr = array('small' => 'small'.$sep.'default', 'thickbox' => 'thickbox'.$sep.'default'); + return $arr[$type]; + } + + public static function getModeDebugLog() + { + return 0; + } + + public static function buildGuide($context, $path = '', $current_step = 1) + { + $skip = Tools::getIsset('skip') ? Tools::getValue('skip') : ''; + $done = Tools::getIsset('done') ? Tools::getValue('done') : ''; + $reset = Tools::getIsset('ap_guide_reset') ? Tools::getValue('ap_guide_reset') : ''; + if ($skip || $done) { + Configuration::updateValue('APPAGEBUILDER_GUIDE', 4); + return ''; + } + if ($reset) { + Configuration::updateValue('APPAGEBUILDER_GUIDE', 1); + } + $status = Configuration::get('APPAGEBUILDER_GUIDE'); + if ($status > 3) { + return ''; + } + // Save next step + if ($status < $current_step) { + Configuration::updateValue('APPAGEBUILDER_GUIDE', $current_step); + } + if ($current_step == 0) { + $current_step = $status; + } + $url1 = 'index.php?controller=adminmodules&configure=appagebuilder&token='.Tools::getAdminTokenLite('AdminModules') + .'&tab_module=Home&module_name=appagebuilder'; + $url2 = ''; + $url3 = ''; + $next_step = ''; + // Add new profile + if ($current_step == 1) { + $next_step = $context->link->getAdminLink('AdminApPageBuilderProfiles').'&addappagebuilder_profiles'; + } + if ($current_step == 2) { + $url2 = $context->link->getAdminLink('AdminApPageBuilderProfiles').'&addappagebuilder_profiles'; + $next_step = $context->link->getAdminLink('AdminApPageBuilderHome'); + } + if ($current_step == 3) { + $url2 = $context->link->getAdminLink('AdminApPageBuilderProfiles').'&addappagebuilder_profiles'; + $url3 = $context->link->getAdminLink('AdminApPageBuilderHome'); + $next_step = $context->link->getAdminLink('AdminApPageBuilderHome'); + } + $context->smarty->assign(array( + 'is_guide' => 1, + 'url1' => $url1, + 'url2' => $url2, + 'url3' => $url3, + 'next_step' => $next_step, + 'step' => $current_step)); + return $context->smarty->fetch($path); + } + + public static function listFontAwesome() + { + return array( + array('value' => 'icon-font'), + array('value' => 'icon-bold'), + array('value' => 'icon-adjust'), + array('value' => 'icon-calendar'), + array('value' => 'icon-bookmark'), + array('value' => 'icon-bolt'), + array('value' => 'icon-book'), + array('value' => 'icon-certificate'), + array('value' => 'icon-bullhorn'), + array('value' => 'icon-check'), + array('value' => 'icon-check-square-o'), + array('value' => 'icon-comments-o'), + array('value' => 'icon-comment'), + array('value' => 'icon-credit-card'), + array('value' => 'icon-thumbs-up'), + array('value' => 'icon-thumbs-down'), + array('value' => 'icon-thumbs-o-up'), + array('value' => 'icon-thumbs-o-down'), + array('value' => 'icon-truck'), + array('value' => 'icon-angle-left'), + array('value' => 'icon-angle-right'), + array('value' => 'icon-angle-up'), + array('value' => 'icon-angle-down'), + array('value' => 'icon-angle-double-left'), + array('value' => 'icon-angle-double-right'), + array('value' => 'icon-angle-double-up'), + array('value' => 'icon-angle-double-down'), + array('value' => 'icon-arrow-left'), + array('value' => 'icon-arrow-right'), + array('value' => 'icon-arrow-up'), + array('value' => 'icon-arrow-down'), + array('value' => 'icon-align-left'), + array('value' => 'icon-align-right'), + array('value' => 'icon-align-center'), + array('value' => 'icon-align-justify'), + array('value' => 'icon-arrow-circle-o-left'), + array('value' => 'icon-arrow-circle-o-right'), + array('value' => 'icon-toggle-left'), + array('value' => 'icon-toggle-right'), + array('value' => 'icon-eye'), + array('value' => 'icon-eye-slash'), + array('value' => 'icon-smile-o'), + array('value' => 'icon-spinner'), + array('value' => 'icon-user'), + array('value' => 'icon-users'), + array('value' => 'icon-user-plus'), + array('value' => 'icon-user-times'), + array('value' => 'icon-user-md'), + array('value' => 'icon-user-secret'), + array('value' => 'icon-female'), + array('value' => 'icon-male'), + array('value' => 'icon-quote-left'), + array('value' => 'icon-quote-right'), + array('value' => 'icon-html5'), + array('value' => 'icon-css3'), + array('value' => 'icon-android'), + array('value' => 'icon-google'), + array('value' => 'icon-apple'), + array('value' => 'icon-windows'), + array('value' => 'icon-linux'), + array('value' => 'icon-youtube'), + array('value' => 'icon-twitter'), + array('value' => 'icon-yahoo'), + array('value' => 'icon-skype'), + array('value' => 'icon-trello'), + array('value' => 'icon-slack'), + array('value' => 'icon-wordpress'), + array('value' => 'icon-drupal'), + array('value' => 'icon-joomla'), + ); + } + + public static function getOverrideHook() + { + if (version_compare(_PS_VERSION_, '1.7.1.0', '>=')) { + $list_hook = array( + 'displayBanner', + 'displayNav1', + 'displayNav2', + 'displayTop', + 'displayHome', + 'displayLeftColumn', + 'displayRightColumn', + 'displayFooterBefore', + 'displayFooter', + 'displayFooterAfter', + 'displayFooterProduct', + 'displayRightColumnProduct', + 'displayLeftColumnProduct', + ); + + return $list_hook; + } + + $list_hook = array( + 'displayNav1', + 'displayNav2', + 'displayTop', + 'displayHome', + 'displayLeftColumn', + 'displayRightColumn', + 'displayFooterBefore', + 'displayFooter', + 'displayFooterAfter', + 'displayFooterProduct', + 'displayRightColumnProduct', + 'displayLeftColumnProduct', + ); + + return $list_hook; + } +} diff --git a/modules/appagebuilder/classes/ApShortCodesBuilder.php b/modules/appagebuilder/classes/ApShortCodesBuilder.php new file mode 100644 index 00000000..2904311b --- /dev/null +++ b/modules/appagebuilder/classes/ApShortCodesBuilder.php @@ -0,0 +1,421 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +if (!class_exists('ApShortCodeBase')) { + + class ApShortCodesBuilder + { + public static $shortcode_tags = array(); + public static $lang_id = 0; + public static $is_front_office = 1; + public static $is_gen_html = 1; + public static $data_form = array(); + public static $shortcode_lang; + public static $hook_name; + public static $profile_param; + + public static function addShortcode($tag, $func) + { + self::$shortcode_tags[$tag] = $func; + } + + public static function removeShortcode($tag) + { + unset(self::$shortcode_tags[$tag]); + } + + public static function shortcodeExists($tag) + { + return array_key_exists($tag, self::$shortcode_tags); + } + + public static function doShortcode($content) + { + if (false === strpos($content, '[')) { + return $content; + } + $pattern = self::getShortcodeRegex(); + return preg_replace_callback("/$pattern/s", array(new ApShortCodesBuilder, 'doShortcodeTag'), $content); + } + + public static function getShortcodeRegex() + { + $tagnames = array_keys(self::$shortcode_tags); + $tagregexp = join('|', array_map('preg_quote', $tagnames)); + return '\\[(\\[?)'."($tagregexp)" + .'(?![\\w-])([^\\]\\/]*(?:\\/(?!\\])[^\\]\\/]*)*?)(?:(\\/)\\]|\\](?:([^\\[]*+(?:\\[(?!\\/\\2\\])[^\\[]*+)*+)\\[\\/\\2\\])?)(\\]?)'; + /* + return '\\[' // Opening bracket + .'(\\[?)' // 1: Optional second opening bracket for escaping shortcodes: [[tag]] + ."($tagregexp)" // 2: Shortcode name + .'(?![\\w-])' // Not followed by word character or hyphen + .'(' // 3: Unroll the loop: Inside the opening shortcode tag + .'[^\\]\\/]*' // Not a closing bracket or forward slash + .'(?:' + .'\\/(?!\\])' // A forward slash not followed by a closing bracket + .'[^\\]\\/]*' // Not a closing bracket or forward slash + .')*?' + .')' + .'(?:' + .'(\\/)' // 4: Self closing tag ... + .'\\]' // ... and closing bracket + .'|' + .'\\]' // Closing bracket + .'(?:' + .'(' // 5: Unroll the loop: Optionally, anything between the opening and closing shortcode tags + .'[^\\[]*+' // Not an opening bracket + .'(?:' + .'\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag + .'[^\\[]*+' // Not an opening bracket + .')*+' + .')' + .'\\[\\/\\2\\]' // Closing shortcode tag + .')?' + .')' + .'(\\]?)'; // 6: Optional second closing brocket for escaping shortcodes: [[tag]] + * */ + } + + public static function doShortcodeTag($m) + { + $shortcode_tags = self::$shortcode_tags; + // allow [[foo]] syntax for escaping a tag + if ($m[1] == '[' && $m[6] == ']') { + return Tools::substr($m[0], 1, -1); + } + $tag = $m[2]; + $attr = self::shortcodeParseAtts($m[3]); + $function_call = self::$is_front_office ? 'fontContent' : 'adminContent'; + if (isset($m[5])) { + // enclosing tag - extra parameter + return $m[1].call_user_func(array($shortcode_tags[$tag], $function_call), $attr, $m[5], $tag, self::$is_gen_html).$m[6]; + } else { + // self-closing tag + return $m[1].call_user_func(array($shortcode_tags[$tag], $function_call), $attr, null, $tag, self::$is_gen_html).$m[6]; + } + } + + public static function shortcodeParseAtts($text) + { + $pattern = '/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/'; + $text = preg_replace('/[\x{00a0}\x{200b}]+/u', ' ', $text); + $atts = array(); + if (preg_match_all($pattern, $text, $match, PREG_SET_ORDER)) { + foreach ($match as $m) { + if (!empty($m[1])) { + $atts[Tools::strtolower($m[1])] = stripcslashes($m[2]); + } elseif (!empty($m[3])) { + $atts[Tools::strtolower($m[3])] = stripcslashes($m[4]); + } elseif (!empty($m[5])) { + $atts[Tools::strtolower($m[5])] = stripcslashes($m[6]); + } elseif (isset($m[7]) && Tools::strlen($m[7])) { + $atts[] = stripcslashes($m[7]); + } elseif (isset($m[8])) { + $atts[] = stripcslashes($m[8]); + } else { + $atts = ltrim($text); + } + } + } + return $atts; + } + + public static function stripShortcodes($content) + { + $shortcode_tags = self::$shortcode_tags; + if (empty($shortcode_tags) || !is_array($shortcode_tags)) { + return $content; + } + $pattern = self::getShortcodeRegex(); + return preg_replace_callback("/$pattern/s", array(self, 'stripShortcodeTag'), $content); + } + + public static function stripShortcodeTag($m) + { + // allow [[foo]] syntax for escaping a tag + if ($m[1] == '[' && $m[6] == ']') { + return Tools::substr($m[0], 1, -1); + } + return $m[1].$m[6]; + } + + public static function setShortCodeLang($type) + { + if (!isset(AdminApPageBuilderHomeController::$shortcode_lang[$type])) { + $fileName = $type; + if (strpos($type, 'apSub') !== false) { + $fileName = str_replace('Sub', '', $type); + } + if (file_exists(_PS_MODULE_DIR_.'appagebuilder/classes/shortcodes/'.$fileName.'.php')) { + require_once(_PS_MODULE_DIR_.'appagebuilder/classes/shortcodes/'.$fileName.'.php'); + } + if ($fileName != $type) { + $inputs = call_user_func(array(new $fileName, 'getConfigList'), 1); + } else { + $inputs = call_user_func(array(new $fileName, 'getConfigList')); + } + foreach ($inputs as $input) { + if (isset($input['lang']) && $input['lang']) { + if (self::$lang_id) { + AdminApPageBuilderHomeController::$shortcode_lang[$type][$input['name']] = $input['name'].'_'.self::$lang_id; + } else { + foreach (AdminApPageBuilderHomeController::$language as $lang) { + AdminApPageBuilderHomeController::$shortcode_lang[$type][$input['name'].'_' + .$lang['iso_code']] = $input['name'].'_'.$lang['id_lang']; + } + } + } + } + } + } + + public static function converParamToAttr($params, $type, $theme_dir = '') + { + $attr = ''; + self::setShortCodeLang($type); + + $lang_field = array(); + if (isset(AdminApPageBuilderHomeController::$shortcode_lang[$type])) { + $lang_field = AdminApPageBuilderHomeController::$shortcode_lang[$type]; + } + + //remove lang field first + if ($lang_field) { + foreach ($params as $key => $val) { + if (false !== $arr_key = array_search($key, $lang_field)) { + //do something + $params[$arr_key] = $val; + foreach ($params as $key => $val) { + foreach (AdminApPageBuilderHomeController::$language as $lang) { + unset($params[$arr_key.'_'.$lang['id_lang']]); + } + } + } + } + } + + //DONGND:: fix data for ApBlockcarousel + if ($type == 'ApBlockCarousel' && isset($params['total_slider']) && $params['total_slider'] != '') + { + $lang_field_special = array(); + + $list = explode('|', $params['total_slider']); + + foreach ($list as $list_item) + { + $lang_field_special['tit_'.$list_item] = 'tit_'.$list_item.'_'.self::$lang_id; + $lang_field_special['img_'.$list_item] = 'img_'.$list_item.'_'.self::$lang_id; + $lang_field_special['link_'.$list_item] = 'link_'.$list_item.'_'.self::$lang_id; + $lang_field_special['descript_'.$list_item] = 'descript_'.$list_item.'_'.self::$lang_id; + }; + + if ($lang_field_special) { + foreach ($params as $key => $val) { + if (false !== $arr_key = array_search($key, $lang_field_special)) { + //do something + $params[$arr_key.'_'.self::$lang_id] = $val; + + foreach ($params as $key => $val) { + foreach (AdminApPageBuilderHomeController::$language as $lang) { + if ($lang['id_lang'] != self::$lang_id) + { + unset($params[$arr_key.'_'.$lang['id_lang']]); + } + } + } + + } + } + } + } + + foreach ($params as $key => $val) { + if ($key == 'override_folder' && $val) { + //remove space + $val = str_replace(' ', '', $val); + //add new function override folder for widget + self::processOverrideTpl($val, $type, $theme_dir); + } + $attr .= ($attr ? ' ' : '').$key.'="'.$val.'"'; + } + return ($attr ? ' ' : '').$attr; + } + + + //DONGND:: clone function for Apshortcode + public static function setShortCodeLang2($type) + { + if (!isset(AdminApPageBuilderShortcodeController::$shortcode_lang[$type])) { + $fileName = $type; + if (strpos($type, 'apSub') !== false) { + $fileName = str_replace('Sub', '', $type); + } + if (file_exists(_PS_MODULE_DIR_.'appagebuilder/classes/shortcodes/'.$fileName.'.php')) { + require_once(_PS_MODULE_DIR_.'appagebuilder/classes/shortcodes/'.$fileName.'.php'); + } + if ($fileName != $type) { + $inputs = call_user_func(array(new $fileName, 'getConfigList'), 1); + } else { + $inputs = call_user_func(array(new $fileName, 'getConfigList')); + } + foreach ($inputs as $input) { + if (isset($input['lang']) && $input['lang']) { + if (self::$lang_id) { + AdminApPageBuilderShortcodeController::$shortcode_lang[$type][$input['name']] = $input['name'].'_'.self::$lang_id; + } else { + foreach (AdminApPageBuilderShortcodeController::$language as $lang) { + AdminApPageBuilderShortcodeController::$shortcode_lang[$type][$input['name'].'_' + .$lang['iso_code']] = $input['name'].'_'.$lang['id_lang']; + } + } + } + } + } + } + + //DONGND:: clone function for Apshortcode + public static function converParamToAttr2($params, $type, $theme_dir = '') + { + $attr = ''; + self::setShortCodeLang2($type); + + $lang_field = array(); + if (isset(AdminApPageBuilderShortcodeController::$shortcode_lang[$type])) { + $lang_field = AdminApPageBuilderShortcodeController::$shortcode_lang[$type]; + } + + //remove lang field first + if ($lang_field) { + foreach ($params as $key => $val) { + if (false !== $arr_key = array_search($key, $lang_field)) { + //do something + $params[$arr_key] = $val; + foreach ($params as $key => $val) { + foreach (AdminApPageBuilderShortcodeController::$language as $lang) { + unset($params[$arr_key.'_'.$lang['id_lang']]); + } + } + } + } + } + + //DONGND:: fix data for ApBlockcarousel + if ($type == 'ApBlockCarousel' && isset($params['total_slider']) && $params['total_slider'] != '') + { + $lang_field_special = array(); + + $list = explode('|', $params['total_slider']); + + foreach ($list as $list_item) + { + $lang_field_special['tit_'.$list_item] = 'tit_'.$list_item.'_'.self::$lang_id; + $lang_field_special['img_'.$list_item] = 'img_'.$list_item.'_'.self::$lang_id; + $lang_field_special['link_'.$list_item] = 'link_'.$list_item.'_'.self::$lang_id; + $lang_field_special['descript_'.$list_item] = 'descript_'.$list_item.'_'.self::$lang_id; + }; + + if ($lang_field_special) { + foreach ($params as $key => $val) { + if (false !== $arr_key = array_search($key, $lang_field_special)) { + //do something + $params[$arr_key.'_'.self::$lang_id] = $val; + + foreach ($params as $key => $val) { + foreach (AdminApPageBuilderHomeController::$language as $lang) { + if ($lang['id_lang'] != self::$lang_id) + { + unset($params[$arr_key.'_'.$lang['id_lang']]); + } + } + } + + } + } + } + } + + foreach ($params as $key => $val) { + if ($key == 'override_folder' && $val) { + //remove space + $val = str_replace(' ', '', $val); + //add new function override folder for widget + self::processOverrideTpl($val, $type, $theme_dir); + } + $attr .= ($attr ? ' ' : '').$key.'="'.$val.'"'; + } + return ($attr ? ' ' : '').$attr; + } + + public static function processOverrideTpl($val, $type, $theme_dir) + { + if (file_exists($theme_dir.'modules/appagebuilder/views/templates/hook/'.$val.'/'.$type.'.tpl')) { + return; + } + + //create overide folder + if (!is_dir($theme_dir.'modules/appagebuilder/')) { + // validate module + mkdir($theme_dir.'modules/appagebuilder/', 0755, true); + } + if (!is_dir($theme_dir.'modules/appagebuilder/views/')) { + // validate module + mkdir($theme_dir.'modules/appagebuilder/views/', 0755, true); + } + if (!is_dir($theme_dir.'modules/appagebuilder/views/templates/')) { + // validate module + mkdir($theme_dir.'modules/appagebuilder/views/templates/', 0755, true); + } + if (!is_dir($theme_dir.'modules/appagebuilder/views/templates/hook/')) { + // validate module + mkdir($theme_dir.'modules/appagebuilder/views/templates/hook/', 0755, true); + } + if (!is_dir($theme_dir.'modules/appagebuilder/views/templates/hook/'.$val)) { + // validate module + mkdir($theme_dir.'modules/appagebuilder/views/templates/hook/'.$val, 0755, true); + } + if (file_exists(_PS_MODULE_DIR_.'appagebuilder/views/templates/hook/'.$type.'.tpl')) { + Tools::copy(_PS_MODULE_DIR_.'appagebuilder/views/templates/hook/'.$type.'.tpl', $theme_dir.'modules/appagebuilder/views/templates/hook/'.$val.'/'.$type.'.tpl'); + } else { + $theme_dir_ori = _PS_THEME_DIR_; + Tools::copy(_PS_MODULE_DIR_.'appagebuilder/views/templates/hook/ApGeneral.tpl', $theme_dir_ori.'modules/appagebuilder/views/templates/hook/'.$val.'/'.$type.'.tpl'); + } + } + + public static function correctDeCodeData($data) + { + $function_name = 'base64_decode'; + //$functionName = 'b'.'a'.'s'.'e'.'6'.'4'.'_'.'decode'; + return call_user_func($function_name, $data); + } + + public static function correctEnCodeData($data) + { + $function_name = 'base64_encode'; + //$functionName = 'b'.'a'.'s'.'e'.'6'.'4'.'_'.'encode'; + return call_user_func($function_name, $data); + } + + public function parse($str) + { + return self::doShortcode($str); + } + } + +} diff --git a/modules/appagebuilder/classes/index.php b/modules/appagebuilder/classes/index.php new file mode 100644 index 00000000..6bf70e95 --- /dev/null +++ b/modules/appagebuilder/classes/index.php @@ -0,0 +1,36 @@ + +* @copyright 2007-2012 PrestaShop SA +* @version Release: $Revision: 13573 $ +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/modules/appagebuilder/classes/shortcodes.php b/modules/appagebuilder/classes/shortcodes.php new file mode 100644 index 00000000..bed14a3d --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes.php @@ -0,0 +1,541 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +if (!class_exists('ApShortCodeBase')) { + require_once(_PS_MODULE_DIR_.'appagebuilder/libs/Helper.php'); + require_once(_PS_MODULE_DIR_.'appagebuilder/controllers/admin/AdminApPageBuilderShortcodes.php'); + require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApShortCodesBuilder.php'); + + abstract class ApShortCodeBase + { + /* + * override it for each widget + */ + public $name = ''; + /** + * override when using tinymcs + */ + public $tinymce = 0; + public $module_name = 'appagebuilder'; + public $id_shop = 0; + public $fields_form = array(); + public $types = array(); + public $config_list = array(); + public $str_search; + public $str_relace; + public $str_relace_html; + public $str_relace_html_admin; + public $theme_img_module; + public $theme_dir; + + public function __construct() + { + $this->str_search = apPageHelper::getStrSearch(); + $this->str_relace = apPageHelper::getStrReplace(); + $this->str_relace_html = apPageHelper::getStrReplaceHtml(); + $this->str_relace_html_admin = apPageHelper::getStrReplaceHtmlAdmin(); + // Not run with multi_shop (ex block carousel cant get image in backend multi_shop) + $this->theme_img_module = apPageHelper::getImgThemeUrl(); + $this->theme_dir = _PS_THEME_DIR_; + } + /* + * if file is not exist in theme folder, will get it in module folder, this function only apply for font end + */ + + public function getDirOfFile($path_theme, $file, $path_module = '') + { + if (file_exists(_PS_THEME_DIR_.$path_theme.'/'.$file)) { + // validate module + return _PS_THEME_DIR_.$path_theme.'/'.$file; + } else { + if ($path_module) { + return _PS_MODULE_DIR_.'appagebuilder/'.$path_module.$file; + } else { + return _PS_MODULE_DIR_.'appagebuilder/'.$path_theme.$file; + } + } + } + + /** + * Get class name of product item by plistkey (using in widgets: ApProductList and ApProductCarousel) + */ + public function getProductClassByPListKey($plist = '') + { + // Against SQL injections +// $plist = pSQL($plist ? $plist : ''); + $result = Db::getInstance()->executeS('SELECT * FROM '._DB_PREFIX_.'appagebuilder_products WHERE plist_key="'.pSQL($plist).'" LIMIT 1'); + if ($result) { + return $result[0]['class']; + } + return 'profile-default'; + } + + /** + * abstract method to return html widget form + */ + public function getInfo() + { + return array('key' => 'base', 'label' => 'Widget Base'); + } + + public static function getUrlProfileEdit() + { + $id_profile = Tools::getIsset('id_appagebuilder_profiles') ? Tools::getValue('id_appagebuilder_profiles') : ''; + if (!$id_profile) { + $profile = ApPageBuilderProfilesModel::getActiveProfile('index'); + $id_profile = $profile['id_appagebuilder_profiles']; + } +// $controller = 'AdminApPageBuilderHome'; +// $id_lang = Context::getContext()->language->id; +// $params = array('token' => Tools::getAdminTokenLite($controller)); + //$url_profile_edit = $admin_dir.'/'.Dispatcher::getInstance()->createUrl($controller, $id_lang, $params, false); + $url_profile_edit = Context::getContext()->link->getAdminLink('AdminApPageBuilderProfiles'). + '&id_appagebuilder_profiles='.$id_profile.'&updateappagebuilder_profiles'; + return $url_profile_edit; + } + + public static function getShortCodeInfos() + { + $shortcode_dir = _PS_MODULE_DIR_.'appagebuilder/classes/shortcodes/'; + $source_file = Tools::scandir($shortcode_dir); + $short_code_list = array(); + $is_sub_tab = Tools::getValue('subTab'); + foreach ($source_file as $value) { + $fileName = basename($value, '.php'); + if ($fileName == 'index' || $fileName == 'ApColumn' || $fileName == 'ApRow' || ($is_sub_tab && ($fileName == 'ApTabs' || $fileName == 'ApAccordions'))) { + continue; + } + require_once($shortcode_dir.$value); + $obj = new $fileName; + $short_code_list[$fileName] = $obj->getInfo(); + } + return $short_code_list; + } + + /** + * abstract method to return widget data + */ + public function renderContent($args, $data) + { + // validate module + unset($args); + unset($data); + return true; + } + + public function getTranslator() + { + static $translator; + if (!$translator) { +// $translator = Context::getContext()->controller->module->getTranslator(); // Run at Backend + $translator = Context::getContext()->getTranslator(); // Run at Backend + Frontend. Test with ApGmap Widget + } + return $translator; + } + + protected function trans($id, array $parameters = array(), $domain = 'Modules.Appagebuilder.Admin', $locale = null) + { + return $this->getTranslator()->trans($id, $parameters, $domain, $locale); + } + + public function l($string, $specific = false) + { + if (Tools::getValue('type_shortcode')) { + // FIX Translate in loading widget ajax + return TranslateCore::getModuleTranslation($this->module_name, $string, ($specific) ? $specific : Tools::getValue('type_shortcode')); + } else { + return TranslateCore::getModuleTranslation($this->module_name, $string, ($specific) ? $specific : $this->module_name); + } + } + + public function getInputValues($type, $value) + { + if ($type == 'switchYesNo') { + return array(array('id' => $value.'_on', 'value' => 1, 'label' => $this->l('Yes')), + array('id' => $value.'_off', 'value' => 0, 'label' => $this->l('No'))); + } + } + + /** + * Asign value for each input of Data form + */ + public function getConfigFieldsValues($data = null) + { + $languages = Language::getLanguages(false); + $fields_values = array(); + $obj = isset($data['params']) ? $data['params'] : array(); + foreach ($this->fields_form as $k => $f) { + foreach ($f['form']['input'] as $j => $input) { + if (isset($input['lang'])) { + foreach ($languages as $lang) { + $fields_values[$input['name']][$lang['id_lang']] = isset($obj[$input['name'].'_' + .$lang['id_lang']]) ? $obj[$input['name'].'_'.$lang['id_lang']] : $input['default']; + } + } else if (isset($obj[trim($input['name'])])) { + $value = $obj[trim($input['name'])]; + + if ($input['name'] == 'image' && $value) { +// $thumb = __PS_BASE_URI__.'modules/'.$this->name.'/img/'.$value; + $thumb = apPageHelper::getImgThemeUrl().$value; + $this->fields_form[$k]['form']['input'][$j]['thumb'] = $thumb; + } + $fields_values[$input['name']] = $value; + } else { + $v = Tools::getValue($input['name'], Configuration::get($input['name'])); + $fields_values[$input['name']] = $v ? $v : $input['default']; + } + } + } + if (isset($data['id_leowidgets'])) { + $fields_values['id_leowidgets'] = $data['id_leowidgets']; + } + return $fields_values; + } + + /** + * Return config value for each shortcode + */ + public function getConfigValue() + { + $config_val = array(); + //return addition config + $a_config = $this->getAdditionConfig(); + if ($a_config) { + $this->config_list = array_merge($this->config_list, $a_config); + } + foreach ($this->config_list as $config) { + $config['lang'] = (isset($config['lang']) && $config['lang']) ? $config['lang'] : ''; + $config['name'] = (isset($config['name']) && $config['name']) ? $config['name'] : ''; + $config['default'] = (isset($config['default']) && $config['default']) ? $config['default'] : ''; + + if ($config['lang']) { + foreach (Language::getLanguages(false) as $lang) { + //$config_val[$config['name']] = Tools::getValue($config['name'], $config['default']); + $config_val[$config['name']][$lang['id_lang']] = str_replace($this->str_search, $this->str_relace_html_admin, Tools::getValue($config['name'].'_'.$lang['id_lang'], $config['default'])); + } + } else if (false !== strpos($config['name'], '[]')) { + $get_val_name = str_replace('[]', '', $config['name']); + $config_val[$config['name']] = explode(',', Tools::getValue($get_val_name, $config['default'])); + } else { + $config_val[$config['name']] = str_replace($this->str_search, $this->str_relace_html_admin, Tools::getValue($config['name'], $config['default'])); + } + } + //$config_val[$config['name']] = Tools::getValue($config['name'], $config['default']); + $config_val['override_folder'] = Tools::getValue('override_folder', ''); + return $config_val; + } + + /** + * Override in each shource code to return config list + */ + public function getConfigList() + { + } + + /** + * Return AdditionConfig list, when you use override of input in helper + */ + public function getAdditionConfig() + { + } + + public function preparaAdminContent($atts, $tag_name = null) + { + if ($tag_name == null) { + $tag_name = $this->name; + } + //need reprocess + if (is_array($atts)) { + $atts = array_diff($atts, array('')); + if (!isset(ApShortCodesBuilder::$shortcode_lang[$tag_name])) { + $inputs = $this->getConfigList(); + $lang_field = array(); + foreach ($inputs as $input) { + if (isset($input['lang']) && $input['lang']) { + $lang_field[] = $input['name']; + } + } + ApShortCodesBuilder::$shortcode_lang[$tag_name] = $lang_field; + } else { + $lang_field = ApShortCodesBuilder::$shortcode_lang[$tag_name]; + } + foreach ($atts as $key => $val) { + if ($lang_field && in_array($key, $lang_field)) { + $key .= '_'.ApShortCodesBuilder::$lang_id; + } + if (!isset(ApShortCodesBuilder::$data_form[$atts['form_id']][$key])) { + //find language fields +// if (strpos($key, '_array') !== false) { +// $key = str_replace ('_array', '[]', $key); +// } + ApShortCodesBuilder::$data_form[$atts['form_id']][$key] = $val; + } + } + } + } + + /** + * Get content for normal short code - from shource controller + */ + public function adminContent($atts, $content = null, $tag_name = null, $is_gen_html = null) + { + // validate module + unset($tag_name); + $this->preparaAdminContent($atts); + if ($is_gen_html) { + foreach ($atts as $key => $val) { + if (strpos($key, 'content') !== false || strpos($key, 'link') !== false || strpos($key, 'url') !== false || strpos($key, 'alt') !== false || strpos($key, 'tit') !== false || strpos($key, 'name') !== false || strpos($key, 'desc') !== false || strpos($key, 'itemscustom') !== false) { + $atts[$key] = str_replace($this->str_search, $this->str_relace_html, $val); + } + } + $assign = array(); + $assign['apContent'] = ApShortCodesBuilder::doShortcode($content); + if (isset($atts['content_html'])) { + $atts['content_html'] = str_replace($this->str_search, $this->str_relace_html, $atts['content_html']); + } + $assign['formAtts'] = $atts; + $w_info = $this->getInfo(); + $w_info['name'] = $this->name; + $assign['apInfo'] = $w_info; + if ($this->name == 'ApColumn') { + $assign['colClass'] = $this->convertColWidthToClass($atts); + $assign['widthList'] = ApPageSetting::returnWidthList(); + } + //DONGND:: add parameter to create animation for group/column + if ($this->name == 'ApRow' || $this->name == 'ApColumn') { + $assign['listAnimation'] = ApPageSetting::getAnimationsColumnGroup(); + } + + $controller = new AdminApPageBuilderShortcodesController(); + return $controller->adminContent($assign, $this->name.'.tpl'); + } else { + ApShortCodesBuilder::doShortcode($content); + } + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + return $assign; + } + + /** + * Get content for normal short code - from shource controller + */ + public function fontContent($atts, $content = null) + { + $is_active = $this->isWidgetActive(array('formAtts' => $atts)); + if (!$is_active) { + return ''; + } + + $assign = array(); + $assign['apContent'] = ApShortCodesBuilder::doShortcode($content); + foreach ($atts as $key => $val) { + if (strpos($key, 'content') !== false || strpos($key, 'link') !== false || strpos($key, 'url') !== false || strpos($key, 'alt') !== false || strpos($key, 'tit') !== false || strpos($key, 'name') !== false || strpos($key, 'desc') !== false || strpos($key, 'itemscustom') !== false) { + $atts[$key] = str_replace($this->str_search, $this->str_relace_html, $val); + if (strpos($atts[$key], '_AP_IMG_DIR') !== false) { + // validate module + $atts[$key] = str_replace('_AP_IMG_DIR/', $this->theme_img_module, $atts[$key]); + } + } + } + + if (!isset($atts['class'])) { + $atts['class'] = ''; + } + if (isset($atts['specific_type']) && $atts['specific_type']) { + $current_page = apPageHelper::getPageName(); + + //$current_hook = ApShortCodesBuilder::$hook_name; + if ($atts['specific_type'] == 'all') { + $ex_page = explode(',', isset($atts['controller_pages']) ? $atts['controller_pages'] : ''); + $ex_page = array_map('trim', $ex_page); + if (in_array($current_page, $ex_page)) { + return ''; + } + + # Front modules controller fc=module module=... controller=... + $current_page = Tools::getValue('fc').'-'.Tools::getValue('module').'-'.Tools::getValue('controller'); + if (in_array($current_page, $ex_page)) { + return ''; + } + } else { + if ($current_page != $atts['specific_type']) { + return ''; + } + if ($current_page == 'category' || $current_page == 'product' || $current_page == 'cms') { + $ids = explode(',', $atts['controller_id']); + $ids = array_map('trim', $ids); + if ($atts['controller_id'] != '' && !ApPageSetting::getControllerId($current_page, $ids)) { + return ''; + } + } + } + } + if ($this->name == 'ApColumn') { + $atts['class'] = $this->convertColWidthToClass($atts). ' ' .$atts['class']; + } + $atts['class'] .= ' '.$this->name; + $atts['class'] = trim($atts['class']); + $atts['rtl'] = Context::getContext()->language->is_rtl; + $assign['formAtts'] = $atts; + $assign['homeSize'] = Image::getSize(ImageType::getFormattedName('home')); + $assign['mediumSize'] = Image::getSize(ImageType::getFormattedName('medium')); + $module = APPageBuilder::getInstance(); + + # FIX 1.7 GLOBAL VARIABLE + $assign['img_manu_dir'] = _THEME_MANU_DIR_; + + $assign['comparator_max_item'] = (int)Configuration::get('PS_COMPARATOR_MAX_ITEM'); + $assign['compared_products'] = array(); + $assign['tpl_dir'] = _PS_THEME_DIR_; + $assign['PS_CATALOG_MODE'] = (int)Configuration::get('PS_CATALOG_MODE'); + $assign['priceDisplay'] = ProductCore::getTaxCalculationMethod(Context::getContext()->cookie->id_customer); + $assign['PS_STOCK_MANAGEMENT'] = Configuration::get('PS_STOCK_MANAGEMENT'); + $assign['page_name'] = apPageHelper::getPageName(); + $assign['leo_helper'] = apPageHelper::getInstance(); + isset($assign['formAtts']['override_folder']) ? true : $assign['formAtts']['override_folder'] = ''; + + $assign = $this->prepareFontContent($assign, $module); + return $module->fontContent($assign, $this->name.'.tpl'); + } + + public function isWidgetActive($assign) + { + $flag = true; + + if (isset($assign['formAtts']['active']) && $assign['formAtts']['active'] == 0) { + $flag = false; + } + + return $flag; + } + + public function convertColWidthToClass($atts) + { + $class = ''; + // 1.7 Update Module + if (!array_key_exists('xl', $atts)) { + $class .= 'col-xl-12'; + } + foreach ($atts as $key => $val) { + if ($key == 'xl' || $key == 'lg' || $key == 'md' || $key == 'sm' || $key == 'xs' || $key == 'sp') { + $class .= ' col-'.$key.'-'.$val; + } + } + return $class; + } + + /** + * Return config form + */ + public function renderForm() + { + $helper = new HelperForm(); + $helper->show_toolbar = false; + $helper->table = (isset($this->table) && $this->table) ? $this->table : ''; + $helper->name_controller = 'form_'.$this->name; + $lang = new Language((int)Configuration::get('PS_LANG_DEFAULT')); + $default_lang = $lang->id; + $this->fields_form = array(); + $helper->identifier = (isset($this->identifier) && $this->identifier) ? $this->identifier : ''; + $helper->token = Tools::getAdminTokenLite('AdminModules'); + foreach (Language::getLanguages(false) as $lang) { + $helper->languages[] = array( + 'id_lang' => $lang['id_lang'], + 'iso_code' => $lang['iso_code'], + 'name' => $lang['name'], + 'is_default' => ($default_lang == $lang['id_lang'] ? 1 : 0) + ); + } + $helper->default_form_language = $default_lang; + $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? + Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0; + $this->config_list = $this->getConfigList(); + //add code for override tpl folder + if ($this->name != 'ApRow' && $this->name != 'ApColumn' && $this->name != 'ApModule') { + $this->config_list[count($this->config_list)] = array( + 'type' => 'text', + 'name' => 'override_folder', + 'label' => $this->l('Override Folder', 'shortcodes'), + 'desc' => $this->l('[Developer Only] System will auto create folder, you can put tpl of this shortcode to the folder. You can use this function to show 2 different layout', 'shortcodes'), + 'form_group_class' => 'aprow_general', + 'default' => '' + ); + } + + $w_info = $this->getInfo(); + $title_widget = array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '', + ); + array_unshift($this->config_list, $title_widget); + $helper->submit_action = $this->name; + $field_value = $this->getConfigValue(); + $this->addConfigList($field_value); + $fields_form = array( + 'form' => array( + 'input' => $this->config_list, + 'name' => $this->name, + 'class' => $this->name, + 'tinymce' => $this->tinymce + ), + ); + $helper->tpl_vars = array( + 'fields_value' => $field_value, + 'widthList' => ApPageSetting::returnWidthList(), + ); + + $this->helper = $helper; + if (method_exists($this, $method_name = 'endRenderForm')) { + $this->$method_name(); + } + + return $this->helper->generateForm(array($fields_form)); + } + + /** + * Widget can override this method and add more config at here + */ + public function addConfigList($field_value) + { + // validate module + unset($field_value); + } + + /** + * Widget can override this method and add more config at here + */ + public function displayModuleExceptionList() + { + return ''; + } + + public function ajaxProcessRender($module) + { + // validate module + unset($module); + } + } + +} diff --git a/modules/appagebuilder/classes/shortcodes/ApAccordions.php b/modules/appagebuilder/classes/shortcodes/ApAccordions.php new file mode 100644 index 00000000..55edc948 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApAccordions.php @@ -0,0 +1,221 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApAccordions extends ApShortCodeBase +{ + public $name = 'ApAccordions'; + + public function getInfo() + { + return array('label' => $this->l('Accordions'), + 'position' => 5, 'desc' => $this->l('You can put widget in accordions'), + 'icon_class' => 'icon icon-align-justify', + 'tag' => 'content'); + } + + public function getConfigList($sub_tab = 0) + { + if (Tools::getIsset('subTab') || $sub_tab) { + $input = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'lang' => 'true', + 'values' => '', + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '' + ), + array( + 'type' => 'text', + 'name' => 'id', + 'label' => $this->l('ID Accordion'), + 'values' => '' + ) + ); + $this->name = 'ApSubAccordion'; + } else { + $input = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'lang' => 'true', + 'default' => '', + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '' + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => '', + ), +// array( +// 'type' => 'select', +// 'label' => $this->l('Accordion Type'), +// 'name' => 'accordion_type', +// 'options' => array( +// 'query' => array( +// array( +// 'id' => 'vertical', +// 'name' => $this->l('Vertical'), +// ), +// array( +// 'id' => 'horizontal', +// 'name' => $this->l('Horizontal'), +// ) +// ), +// 'id' => 'id', +// 'name' => 'name' +// ), +// ), + array( + 'type' => 'select', + 'label' => $this->l('Showing Type'), + 'name' => 'active_type', + 'class' => 'form-action', + 'default' => 'hideall', + 'options' => array( + 'query' => array( + array( + 'id' => 'set', + 'name' => $this->l('Set active'), + ), + array( + 'id' => 'showall', + 'name' => $this->l('Show all'), + ), + array( + 'id' => 'hideall', + 'name' => $this->l('Hide all'), + ) + ), + 'id' => 'id', + 'name' => 'name' + ), + ), + array( + 'type' => 'text', + 'name' => 'active_accordion', + 'label' => $this->l('Active Accordion'), + 'default' => '1', + 'form_group_class' => 'active_type_sub active_type-set', + ), + ); + } + return $input; + } + + /** + * overide in tabs module + */ + public function adminContent($atts, $content = null, $tag_name = null, $is_gen_html = null) + { + $this->preparaAdminContent($atts, $tag_name); + if ($is_gen_html) { + $assign = array(); + $w_info = $this->getInfo(); + $w_info['name'] = $this->name; + if ($tag_name == 'ApAccordion') { + $assign['isSubTab'] = 1; + $w_info['name'] = 'ApAccordion'; + } else { + preg_match_all('/ parent_id="([^\"]+)"{0,1}/i', $content, $matches, PREG_OFFSET_CAPTURE); + if (isset($matches['1']['0']['0'])) { + $atts['id'] = $matches['1']['0']['0']; + } + } + $assign['formAtts'] = $atts; + $assign['apInfo'] = $w_info; + $assign['apContent'] = ApShortCodesBuilder::doShortcode($content); + $controller = new AdminApPageBuilderShortcodesController(); + return $controller->adminContent($assign, $this->name.'.tpl'); + } else { + ApShortCodesBuilder::doShortcode($content); + } + } + + /** + * overide in tabs module + */ + public function fontContent($atts, $content = null, $tag_name = null, $is_gen_html = null) + { + $is_active = $this->isWidgetActive(array('formAtts' => $atts)); + if (!$is_active) { + return ''; + } + + foreach ($atts as $key => $val) { + if (strpos($key, 'content') !== false || strpos($key, 'link') !== false || strpos($key, 'url') !== false || strpos($key, 'alt') !== false || strpos($key, 'tit') !== false || strpos($key, 'name') !== false || strpos($key, 'desc') !== false || strpos($key, 'itemscustom') !== false) { + $atts[$key] = str_replace($this->str_search, $this->str_relace_html, $val); + if (strpos($atts[$key], '_AP_IMG_DIR') !== false) { + // validate module + $atts[$key] = str_replace('_AP_IMG_DIR/', $this->theme_img_module, $atts[$key]); + } + } + } + // validate module + unset($is_gen_html); + $assign = $w_info = array(); + $w_info['name'] = $this->name; + if ($tag_name == 'ApAccordion') { + $assign['isSubTab'] = 1; + $w_info['name'] = 'ApAccordion'; + } else { + //DONGND:: check correct wrapper ApAccordion + $assign['isWrapper'] = 1; + preg_match_all('/ parent_id="([^\"]+)"{0,1}/i', $content, $matches, PREG_OFFSET_CAPTURE); + if (isset($matches['1']['0']['0'])) { + $atts['id'] = $matches['1']['0']['0']; + } + + if (!isset($atts['active_accordion'])) { + $active_tab = 0; + // validate module + unset($active_tab); + } else { + # SET ACTIVE + if (isset($atts['title']) && !empty($atts['title'])) { + $atts['active_accordion'] = $atts['active_accordion'] + 1; + } + } + } + $content = ApShortCodesBuilder::doShortcode($content); + $assign['apContent'] = $content; + $assign['formAtts'] = $atts; + $module = APPageBuilder::getInstance(); + return $module->fontContent($assign, $this->name.'.tpl'); + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApAlert.php b/modules/appagebuilder/classes/shortcodes/ApAlert.php new file mode 100644 index 00000000..aba08c7c --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApAlert.php @@ -0,0 +1,99 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApAlert extends ApShortCodeBase +{ + public $name = 'ApAlert'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Alert'), + 'position' => 5, + 'desc' => $this->l('Alert Message box'), + 'icon_class' => 'icon-info-sign', + 'tag' => 'content'); + } + + public function getConfigList() + { + $types = array( + array( + 'value' => 'alert-success', + 'text' => $this->l('Alert Success') + ), + array( + 'value' => 'alert-info', + 'text' => $this->l('Alert Info') + ), + array( + 'value' => 'alert-warning', + 'text' => $this->l('Alert Warning') + ), + array( + 'value' => 'alert-danger', + 'text' => $this->l('Alert Danger') + ) + ); + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'form_group_class' => 'aprow_general', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '' + ), + array( + 'type' => 'textarea', + 'lang' => true, + 'label' => $this->l('Content'), + 'name' => 'content_html', + 'cols' => 40, + 'rows' => 10, + 'value' => true, + 'lang' => true, + 'default' => '', + 'autoload_rte' => true, + ), + array( + 'type' => 'select', + 'label' => $this->l('Alert Type'), + 'name' => 'alert_type', + 'options' => array('query' => $types, + 'id' => 'value', + 'name' => 'text'), + 'default' => '1', + 'desc' => $this->l('Select a alert style') + ) + ); + return $inputs; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApBlockCarousel.php b/modules/appagebuilder/classes/shortcodes/ApBlockCarousel.php new file mode 100644 index 00000000..63123fc5 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApBlockCarousel.php @@ -0,0 +1,1010 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApBlockCarousel extends ApShortCodeBase +{ + public $name = 'ApBlockCarousel'; + + public function getInfo() + { + return array('label' => $this->l('Block Carousel'), 'position' => 6, + 'desc' => $this->l('Show block in Carousel'), + 'icon_class' => 'icon icon-chevron-right', + 'tag' => 'content slider'); + } + + public function getConfigList() + { + $href = Context::getContext()->link->getAdminLink('AdminApPageBuilderImages').'&ajax=1&action=manageimage&imgDir=images'; + $ad = __PS_BASE_URI__.basename(_PS_ADMIN_DIR_); + $iso_tiny_mce = Context::getContext()->language->iso_code; + $iso_tiny_mce = (file_exists(_PS_JS_DIR_.'tiny_mce/langs/'.$iso_tiny_mce.'.js') ? $iso_tiny_mce : 'en'); + $list_slider = '
'; + $list_slider_button = '
+
+
+ + + +
+
+ +
+
'; + $input = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '' + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => '', + ), + array( + 'type' => 'text', + 'name' => 'description', + 'label' => $this->l('Description'), + ), + array( + 'type' => 'switch', + 'label' => $this->l('Open new tab'), + 'desc' => $this->l('Open new tab when click to link in slider'), + 'name' => 'is_open', + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
'.$this->l('Step 1: Select type').'
' + ), + array( + 'type' => 'select', + 'label' => $this->l('Carousel Type'), + 'class' => 'form-action', + 'name' => 'carousel_type', + 'options' => array( + 'query' => array( + array('id' => 'boostrap', 'name' => $this->l('Bootstrap')), + array('id' => 'owlcarousel', 'name' => $this->l('Owl Carousel')), + array('id' => 'slickcarousel', 'name' => $this->l('Slick Carousel')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => 'boostrap' + ), + //Owl Carousel begin + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
'.$this->l('Items per Row').'
', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'items', + 'label' => $this->l('Items'), + 'desc' => $this->l('Typing number of items. Default'), + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + 'default' => '5', + ), + array( + 'type' => 'text', + 'name' => 'itemsdesktop', + 'label' => $this->l('Items_Desktop'), + 'desc' => $this->l('Typing number of items ( with Screen < 1200 )'), + 'default' => '4', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemsdesktopsmall', + 'label' => $this->l('Items_Desktop_Small'), + 'desc' => $this->l('Typing number of items ( with Screen < 992 )'), + 'default' => '3', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemstablet', + 'label' => $this->l('Items_Tablet'), + 'desc' => $this->l('Typing number of items ( with Screen < 768 )'), + 'default' => '2', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemsmobile', + 'label' => $this->l('Items_Mobile'), + 'desc' => $this->l('Typing number of items ( with Screen < 576 )'), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemscustom', + 'label' => $this->l('Items_Custom'), + 'desc' => $this->l('(Advance User) Example: [[0, 2], [576, 3], [768, 4], [992, 5], [1200, 6]]. The format is [x,y] whereby x=browser width and y=number of slides displayed'), + 'default' => '', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itempercolumn', + 'label' => $this->l('Items per Column'), + 'desc' => $this->l('Number of item per one column. Same with number of line for one page'), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
'.$this->l('Effect').'
', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Autoplay'), + 'name' => 'autoplay', + 'is_bool' => true, + 'desc' => $this->l('Yes - scroll per page. No - scroll per item. This affect next/prev buttons and mouse/touch dragging.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Stop on Hover'), + 'name' => 'stoponhover', + 'is_bool' => true, + 'desc' => $this->l('Stop autoplay on mouse hover'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Responsive'), + 'name' => 'responsive', + 'is_bool' => true, + 'desc' => $this->l('You can use Owl Carousel on desktop-only websites too! Just change that to "false" to disable resposive capabilities'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Navigation'), + 'name' => 'navigation', + 'is_bool' => true, + 'desc' => $this->l('Display "next" and "prev" buttons.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Auto Height'), + 'name' => 'autoHeight', + 'is_bool' => true, + 'desc' => $this->l('Add height to owl-wrapper-outer so you can use diffrent heights on slides. Use it only for one item per page setting.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Mouse Drag'), + 'name' => 'mouseDrag', + 'is_bool' => true, + 'desc' => $this->l('On DeskTop - Turn off/on mouse events.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Touch Drag'), + 'name' => 'touchdrag', + 'is_bool' => true, + 'desc' => $this->l('On Mobile - Turn off/on touch events.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
'.$this->l('Lazy Load: This function is only work when have one item per column').'
', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Lazy Load'), + 'name' => 'lazyload', + 'values' => ApPageSetting::returnYesNo(), + 'desc' => $this->l('Delays loading of images. Images outside of viewport will not be loaded before user scrolls to them. Great for mobile devices to speed up page loadings'), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Lazy Follow'), + 'name' => 'lazyfollow', + 'is_bool' => true, + 'desc' => $this->l('When pagination used, it skips loading the images from pages that got skipped. It only loads the images that get displayed in viewport. If set to false, all images get loaded when pagination used. It is a sub setting of the lazy load function.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'select', + 'label' => $this->l('Lazy Effect'), + 'name' => 'lazyeffect', + 'options' => array( + 'query' => array( + array('id' => 'fade', 'name' => $this->l('fade')), + array('id' => 'false', 'name' => $this->l('No')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'desc' => $this->l('Default is fadeIn on 400ms speed. Use false to remove that effect.'), + 'default' => 'fade', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Pagination Enable'), + 'name' => 'pagination', + 'is_bool' => true, + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'desc' => $this->l('Show Pagination below owl-carousel.'), + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Pagination Numbers'), + 'name' => 'paginationnumbers', + 'is_bool' => true, + 'desc' => $this->l('Show numbers inside Pagination'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
'.$this->l('NEXT PAGE').'
', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Scroll per Page'), + 'name' => 'scrollPerPage', + 'is_bool' => true, + 'desc' => $this->l('Yes - scroll per Page. No - scroll per Item. This affect next/prev buttons and mouse/touch dragging.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'label' => $this->l('Scroll Page Speed'), + 'name' => 'paginationspeed', + 'desc' => $this->l('Time to next page. Ex 800 ( Milliseconds )'), + 'default' => '800', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'label' => $this->l('Scroll Item Speed'), + 'name' => 'slidespeed', + 'desc' => $this->l('Time to next item. Ex 200 (Milliseconds)'), + 'default' => '200', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + //Owl Carousel end + //boostrap carousel begin + + //Slick carousel start + array( + 'type' => 'select', + 'label' => $this->l('Vertical'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'name' => 'slick_vertical', + 'options' => array( + 'query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => '0' + ), + array( + 'type' => 'select', + 'name' => 'slick_autoplay', + 'label' => $this->l('Auto play'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'options' => array('query' => array( + array('id' => '1', 'name' => $this->l('Yes')), + array('id' => '0', 'name' => $this->l('No')), + ), + 'id' => 'id', + 'name' => 'name') + ), + array( + 'type' => 'select', + 'name' => 'slick_pauseonhover', + 'label' => $this->l('Pause on Hover'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'options' => array('query' => array( + array('id' => '1', 'name' => $this->l('Yes')), + array('id' => '0', 'name' => $this->l('No')), + ), + 'id' => 'id', + 'name' => 'name') + ), + array( + 'type' => 'select', + 'name' => 'slick_loopinfinite', + 'label' => $this->l('Loop Infinite'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '0', + 'options' => array('query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'name' => 'slick_arrows', + 'label' => $this->l('Prev/Next Arrows'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'options' => array('query' => array( + array('id' => '1', 'name' => $this->l('Yes')), + array('id' => '0', 'name' => $this->l('No')), + ), + 'id' => 'id', + 'name' => 'name') + ), + array( + 'type' => 'select', + 'name' => 'slick_dot', + 'label' => $this->l('Show dot indicators'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '0', + 'options' => array('query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name') + ), + array( + 'type' => 'select', + 'name' => 'slick_centermode', + // 'class' => 'form-action', + 'label' => $this->l('Center mode'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '0', + 'options' => array('query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name') + ), + array( + 'type' => 'text', + 'name' => 'slick_centerpadding', + 'label' => $this->l('Center padding'), + 'desc' => $this->l('Only for center mode. Unit is px (pixel). Default: 60(px)'), + 'default' => '60', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + array( + 'type' => 'text', + 'name' => 'slick_row', + 'label' => $this->l('Num Row'), + 'desc' => $this->l('Show number row display. Ex 1 or 1,2,3,4 '), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel' + ), + array( + 'type' => 'text', + 'name' => 'slick_slidestoshow', + 'label' => $this->l('Slides To Show'), + 'desc' => $this->l('Show number row display. Ex 1 or 1,2,3,4 '), + 'default' => '5', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel' + ), + array( + 'type' => 'text', + 'name' => 'slick_slidestoscroll', + 'label' => $this->l('Slides To Scroll'), + 'desc' => $this->l('Show number row display. Ex 1 or 1,2,3,4 '), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel' + ), + array( + 'type' => 'text', + 'name' => 'slick_items_custom', + 'label' => $this->l('Display for other screen'), + 'desc' => $this->l('(Advance User) Example: [[1200, 6],[992, 5],[768, 4], [576, 3],[480, 2]]. The format is [x,y] whereby x=browser width and y=number of slides displayed'), + 'default' => '[[1200, 6],[992, 5],[768, 4], [576, 3],[480, 2]]', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel' + ), + + array( + 'type' => 'select', + 'name' => 'slick_custom_status', + // 'class' => 'form-action', + 'label' => $this->l('Enable custom js slick'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l('Only for developers and advanced users. Goto http://kenwheeler.github.io/slick/ for option'), + 'options' => array('query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name'), + 'default' => '0' + ), + array( + 'type' => 'textarea', + 'name' => 'slick_custom', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'label' => $this->l('Custom js Slick'), + 'values' => '', + 'autoload_rte' => false, + 'default' => '{ + dots: true, + infinite: false, + speed: 300, + slidesToShow: 4, + slidesToScroll: 4, + responsive: [ + { + breakpoint: 1024, + settings: { + slidesToShow: 3, + slidesToScroll: 3, + infinite: true, + dots: true + } + }, + { + breakpoint: 600, + settings: { + slidesToShow: 2, + slidesToScroll: 2 + } + }, + { + breakpoint: 480, + settings: { + slidesToShow: 1, + slidesToScroll: 1 + } + } + ] +}', + // 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + + //Slick carousel end + + + array( + 'type' => 'text', + 'name' => 'nbitemsperpage', + 'label' => $this->l('Number of Item per Page'), + 'desc' => $this->l('How many product you want to display in a Page. Divisible by Item per Line (Desktop, Table, mobile)(default:12)'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + 'default' => '12', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
'.$this->l('Items per Row').'
', + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_Desktop ( >= 1200 )'), + 'name' => 'nbitemsperline_desktop', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + array('id' => '12', 'name' => $this->l('12 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 4'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_SmallDesktop ( >= 992 )'), + 'name' => 'nbitemsperline_smalldesktop', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + array('id' => '12', 'name' => $this->l('12 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 3'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_Tablet ( >= 768 )'), + 'name' => 'nbitemsperline_tablet', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + array('id' => '12', 'name' => $this->l('12 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 3'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_SmallDevices ( >= 576 )'), + 'name' => 'nbitemsperline_smalldevices', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 2'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_ExtraSmallDevices ( >= 480 )'), + 'name' => 'nbitemsperline_extrasmalldevices', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 1'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_Smartphone ( < 480 )'), + 'name' => 'nbitemsperline_smartphone', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 1'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'text', + 'name' => 'interval', + 'label' => $this->l('interval'), + 'desc' => $this->l('The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle.'), + 'default' => '5000', + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
'.$this->l('Step 2: Add content for sliders').'
' + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => $list_slider + ), + array( + 'label' => $this->l('Image'), + 'type' => 'selectImg', + 'href' => $href, + 'name' => 'temp_image', + 'lang' => true, + 'class' => 'item-add-slide ignore-lang', + 'form_group_class' => 'apfullslider-row select-img', + ), + array( + 'type' => 'text', + 'name' => 'temp_title', + 'label' => $this->l('Title'), + 'lang' => 'true', + 'default' => '', + 'class' => 'item-add-slide ignore-lang', + 'form_group_class' => 'apfullslider-row title-slide', + ), + array( + 'type' => 'text', + 'name' => 'temp_link', + 'label' => $this->l('Link'), + 'lang' => 'true', + 'default' => '', + 'class' => 'item-add-slide ignore-lang', + 'form_group_class' => 'apfullslider-row link-slide', + ), + array( + 'type' => 'textarea', + 'label' => $this->l('Description'), + 'name' => 'temp_descript', + 'cols' => 40, + 'rows' => 10, + 'value' => true, + 'lang' => true, + 'default' => '', + 'class' => 'item-add-slide ignore-lang', + 'form_group_class' => 'apfullslider-row description-slide', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => $list_slider_button + ), + array( + 'type' => 'hidden', + 'name' => 'total_slider', + 'default' => '' + ), + ); + return $input; + } + + public function addConfigList($values) + { + // Get value with keys special + $config_val = array(); + $total = isset($values['total_slider']) ? $values['total_slider'] : ''; + $arr = explode('|', $total); + $inputs = array('tit', 'img', 'link', 'descript'); + $languages = Language::getLanguages(false); + foreach ($arr as $i) { + foreach ($inputs as $config) { + foreach ($languages as $lang) { + $config_val[$config][$i][$lang['id_lang']] = str_replace($this->str_search, $this->str_relace_html_admin, Tools::getValue($config.'_'.$i.'_'.$lang['id_lang'], '')); + // print_r($config_val); + // echo '===='; + } + } + } + + Context::getContext()->smarty->assign(array( + 'lang' => $lang = new Language((int)Configuration::get('PS_LANG_DEFAULT')), + 'default_lang' => $lang->id, + 'arr' => $arr, + 'languages' => $languages, + 'config_val' => $config_val, + 'path' => apPageHelper::getImgThemeUrl(), + )); + $list_slider = Context::getContext()->smarty->fetch(apPageHelper::getShortcodeTemplatePath('ApBlockCarousel.tpl')); + + $input = array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => $list_slider, + ); + // Append new input type html + $this->config_list[] = $input; + } + public function endRenderForm() + { + $this->helper->module = new $this->module_name(); + + // KEEP OLD DATA + if (Tools::getIsset('nbitemsperline') && Tools::getValue('nbitemsperline')) { + $this->helper->tpl_vars['fields_value']['nbitemsperline_desktop'] = Tools::getValue('nbitemsperline'); + $this->helper->tpl_vars['fields_value']['nbitemsperline_smalldesktop'] = Tools::getValue('nbitemsperline'); + $this->helper->tpl_vars['fields_value']['nbitemsperline_tablet'] = Tools::getValue('nbitemsperline'); + } + + if (Tools::getIsset('nbitemsperlinetablet') && Tools::getValue('nbitemsperlinetablet')) { + $this->helper->tpl_vars['fields_value']['nbitemsperline_smalldevices'] = Tools::getValue('nbitemsperlinetablet'); + } + + if (Tools::getIsset('nbitemsperlinemobile') && Tools::getValue('nbitemsperlinemobile')) { + $this->helper->tpl_vars['fields_value']['nbitemsperline_extrasmalldevices'] = Tools::getValue('nbitemsperlinemobile'); + $this->helper->tpl_vars['fields_value']['nbitemsperline_smartphone'] = Tools::getValue('nbitemsperlinemobile'); + } + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + + if (isset($assign['formAtts']['carousel_type']) && $assign['formAtts']['carousel_type'] == 'owlcarousel') { + if (!Configuration::get('APPAGEBUILDER_LOAD_OWL')) { + $assign['formAtts']['lib_has_error'] = true; + $assign['formAtts']['lib_error'] = 'Can not show Block Carousel. Please enable Owl Carousel library in Appagebuilder Configuration.'; + return $assign; + } + } + $list = explode('|', isset($assign['formAtts']['total_slider']) ? $assign['formAtts']['total_slider'] : ''); + $sliders = array(); + // $lang = Language::getLanguage(Context::getContext()->language->id); + // $lang_default = $lang['id_lang']; + // foreach ($list as $item) + // if ($item) + // { + // $slider = array(); + // $slider['id'] = $item; + // $slider['title'] = isset($assign['formAtts']['tit_'.$item]) ? $assign['formAtts']['tit_'.$item] : ''; + // $slider['image'] = isset($assign['formAtts']['image_'.$item]) ? $assign['formAtts']['image_'.$item] : ''; + // $slider['link'] = isset($assign['formAtts']['link_'.$item]) ? $assign['formAtts']['link_'.$item] : ''; + // $slider['descript'] = str_replace($this->str_search, $this->str_relace_html, isset($assign['formAtts']['descript_'.$item]) + // ? $assign['formAtts']['descript_'.$item] : ''); + // $sliders[] = $slider; + // } + $lang = Language::getLanguage(Context::getContext()->language->id); + $lang_default = $lang['id_lang']; + foreach ($list as $item) { + if ($item) { + $temp = $item.'_'.$lang_default; + $slider = array(); + $slider['id'] = $item; + $slider['title'] = isset($assign['formAtts']['tit_'.$temp]) ? $assign['formAtts']['tit_'.$temp] : ''; + $slider['link'] = isset($assign['formAtts']['link_'.$temp]) ? $assign['formAtts']['link_'.$temp] : ''; + if (isset($assign['formAtts']['img_'.$temp]) && $assign['formAtts']['img_'.$temp]) { + // validate module + $slider['image'] = apPageHelper::getImgThemeUrl().$assign['formAtts']['img_'.$temp]; + } else { + // validate module + $slider['image'] = ''; + } + $desc = isset($assign['formAtts']['descript_'.$temp]) ? $assign['formAtts']['descript_'.$temp] : ''; + $slider['descript'] = str_replace($this->str_search, $this->str_relace_html, $desc); + //$slider['descript'] = $assign['formAtts']['descript_'.$temp]; + $sliders[] = $slider; + } + } + $assign['formAtts']['is_open'] = isset($assign['formAtts']['is_open']) ? $assign['formAtts']['is_open'] : 0; + $assign['formAtts']['slides'] = $sliders; + $assign['carouselName'] = 'carousel-'.ApPageSetting::getRandomNumber(); + if ($assign['formAtts']['carousel_type'] == 'boostrap') { + if (isset($assign['formAtts']['nbitemsperline']) && $assign['formAtts']['nbitemsperline']) { + $assign['formAtts']['nbitemsperline_desktop'] = $assign['formAtts']['nbitemsperline']; + $assign['formAtts']['nbitemsperline_smalldesktop'] = $assign['formAtts']['nbitemsperline']; + $assign['formAtts']['nbitemsperline_tablet'] = $assign['formAtts']['nbitemsperline']; + } + if (isset($assign['formAtts']['nbitemsperlinetablet']) && $assign['formAtts']['nbitemsperlinetablet']) { + $assign['formAtts']['nbitemsperline_smalldevices'] = $assign['formAtts']['nbitemsperlinetablet']; + } + if (isset($assign['formAtts']['nbitemsperlinemobile']) && $assign['formAtts']['nbitemsperlinemobile']) { + $assign['formAtts']['nbitemsperline_extrasmalldevices'] = $assign['formAtts']['nbitemsperlinemobile']; + $assign['formAtts']['nbitemsperline_smartphone'] = $assign['formAtts']['nbitemsperlinemobile']; + } + + $assign['formAtts']['nbitemsperline_desktop'] = isset($assign['formAtts']['nbitemsperline_desktop']) && $assign['formAtts']['nbitemsperline_desktop'] ? (int)$assign['formAtts']['nbitemsperline_desktop'] : 4; + $assign['formAtts']['nbitemsperline_smalldesktop'] = isset($assign['formAtts']['nbitemsperline_smalldesktop']) && $assign['formAtts']['nbitemsperline_smalldesktop'] ? (int)$assign['formAtts']['nbitemsperline_smalldesktop'] : 4; + $assign['formAtts']['nbitemsperline_tablet'] = isset($assign['formAtts']['nbitemsperline_tablet']) && $assign['formAtts']['nbitemsperline_tablet'] ? (int)$assign['formAtts']['nbitemsperline_tablet'] : 3; + $assign['formAtts']['nbitemsperline_smalldevices'] = isset($assign['formAtts']['nbitemsperline_smalldevices']) && $assign['formAtts']['nbitemsperline_smalldevices'] ? (int)$assign['formAtts']['nbitemsperline_smalldevices'] : 2; + $assign['formAtts']['nbitemsperline_extrasmalldevices'] = isset($assign['formAtts']['nbitemsperline_extrasmalldevices']) && $assign['formAtts']['nbitemsperline_extrasmalldevices'] ? (int)$assign['formAtts']['nbitemsperline_extrasmalldevices'] : 1; + $assign['formAtts']['nbitemsperline_smartphone'] = isset($assign['formAtts']['nbitemsperline_smartphone']) && $assign['formAtts']['nbitemsperline_smartphone'] ? (int)$assign['formAtts']['nbitemsperline_smartphone'] : 1; + + $assign['tabname'] = 'carousel-'.ApPageSetting::getRandomNumber(); + $assign['itemsperpage'] = (int)$assign['formAtts']['nbitemsperpage']; + $assign['nbItemsPerLine'] = (int)$assign['formAtts']['nbitemsperline_desktop']; + + $assign['scolumn'] = ''; + + if ($assign['formAtts']['nbitemsperline_desktop'] == '5') { + $assign['scolumn'] .= ' col-xl-2-4'; + } else { + $assign['scolumn'] .= ' col-xl-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_desktop'])); + } + + if ($assign['formAtts']['nbitemsperline_smalldesktop'] == '5') { + $assign['scolumn'] .= ' col-lg-2-4'; + } else { + $assign['scolumn'] .= ' col-lg-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_smalldesktop'])); + } + + if ($assign['formAtts']['nbitemsperline_tablet'] == '5') { + $assign['scolumn'] .= ' col-md-2-4'; + } else { + $assign['scolumn'] .= ' col-md-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_tablet'])); + } + + if ($assign['formAtts']['nbitemsperline_smalldevices'] == '5') { + $assign['scolumn'] .= ' col-sm-2-4'; + } else { + $assign['scolumn'] .= ' col-sm-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_smalldevices'])); + } + + if ($assign['formAtts']['nbitemsperline_extrasmalldevices'] == '5') { + $assign['scolumn'] .= ' col-xs-2-4'; + } else { + $assign['scolumn'] .= ' col-xs-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_extrasmalldevices'])); + } + + if ($assign['formAtts']['nbitemsperline_smartphone'] == '5') { + $assign['scolumn'] .= ' col-sp-2-4'; + } else { + $assign['scolumn'] .= ' col-sp-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_smartphone'])); + } + } + + //DONGND:: create data for owl carousel with item custom + if ($assign['formAtts']['carousel_type'] == 'owlcarousel') { + //DONGND:: build data for fake item loading + $assign['formAtts']['number_fake_item'] = $assign['formAtts']['items']; + $array_fake_item = array(); + $array_fake_item['m'] = $assign['formAtts']['itemsmobile']; + $array_fake_item['sm'] = $assign['formAtts']['itemstablet']; + $array_fake_item['md'] = $assign['formAtts']['itemsdesktopsmall']; + $array_fake_item['lg'] = $assign['formAtts']['itemsdesktop']; + $array_fake_item['xl'] = $assign['formAtts']['items']; + $assign['formAtts']['array_fake_item'] = $array_fake_item; + + if (isset($assign['formAtts']['itemscustom']) && $assign['formAtts']['itemscustom'] != '') { + $array_item_custom = Tools::jsonDecode($assign['formAtts']['itemscustom']); + $array_item_custom_tmp = array(); + $array_number_item = array(); + foreach ($array_item_custom as $array_item_custom_val) { + $size_window = $array_item_custom_val[0]; + $number_item = $array_item_custom_val[1]; + if (0 <= $size_window && $size_window < 576) { + $array_item_custom_tmp['m'] = $number_item; + } else if (576 <= $size_window && $size_window < 768) { + $array_item_custom_tmp['sm'] = $number_item; + } else if (768 <= $size_window && $size_window < 992) { + $array_item_custom_tmp['md'] = $number_item; + } else if (992 <= $size_window && $size_window < 1200) { + $array_item_custom_tmp['lg'] = $number_item; + } else if ($size_window >= 1200) { + $array_item_custom_tmp['xl'] = $number_item; + } + $array_item_custom_tmp[$size_window] = $number_item; + $array_number_item[] = $number_item; + }; + $assign['formAtts']['array_fake_item'] = array_merge($array_fake_item, $array_item_custom_tmp); + + if (max($array_number_item) > $assign['formAtts']['items']) { + $assign['formAtts']['number_fake_item'] = max($array_number_item); + } + } + } + if ($assign['formAtts']['carousel_type'] == 'slickcarousel') { + if (isset($assign['formAtts']['slick_items_custom'])) { + $assign['formAtts']['slick_items_custom'] = str_replace($this->str_search, $this->str_relace, $assign['formAtts']['slick_items_custom']); + } + if (isset($assign['formAtts']['slick_custom'])) { + $str_relace = array('&', '\"', '\'', '', '', '', '[', ']'); + $assign['formAtts']['slick_custom'] = str_replace($this->str_search, $str_relace, $assign['formAtts']['slick_custom']); + } + if (isset($assign['formAtts']['slick_items_custom'])) { + $assign['formAtts']['slick_items_custom'] = Tools::jsonDecode($assign['formAtts']['slick_items_custom']); + } + + //DONGND:: build data for fake item loading + $assign['formAtts']['number_fake_item'] = $assign['formAtts']['slick_slidestoshow']*$assign['formAtts']['slick_row']; + + if (isset($assign['formAtts']['slick_items_custom']) && $assign['formAtts']['slick_items_custom'] != '') { + $array_item_custom = $assign['formAtts']['slick_items_custom']; + $array_item_custom_tmp = array(); + $array_number_item = array(); + foreach ($array_item_custom as $array_item_custom_val) { + $size_window = $array_item_custom_val[0]; + $number_item = $array_item_custom_val[1]; + if (0 <= $size_window && $size_window < 576) { + $array_item_custom_tmp['m'] = $number_item; + } else if (576 <= $size_window && $size_window < 768) { + $array_item_custom_tmp['sm'] = $number_item; + } else if (768 <= $size_window && $size_window < 992) { + $array_item_custom_tmp['md'] = $number_item; + } else if (992 <= $size_window && $size_window < 1200) { + $array_item_custom_tmp['lg'] = $number_item; + } else if ($size_window >= 1200) { + $array_item_custom_tmp['xl'] = $assign['formAtts']['slick_slidestoshow']; + } + $number_item = $number_item*$assign['formAtts']['slick_row']; + $array_item_custom_tmp[$size_window] = $number_item; + $array_number_item[] = $number_item; + }; + $assign['formAtts']['array_fake_item'] = $array_item_custom_tmp; + + if (max($array_number_item) > $assign['formAtts']['slick_slidestoshow']) { + $assign['formAtts']['number_fake_item'] = max($array_number_item); + } + } + } + return $assign; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApBlockLink.php b/modules/appagebuilder/classes/shortcodes/ApBlockLink.php new file mode 100644 index 00000000..d99fdfcd --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApBlockLink.php @@ -0,0 +1,473 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApBlockLink extends ApShortCodeBase +{ + public $name = 'ApBlockLink'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Block Link'), + 'position' => 5, + 'desc' => $this->l('Create List Block Links'), + 'icon_class' => 'icon icon-list', + 'tag' => 'content'); + } + + public function getConfigList() + { + $types = array( + array( + 'value' => 'link-url', + 'text' => $this->l('URL') + ), + array( + 'value' => 'link-category', + 'text' => $this->l('Category') + ), + array( + 'value' => 'link-product', + 'text' => $this->l('Product') + ), + array( + 'value' => 'link-manufacture', + 'text' => $this->l('Manufacture') + ), + array( + 'value' => 'link-supplier', + 'text' => $this->l('Supplier') + ), + array( + 'value' => 'link-cms', + 'text' => $this->l('CMS') + ), + array( + 'value' => 'link-page', + 'text' => $this->l('Page Controller') + ), + ); + + $target = array( + array( + 'value' => '_blank', + 'text' => $this->l('Blank ( New Tab)') + ), + array( + 'value' => '_self', + 'text' => $this->l('Self ( Same Tab)') + ), + array( + 'value' => '_parent', + 'text' => $this->l('Parent') + ), + array( + 'value' => '_top', + 'text' => $this->l('Top') + ), + ); + $accordion_type = array( + array( + 'value' => 'full', + 'text' => $this->l('Always Full') + ), + array( + 'value' => 'accordion', + 'text' => $this->l('Always Accordion') + ), + array( + 'value' => 'accordion_small_screen', + 'text' => $this->l('Accordion at small screen') + ), + ); + $page_controller = array(); + foreach (Meta::getPages() as $page) { + if (strpos($page, 'module') === false) { + $array_tmp = array(); + $array_tmp['link'] = $page; + $array_tmp['name'] = $page; + array_push($page_controller, $array_tmp); + } + } + # $sqlFilter : NOT SHOW ROOT CATEOGRY, ONLY SHOW FROM HOME + $list_categories = Category::getAllCategoriesName(null, Context::getContext()->language->id, true, null, true, ' AND c.id_parent != 0 '); + $languages = Language::getLanguages(true, Context::getContext()->shop->id); + + $languages = Language::getLanguages(); + $list_id_lang = array(); + foreach ($languages as $languages_val) { + array_push($list_id_lang, $languages_val['id_lang']); + } + + // Get value with keys special + $languages = Language::getLanguages(false); + $config_val = array(); + + $list_field = Tools::getValue('list_field'); + $list_field = array_filter(explode(',', $list_field)); + foreach ($list_field as $field) { + $key = $field; + $config_val[$key] = str_replace($this->str_search, $this->str_relace_html_admin, Tools::getValue($key)); + } + + $list_field_lang = Tools::getValue('list_field_lang'); + $list_field_lang = array_filter(explode(',', $list_field_lang)); + foreach ($languages as $lang) { + foreach ($list_field_lang as $field) { + $key = $field.'_'.$lang['id_lang']; + $config_val[$key] = str_replace($this->str_search, $this->str_relace_html_admin, Tools::getValue($key)); + } + } + + $inputs = array( + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '', + 'form_group_class' => 'hidden', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '', + 'form_group_class' => 'hidden', + ), + array( + 'type' => 'hidden', + 'name' => 'total_link', + 'default' => '0', + 'form_group_class' => 'hidden', + ), + array( + 'type' => 'hidden', + 'name' => 'list_id_link', + 'default' => '', + 'form_group_class' => 'hidden', + ), + array( + 'type' => 'hidden', + 'name' => 'list_field', + 'default' => '', + 'form_group_class' => 'hidden', + ), + array( + 'type' => 'hidden', + 'name' => 'list_field_lang', + 'default' => '', + 'form_group_class' => 'hidden', + ), + array( + 'type' => 'blockLink', + 'name' => 'title', + 'lang' => 'true', + 'label' => $this->l('Title'), + 'default' => '', + 'form_group_class' => 'hidden', + ), + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Widget Title'), + 'hint' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'default' => '', + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Widget Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => '', + ), + array( + 'type' => 'select', + 'label' => $this->l('Accordion Type'), + 'name' => 'accordion_type', + 'options' => array( + 'query' => $accordion_type, + 'id' => 'value', + 'name' => 'text' ), + 'default' => 'full', + 'hint' => $this->l('Select a Accordion Type'), + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '', + 'form_group_class' => 'frm-add-new-link', + ), + array( + 'type' => 'text', + 'label' => $this->l('Title'), + 'name' => 'link_title', + 'lang' => true, + 'default' => '', + 'class' => 'tmp', + 'form_group_class' => 'parent-tmp hidden', + ), + array( + 'type' => 'select', + 'label' => $this->l('Target Type'), + 'name' => 'target_type', + 'options' => array( + 'query' => $target, + 'id' => 'value', + 'name' => 'text' ), + 'default' => '_self', + 'class' => 'tmp', + 'form_group_class' => 'parent-tmp hidden', + ), + array( + 'type' => 'select', + 'label' => $this->l('Link Type'), + 'name' => 'link_type', + 'options' => array( + 'query' => $types, + 'id' => 'value', + 'name' => 'text' ), + 'default' => 'link-url', + 'class' => 'form-action tmp', + 'hint' => $this->l('Select a link type'), + 'form_group_class' => 'parent-tmp hidden', + ), + + + + + + + + + array( + 'type' => 'text', + 'label' => $this->l('URL'), + 'name' => 'link_url', + 'lang' => true, + 'default' => '', + 'class' => 'tmp', + 'form_group_class' => 'link_type_sub link_type-link-url parent-tmp hidden', + ), + array( + 'type' => 'select', + 'label' => $this->l('CMS'), + 'name' => 'cmspage_id', + 'options' => array('query' => CMS::listCms(Context::getContext()->language->id, false, true), + 'id' => 'id_cms', + 'name' => 'meta_title'), + 'default' => '', + 'class' => 'tmp', + 'form_group_class' => 'link_type_sub link_type-link-cms parent-tmp hidden', + ), + array( + 'type' => 'select', + 'label' => $this->l('Categories'), + 'name' => 'category_id', + 'options' => array('query' => $list_categories, + 'id' => 'id_category', + 'name' => 'name'), + 'default' => '', + 'class' => 'tmp', + 'form_group_class' => 'link_type_sub link_type-link-category parent-tmp hidden', + ), + array( + 'type' => 'text', + 'label' => $this->l('Product ID'), + 'name' => 'product_id', + 'default' => '', + 'class' => 'tmp', + 'form_group_class' => 'link_type_sub link_type-link-product parent-tmp hidden', + 'hint' => $this->l('Enter a product id'), + ), + array( + 'type' => 'select', + 'label' => $this->l('Manufacture'), + 'name' => 'manufacture_id', + 'options' => array('query' => Manufacturer::getManufacturers(false, Context::getContext()->language->id, true), + 'id' => 'id_manufacturer', + 'name' => 'name'), + 'default' => '', + 'class' => 'tmp', + 'form_group_class' => 'link_type_sub link_type-link-manufacture parent-tmp hidden', + ), + array( + 'type' => 'select', + 'label' => $this->l('Supplier'), + 'name' => 'supplier_id', + 'options' => array('query' => Supplier::getSuppliers(false, Context::getContext()->language->id, true), + 'id' => 'id_supplier', + 'name' => 'name'), + 'default' => '', + 'class' => 'tmp', + 'form_group_class' => 'link_type_sub link_type-link-supplier parent-tmp hidden', + ), + array( + 'type' => 'select', + 'label' => $this->l('Page'), + 'name' => 'page_id', + 'options' => array('query' => $page_controller, + 'id' => 'link', + 'name' => 'name'), + 'default' => '', + 'class' => 'tmp', + 'form_group_class' => 'link_type_sub link_type-link-page parent-tmp hidden', + ), + array( + 'type' => 'text', + 'label' => $this->l('Parameter of page'), + 'name' => 'page_param', + 'default' => '', + 'hint' => $this->l('Param on URL. Example var=100&var2=110&var3=120'), + 'class' => 'tmp', + 'form_group_class' => 'link_type_sub link_type-link-page parent-tmp hidden', + ), + ); + + return $inputs; + } + + public function getConfigValue() + { + $config_val = parent::getConfigValue(); + $config_val['target_type'] = '_self'; + return $config_val; + } + + public function endRenderForm() + { + $this->helper->module = new $this->module_name(); + } + + public function prepareFontContent($assign, $module = null) + { + unset($module); + $formAtts = $assign['formAtts']; + $formAtts['links'] = array(); + + if (!isset($formAtts['list_id_link'])) { + $assign['formAtts']['lib_has_error'] = true; + $assign['formAtts']['lib_error'] = 'Can not show this Blocklink. Please remove it and create new Blocklink in Appbuilder Profile.'; + return $assign; + } + $id_forms = $formAtts['list_id_link']; + $id_forms = array_filter(explode(',', $id_forms)); + + foreach ($id_forms as $id_form) { + $index = '_'.$id_form; + $indexlang = $index.'_'.Context::getContext()->language->id; + $link = array(); + switch ($formAtts['link_type'.$index]) { + case 'link-url': + if (isset($formAtts['link_title'.$indexlang]) && $formAtts['link_title'.$indexlang]) { + $link['title'] = (isset($formAtts['link_title'.$indexlang]) && $formAtts['link_title'.$indexlang]) ? $formAtts['link_title'.$indexlang] : $formAtts['link_url'.$indexlang]; + $link['link'] = isset($formAtts['link_url'.$indexlang]) ? $formAtts['link_url'.$indexlang] : ''; + $link['target_type'] = isset($formAtts['target_type'.$index]) ? $formAtts['target_type'.$index] : '_self'; + $formAtts['links'][] = $link; + } + break; + case 'link-category': + $category = new Category((int)$formAtts['category_id'.$index], Context::getContext()->language->id, Context::getContext()->shop->id); + $link['title'] = (isset($formAtts['link_title'.$indexlang]) && $formAtts['link_title'.$indexlang]) ? $formAtts['link_title'.$indexlang] : $category->name; + $link['link'] = Context::getContext()->link->getCategoryLink($category); + $link['target_type'] = isset($formAtts['target_type'.$index]) ? $formAtts['target_type'.$index] : '_self'; + $formAtts['links'][] = $link; + break; + case 'link-product': + $product_id = isset($formAtts['product_id'.$index]) ? (int)$formAtts['product_id'.$index] : 0; + $product = new Product($product_id, true, Context::getContext()->language->id, Context::getContext()->shop->id); + $link['title'] = (isset($formAtts['link_title'.$indexlang]) && $formAtts['link_title'.$indexlang]) ? $formAtts['link_title'.$indexlang] : $product->name; + if ((int)$product->id > 0) { + $link['link'] = Context::getContext()->link->getProductLink($product); + } else { + $link['link'] = ''; + } + $link['target_type'] = isset($formAtts['target_type'.$index]) ? $formAtts['target_type'.$index] : '_self'; + $formAtts['links'][] = $link; + break; + case 'link-manufacture': + $manufacture = new Manufacturer($assign['formAtts']['manufacture_id'], Context::getContext()->language->id); + $link['title'] = (isset($formAtts['link_title'.$indexlang]) && $formAtts['link_title'.$indexlang]) ? $formAtts['link_title'.$indexlang] : $manufacture->name; + $link['link'] = Context::getContext()->link->getManufacturerLink((int)$manufacture->id, $manufacture->link_rewrite, Context::getContext()->language->id); + $link['target_type'] = isset($formAtts['target_type'.$index]) ? $formAtts['target_type'.$index] : '_self'; + $formAtts['links'][] = $link; + break; + case 'link-supplier': + $supplier = new Supplier($assign['formAtts']['supplier_id'], Context::getContext()->language->id); + $link['title'] = (isset($formAtts['link_title'.$indexlang]) && $formAtts['link_title'.$indexlang]) ? $formAtts['link_title'.$indexlang] : $supplier->name; + $link['link'] = Context::getContext()->link->getSupplierLink((int)$supplier->id, $supplier->link_rewrite, Context::getContext()->language->id); + $link['target_type'] = isset($formAtts['target_type'.$index]) ? $formAtts['target_type'.$index] : '_self'; + $formAtts['links'][] = $link; + break; + case 'link-cms': + $cms = new CMS((int)$formAtts['cmspage_id'.$index], Context::getContext()->language->id, Context::getContext()->shop->id); + $link['title'] = (isset($formAtts['link_title'.$indexlang]) && $formAtts['link_title'.$indexlang]) ? $formAtts['link_title'.$indexlang] : $cms->meta_title; + $link['link'] = Context::getContext()->link->getCMSLink($cms, $cms->link_rewrite, (bool)Configuration::get('PS_SSL_ENABLED')); + $link['target_type'] = isset($formAtts['target_type'.$index]) ? $formAtts['target_type'.$index] : '_self'; + $formAtts['links'][] = $link; + break; + case 'link-page': + $param = isset($formAtts['page_param'.$index]) ? $formAtts['page_param'.$index] : ''; +// $front_link = $this->getFronTLink($formAtts['page_id'.$index]); +// if ($front_link != false) { +// $formAtts['page_id'.$index] = $front_link; +// } + $link['link'] = Context::getContext()->link->getPageLink($formAtts['page_id'.$index], null, Context::getContext()->language->id, $param); + $link['title'] = (isset($formAtts['link_title'.$indexlang]) && $formAtts['link_title'.$indexlang]) ? $formAtts['link_title'.$indexlang] : Tools::ucfirst($formAtts['page_id'.$index]); + $link['target_type'] = isset($formAtts['target_type'.$index]) ? $formAtts['target_type'.$index] : '_self'; + $formAtts['links'][] = $link; + break; + } + } + + $assign['formAtts']['links'] = $formAtts['links']; + return $assign; + } + + public function getFronTLink($controller_param) + { + $controllers = Dispatcher::getControllers(array(_PS_FRONT_CONTROLLER_DIR_, _PS_OVERRIDE_DIR_.'controllers/front/')); + $controllers['index'] = 'IndexController'; + if (isset($controllers['auth'])) { + $controllers['authentication'] = $controllers['auth']; + } + if (isset($controllers['contact'])) { + $controllers['contactform'] = $controllers['contact']; + } + if (!isset($controllers[Tools::strtolower($controller_param)])) { + return false; + } + $controller_class = $controllers[Tools::strtolower($controller_param)]; + $controller_obj = Controller::getController($controller_class); + return $controller_obj->php_self; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApBlog.php b/modules/appagebuilder/classes/shortcodes/ApBlog.php new file mode 100644 index 00000000..6ac5d90c --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApBlog.php @@ -0,0 +1,1158 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApBlog extends ApShortCodeBase +{ + public $name = 'ApBlog'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Blog'), 'position' => 3, 'desc' => $this->l('You can display blogs'), + 'icon_class' => 'icon icon icon-chevron-right', 'tag' => 'content slider'); + } + + public function getConfigList() + { + if (Module::isInstalled('leoblog') && Module::isEnabled('leoblog')) { + include_once(_PS_MODULE_DIR_.'leoblog/leoblog.php'); + $module = new Leoblog(); +// $list = array(); + $controller = 'AdminLeoblogDashboard'; + $id_lang = Context::getContext()->language->id; + $params = array('token' => Tools::getAdminTokenLite($controller)); + $url = dirname($_SERVER['PHP_SELF']).'/'.Dispatcher::getInstance()->createUrl($controller, $id_lang, $params, false); + $selected_categories = array(); + if (Tools::getIsset('chk_cat')) { + $chk_cat = Tools::getValue('chk_cat'); + $arr_key = explode(',', $chk_cat); + + $randkey_cat = ''; + foreach ($arr_key as $val) { + $randkey_cat .= ($randkey_cat == '') ? "'".pSQL($val)."'" : ",'".pSQL($val)."'"; + } + $sql = 'SELECT * FROM `'._DB_PREFIX_.'leoblogcat`'; + $sql .= ' WHERE randkey IN ('.$randkey_cat.')'; + + $arr_cat = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); + + foreach ($arr_cat as $cat) { + $selected_categories[] = $cat['id_leoblogcat']; + } + } + + $data_category = ''; + $data_category = $module->getTreeForApPageBuilder($selected_categories); + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => '' + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '' + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
'.$this->l('Step 1: Blog Filter').'
', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => "
$data_category
", + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
', + 'form_group_class' => 'value_by_tags', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
'.$this->l('Step 2: Blog Order And Limit').'
', + ), + array( + 'type' => 'text', + 'label' => $this->l('Image Blog Width'), + 'name' => 'bleoblogs_width', + 'class' => 'fixed-width-xs', + 'desc' => $this->l('Define the width of images displayed in this block.'), + 'default' => 690, + ), + array( + 'type' => 'text', + 'label' => $this->l('Image Blog Height'), + 'name' => 'bleoblogs_height', + 'class' => 'fixed-width-xs', + 'desc' => $this->l('Define the height of images displayed in this block.'), + 'default' => 300, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show View All'), + 'name' => 'bleoblogs_show', + 'values' => array( + array( + 'id' => 'active_on', + 'value' => 1, + 'label' => $this->l('Enabled') + ), + array( + 'id' => 'active_off', + 'value' => 0, + 'label' => $this->l('Disabled') + ) + ), + 'default' => 1, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show title'), + 'name' => 'show_title', + 'values' => ApPageSetting::returnYesNo(), + 'default' => 1, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show description'), + 'name' => 'show_desc', + 'values' => ApPageSetting::returnYesNo(), + 'default' => 1, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show Image:'), + 'name' => 'bleoblogs_sima', + 'values' => array( + array( + 'id' => 'active_on', + 'value' => 1, + 'label' => $this->l('Enabled') + ), + array( + 'id' => 'active_off', + 'value' => 0, + 'label' => $this->l('Disabled') + ) + ), + 'default' => 1, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show Author:'), + 'name' => 'bleoblogs_saut', + 'values' => array( + array( + 'id' => 'active_on', + 'value' => 1, + 'label' => $this->l('Enabled') + ), + array( + 'id' => 'active_off', + 'value' => 0, + 'label' => $this->l('Disabled') + ) + ), + 'default' => 1, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show Category:'), + 'name' => 'bleoblogs_scat', + 'values' => array( + array( + 'id' => 'active_on', + 'value' => 1, + 'label' => $this->l('Enabled') + ), + array( + 'id' => 'active_off', + 'value' => 0, + 'label' => $this->l('Disabled') + ) + ), + 'default' => 1, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show Created Date:'), + 'name' => 'bleoblogs_scre', + 'values' => array( + array( + 'id' => 'active_on', + 'value' => 1, + 'label' => $this->l('Enabled') + ), + array( + 'id' => 'active_off', + 'value' => 0, + 'label' => $this->l('Disabled') + ) + ), + 'default' => 1, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show Counter:'), + 'name' => 'bleoblogs_scoun', + 'values' => array( + array( + 'id' => 'active_on', + 'value' => 1, + 'label' => $this->l('Enabled') + ), + array( + 'id' => 'active_off', + 'value' => 0, + 'label' => $this->l('Disabled') + ) + ), + 'default' => 1, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show Hits:'), + 'name' => 'bleoblogs_shits', + 'values' => array( + array( + 'id' => 'active_on', + 'value' => 1, + 'label' => $this->l('Enabled') + ), + array( + 'id' => 'active_off', + 'value' => 0, + 'label' => $this->l('Disabled') + ) + ), + 'default' => 1, + ), + array( + 'type' => 'select', + 'label' => $this->l('Order Way'), + 'class' => 'form-action', + 'name' => 'order_way', + 'options' => array( + 'query' => array( + array('id' => 'asc', 'name' => $this->l('Asc')), + array('id' => 'desc', 'name' => $this->l('Desc')), + array('id' => 'random', 'name' => $this->l('Random'))), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => 'desc' + ), + array( + 'type' => 'select', + 'label' => $this->l('Order By'), + 'name' => 'order_by', + 'options' => array( + 'query' => ApPageSetting::getOrderByBlog(), + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'order_type_sub order_type-asc order_type-desc', + 'default' => 'id_leoblog_blog' + ), + array( + 'type' => 'text', + 'label' => $this->l('Limit'), + 'name' => 'nb_blogs', + 'default' => '10', + 'desc' => $this->l('Define the number of blogs displayed in this block.'), + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
'.$this->l('Step 3: Carousel Setting').'
', + ), + array( + 'type' => 'select', + 'label' => $this->l('Carousel Type'), + 'class' => 'form-action', + 'name' => 'carousel_type', + 'options' => array( + 'query' => array( + array('id' => 'boostrap', 'name' => $this->l('Bootstrap')), + array('id' => 'owlcarousel', 'name' => $this->l('Owl Carousel')), + array('id' => 'slickcarousel', 'name' => $this->l('Slick Carousel')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => 'boostrap' + ), + //Owl Carousel begin + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
'.$this->l('Items per Row').'
', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'items', + 'label' => $this->l('Items'), + 'desc' => $this->l('Typing number of items. Default'), + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + 'default' => '5', + ), + array( + 'type' => 'text', + 'name' => 'itemsdesktop', + 'label' => $this->l('Items_Desktop'), + 'desc' => $this->l('Typing number of items ( with Screen < 1200 )'), + 'default' => '4', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemsdesktopsmall', + 'label' => $this->l('Items_Desktop_Small'), + 'desc' => $this->l('Typing number of items ( with Screen < 992 )'), + 'default' => '3', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemstablet', + 'label' => $this->l('Items_Tablet'), + 'desc' => $this->l('Typing number of items ( with Screen < 768 )'), + 'default' => '2', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemsmobile', + 'label' => $this->l('Items_Mobile'), + 'desc' => $this->l('Typing number of items ( with Screen < 576 )'), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemscustom', + 'label' => $this->l('Items_Custom'), + 'desc' => $this->l('(Advance User) Example: [[0, 2], [576, 3], [768, 4], [992, 5], [1200, 6]]. The format is [x,y] whereby x=browser width and y=number of slides displayed'), + 'default' => '', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itempercolumn', + 'label' => $this->l('Items per Column'), + 'desc' => $this->l('Number of item per one column. Same with number of line for one page'), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
'.$this->l('Effect').'
', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Autoplay'), + 'name' => 'autoplay', + 'is_bool' => true, + 'desc' => $this->l('Yes - scroll per page. No - scroll per item. This affect next/prev buttons and mouse/touch dragging.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Stop on Hover'), + 'name' => 'stoponhover', + 'is_bool' => true, + 'desc' => $this->l('Stop autoplay on mouse hover'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Responsive'), + 'name' => 'responsive', + 'is_bool' => true, + 'desc' => $this->l('You can use Owl Carousel on desktop-only websites too! Just change that to "false" to disable resposive capabilities'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Navigation'), + 'name' => 'navigation', + 'is_bool' => true, + 'desc' => $this->l('Display "next" and "prev" buttons.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Auto Height'), + 'name' => 'autoHeight', + 'is_bool' => true, + 'desc' => $this->l('Add height to owl-wrapper-outer so you can use diffrent heights on slides. Use it only for one item per page setting.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Mouse Drag'), + 'name' => 'mouseDrag', + 'is_bool' => true, + 'desc' => $this->l('On DeskTop - Turn off/on mouse events.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Touch Drag'), + 'name' => 'touchdrag', + 'is_bool' => true, + 'desc' => $this->l('On Mobile - Turn off/on touch events.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
'.$this->l('Lazy Load: This function is only work when have one item per column').'
', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Lazy Load'), + 'name' => 'lazyload', + 'values' => ApPageSetting::returnYesNo(), + 'desc' => $this->l('Delays loading of images. Images outside of viewport will not be loaded before user scrolls to them. Great for mobile devices to speed up page loadings'), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Lazy Follow'), + 'name' => 'lazyfollow', + 'is_bool' => true, + 'desc' => $this->l('When pagination used, it skips loading the images from pages that got skipped. It only loads the images that get displayed in viewport. If set to false, all images get loaded when pagination used. It is a sub setting of the lazy load function.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'select', + 'label' => $this->l('Lazy Effect'), + 'name' => 'lazyeffect', + 'options' => array( + 'query' => array( + array('id' => 'fade', 'name' => $this->l('fade')), + array('id' => 'false', 'name' => $this->l('No')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'desc' => $this->l('Default is fadeIn on 400ms speed. Use false to remove that effect.'), + 'default' => 'fade', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Pagination Enable'), + 'name' => 'pagination', + 'is_bool' => true, + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'desc' => $this->l('Show Pagination below owl-carousel.'), + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Pagination Numbers'), + 'name' => 'paginationnumbers', + 'is_bool' => true, + 'desc' => $this->l('Show numbers inside Pagination'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
'.$this->l('NEXT PAGE').'
', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Scroll per Page'), + 'name' => 'scrollPerPage', + 'is_bool' => true, + 'desc' => $this->l('Yes - scroll per Page. No - scroll per Item. This affect next/prev buttons and mouse/touch dragging.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'label' => $this->l('Scroll Page Speed'), + 'name' => 'paginationspeed', + 'desc' => $this->l('Time to next page. Ex 800 ( Milliseconds )'), + 'default' => '800', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'label' => $this->l('Scroll Item Speed'), + 'name' => 'slidespeed', + 'desc' => $this->l('Time to next item. Ex 200 (Milliseconds)'), + 'default' => '200', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + //Owl Carousel end + //boostrap carousel begin + array( + 'type' => 'text', + 'name' => 'nbitemsperpage', + 'label' => $this->l('Number of Items per Page'), + 'desc' => $this->l('How many product you want to display in a Page. Divisible by Item per Line (Desktop, Table, mobile)(default:12)'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + 'default' => '12', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
'.$this->l('Items per Row').'
', + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_Desktop ( >= 1200 )'), + 'name' => 'nbitemsperline_desktop', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + array('id' => '12', 'name' => $this->l('12 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 4'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_SmallDesktop ( >= 992 )'), + 'name' => 'nbitemsperline_smalldesktop', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + array('id' => '12', 'name' => $this->l('12 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 3'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_Tablet ( >= 768 )'), + 'name' => 'nbitemsperline_tablet', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + array('id' => '12', 'name' => $this->l('12 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 3'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_SmallDevices ( >= 576 )'), + 'name' => 'nbitemsperline_smalldevices', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 2'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_ExtraSmallDevices ( >= 480 )'), + 'name' => 'nbitemsperline_extrasmalldevices', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 1'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_Smartphone ( < 480 )'), + 'name' => 'nbitemsperline_smartphone', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 1'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'text', + 'name' => 'interval', + 'label' => $this->l('interval'), + 'desc' => $this->l('The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle.'), + 'default' => '5000', + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + //boostrap carousel end + //Slick carousel start + array( + 'type' => 'select', + 'label' => $this->l('Vertical'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'name' => 'slick_vertical', + 'options' => array( + 'query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => '0' + ), + array( + 'type' => 'select', + 'name' => 'slick_autoplay', + 'label' => $this->l('Auto play'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '1', + 'options' => array('query' => array( + array('id' => '1', 'name' => $this->l('Yes')), + array('id' => '0', 'name' => $this->l('No')), + ), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'name' => 'slick_pauseonhover', + 'label' => $this->l('Pause on Hover'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '1', + 'options' => array('query' => array( + array('id' => '1', 'name' => $this->l('Yes')), + array('id' => '0', 'name' => $this->l('No')), + ), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'name' => 'slick_loopinfinite', + 'label' => $this->l('Loop Infinite'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '0', + 'options' => array('query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'name' => 'slick_arrows', + 'label' => $this->l('Prev/Next Arrows'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '1', + 'options' => array('query' => array( + array('id' => '1', 'name' => $this->l('Yes')), + array('id' => '0', 'name' => $this->l('No')), + ), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'name' => 'slick_dot', + 'label' => $this->l('Show dot indicators'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '0', + 'options' => array('query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'name' => 'slick_centermode', + // 'class' => 'form-action', + 'label' => $this->l('Center mode'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '0', + 'options' => array('query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name') + ), + array( + 'type' => 'text', + 'name' => 'slick_centerpadding', + 'label' => $this->l('Center padding'), + 'desc' => $this->l('Only for center mode. Unit is px (pixel). Default: 60(px)'), + 'default' => '60', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + array( + 'type' => 'text', + 'name' => 'slick_row', + 'label' => $this->l('Num Row'), + 'desc' => $this->l('Show number row display. Ex 1 or 1,2,3,4 '), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + array( + 'type' => 'text', + 'name' => 'slick_slidestoshow', + 'label' => $this->l('Slides To Show'), + 'desc' => $this->l('Show number row display. Ex 1 or 1,2,3,4 '), + 'default' => '5', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + array( + 'type' => 'text', + 'name' => 'slick_slidestoscroll', + 'label' => $this->l('Slides To Scroll'), + 'desc' => $this->l('Show number row display. Ex 1 or 1,2,3,4 '), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + array( + 'type' => 'text', + 'name' => 'slick_items_custom', + 'label' => $this->l('Display for other screen'), + 'desc' => $this->l('(Advance User) Example: [[1200, 6],[992, 5],[768, 4], [576, 3],[480, 2]]. The format is [x,y] whereby x=browser width and y=number of slides displayed'), + 'default' => '[[1200, 6],[992, 5],[768, 4], [576, 3],[480, 2]]', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + + array( + 'type' => 'select', + 'name' => 'slick_custom_status', + // 'class' => 'form-action', + 'label' => $this->l('Enable custom js slick'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l('Only for developers and advanced users. Goto http://kenwheeler.github.io/slick/ for option'), + 'options' => array('query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name', + ), + 'default' => '0', + ), + array( + 'type' => 'textarea', + 'name' => 'slick_custom', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'label' => $this->l('Custom js Slick'), + 'values' => '', + 'autoload_rte' => false, + 'default' => '{ + dots: true, + infinite: false, + speed: 300, + slidesToShow: 4, + slidesToScroll: 4, + responsive: [ + { + breakpoint: 1024, + settings: { + slidesToShow: 3, + slidesToScroll: 3, + infinite: true, + dots: true + } + }, + { + breakpoint: 600, + settings: { + slidesToShow: 2, + slidesToScroll: 2 + } + }, + { + breakpoint: 480, + settings: { + slidesToShow: 1, + slidesToScroll: 1 + } + } + ] +}', + // 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + + //Slick carousel end + ); + } else { + $inputs = array( + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
'. + $this->l('"LeoBlog" Module must be installed and enabled before using.'). + '

You can take this module at leo-theme or apollo-theme

' + ) + ); + } + return $inputs; + } + + public function endRenderForm() + { + // KEEP OLD DATA + if (Tools::getIsset('nbitemsperline') && Tools::getValue('nbitemsperline')) { + $this->helper->tpl_vars['fields_value']['nbitemsperline_desktop'] = Tools::getValue('nbitemsperline'); + $this->helper->tpl_vars['fields_value']['nbitemsperline_smalldesktop'] = Tools::getValue('nbitemsperline'); + $this->helper->tpl_vars['fields_value']['nbitemsperline_tablet'] = Tools::getValue('nbitemsperline'); + } + + if (Tools::getIsset('nbitemsperlinetablet') && Tools::getValue('nbitemsperlinetablet')) { + $this->helper->tpl_vars['fields_value']['nbitemsperline_smalldevices'] = Tools::getValue('nbitemsperlinetablet'); + } + + if (Tools::getIsset('nbitemsperlinemobile') && Tools::getValue('nbitemsperlinemobile')) { + $this->helper->tpl_vars['fields_value']['nbitemsperline_extrasmalldevices'] = Tools::getValue('nbitemsperlinemobile'); + $this->helper->tpl_vars['fields_value']['nbitemsperline_smartphone'] = Tools::getValue('nbitemsperlinemobile'); + } + } + + public function prepareFontContent($assign, $module = null) + { + if (Module::isInstalled('leoblog') && Module::isEnabled('leoblog')) { + $id_shop = (int)Context::getContext()->shop->id; + if (isset($assign['formAtts']['carousel_type']) && $assign['formAtts']['carousel_type'] == 'owlcarousel') { + if (!Configuration::get('APPAGEBUILDER_LOAD_OWL')) { + $assign['formAtts']['lib_has_error'] = true; + $assign['formAtts']['lib_error'] = 'Can not show Blog. Please enable Owl Carousel library in Appagebuilder Configuration.'; + return $assign; + } + } + $assign['formAtts']['isEnabled'] = true; + $assign['formAtts']['leo_blog_helper'] = LeoBlogHelper::getInstance(); + include_once(_PS_MODULE_DIR_.'leoblog/leoblog.php'); + $module = new Leoblog(); + //get id of blog via link-url +// if (isset($assign['formAtts']['chk_cat'])) { +// $link_array = explode(',', $assign['formAtts']['chk_cat']); +// } +// else { +// $link_array = array(); +// } +// if ($link_array && !is_numeric($link_array['0'])) { +// $where = ''; +// foreach ($link_array as $val) { +// // validate module +// $where .= ($where == '') ? "'".$val."'" : ",'".$val."'"; +// } +// +// $where = ' WHERE link_rewrite IN (".$where.") AND id_lang = '.(int)Context::getContext()->language->id; +// $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('SELECT id_leoblogcat FROM `'._DB_PREFIX_.'leoblogcat_lang` '.$where); +// $where = ''; +// foreach ($result as $blog) { +// // validate module +// $where .= ($where == '') ? $blog['id_leoblogcat'] : ','.$blog['id_leoblogcat']; +// } +// $assign['formAtts']['chk_cat'] = $where; +// } + + // GET ID_BLOG VIA randkey - BEGIN + $arr_key = array(-1); // DEFAULT + if (isset($assign['formAtts']['chk_cat'])) { + $arr_key = explode(',', $assign['formAtts']['chk_cat']); + } + $randkey_cat = ''; + foreach ($arr_key as $val) { + $randkey_cat .= ($randkey_cat == '') ? "'".pSQL($val)."'" : ",'".pSQL($val)."'"; + } + + $where = ' WHERE randkey IN ('.$randkey_cat.')'; + $sql = 'SELECT cat.id_leoblogcat FROM `'._DB_PREFIX_.'leoblogcat` cat'; + $sql .= ' JOIN `'._DB_PREFIX_.'leoblogcat_shop` cat_s ON cat.id_leoblogcat = cat_s.id_leoblogcat AND id_shop = ' . (int)$id_shop; + $sql .= $where; + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); + $where = '-1'; + foreach ($result as $blog) { + // validate module + $where .= ($where == '') ? $blog['id_leoblogcat'] : ','.$blog['id_leoblogcat']; + } + $assign['formAtts']['chk_cat'] = $where; + // GET ID_BLOG VIA randkey - END + + + $config = LeoBlogConfig::getInstance(); + $config->setVar('listing_leading_img_width', $assign['formAtts']['bleoblogs_width']); + $config->setVar('listing_leading_img_height', $assign['formAtts']['bleoblogs_height']); + $assign['products'] = $module->getBlogsFont($assign['formAtts'], $module); + $assign['carouselName'] = 'carousel-'.ApPageSetting::getRandomNumber(); + if ($assign['formAtts']['carousel_type'] == 'boostrap') { + if (isset($assign['formAtts']['nbitemsperline']) && $assign['formAtts']['nbitemsperline']) { + $assign['formAtts']['nbitemsperline_desktop'] = $assign['formAtts']['nbitemsperline']; + $assign['formAtts']['nbitemsperline_smalldesktop'] = $assign['formAtts']['nbitemsperline']; + $assign['formAtts']['nbitemsperline_tablet'] = $assign['formAtts']['nbitemsperline']; + } + if (isset($assign['formAtts']['nbitemsperlinetablet']) && $assign['formAtts']['nbitemsperlinetablet']) { + $assign['formAtts']['nbitemsperline_smalldevices'] = $assign['formAtts']['nbitemsperlinetablet']; + } + if (isset($assign['formAtts']['nbitemsperlinemobile']) && $assign['formAtts']['nbitemsperlinemobile']) { + $assign['formAtts']['nbitemsperline_extrasmalldevices'] = $assign['formAtts']['nbitemsperlinemobile']; + $assign['formAtts']['nbitemsperline_smartphone'] = $assign['formAtts']['nbitemsperlinemobile']; + } + + $assign['formAtts']['nbitemsperline_desktop'] = isset($assign['formAtts']['nbitemsperline_desktop']) && $assign['formAtts']['nbitemsperline_desktop'] ? (int)$assign['formAtts']['nbitemsperline_desktop'] : 4; + $assign['formAtts']['nbitemsperline_smalldesktop'] = isset($assign['formAtts']['nbitemsperline_smalldesktop']) && $assign['formAtts']['nbitemsperline_smalldesktop'] ? (int)$assign['formAtts']['nbitemsperline_smalldesktop'] : 4; + $assign['formAtts']['nbitemsperline_tablet'] = isset($assign['formAtts']['nbitemsperline_tablet']) && $assign['formAtts']['nbitemsperline_tablet'] ? (int)$assign['formAtts']['nbitemsperline_tablet'] : 3; + $assign['formAtts']['nbitemsperline_smalldevices'] = isset($assign['formAtts']['nbitemsperline_smalldevices']) && $assign['formAtts']['nbitemsperline_smalldevices'] ? (int)$assign['formAtts']['nbitemsperline_smalldevices'] : 2; + $assign['formAtts']['nbitemsperline_extrasmalldevices'] = isset($assign['formAtts']['nbitemsperline_extrasmalldevices']) && $assign['formAtts']['nbitemsperline_extrasmalldevices'] ? (int)$assign['formAtts']['nbitemsperline_extrasmalldevices'] : 1; + $assign['formAtts']['nbitemsperline_smartphone'] = isset($assign['formAtts']['nbitemsperline_smartphone']) && $assign['formAtts']['nbitemsperline_smartphone'] ? (int)$assign['formAtts']['nbitemsperline_smartphone'] : 1; + + $assign['tabname'] = 'carousel-'.ApPageSetting::getRandomNumber(); + $assign['itemsperpage'] = (int)$assign['formAtts']['nbitemsperpage']; + $assign['nbItemsPerLine'] = (int)$assign['formAtts']['nbitemsperline_desktop']; + + $assign['scolumn'] = ''; + + if ($assign['formAtts']['nbitemsperline_desktop'] == '5') { + $assign['scolumn'] .= ' col-xl-2-4'; + } else { + $assign['scolumn'] .= ' col-xl-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_desktop'])); + } + + if ($assign['formAtts']['nbitemsperline_smalldesktop'] == '5') { + $assign['scolumn'] .= ' col-lg-2-4'; + } else { + $assign['scolumn'] .= ' col-lg-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_smalldesktop'])); + } + + if ($assign['formAtts']['nbitemsperline_tablet'] == '5') { + $assign['scolumn'] .= ' col-md-2-4'; + } else { + $assign['scolumn'] .= ' col-md-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_tablet'])); + } + + if ($assign['formAtts']['nbitemsperline_smalldevices'] == '5') { + $assign['scolumn'] .= ' col-sm-2-4'; + } else { + $assign['scolumn'] .= ' col-sm-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_smalldevices'])); + } + + if ($assign['formAtts']['nbitemsperline_extrasmalldevices'] == '5') { + $assign['scolumn'] .= ' col-xs-2-4'; + } else { + $assign['scolumn'] .= ' col-xs-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_extrasmalldevices'])); + } + + if ($assign['formAtts']['nbitemsperline_smartphone'] == '5') { + $assign['scolumn'] .= ' col-sp-2-4'; + } else { + $assign['scolumn'] .= ' col-sp-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_smartphone'])); + } + } + + //DONGND:: create data for owl carousel with item custom + if ($assign['formAtts']['carousel_type'] == 'owlcarousel') { + //DONGND:: build data for fake item loading + $assign['formAtts']['number_fake_item'] = $assign['formAtts']['items']; + $array_fake_item = array(); + $array_fake_item['m'] = $assign['formAtts']['itemsmobile']; + $array_fake_item['sm'] = $assign['formAtts']['itemstablet']; + $array_fake_item['md'] = $assign['formAtts']['itemsdesktopsmall']; + $array_fake_item['lg'] = $assign['formAtts']['itemsdesktop']; + $array_fake_item['xl'] = $assign['formAtts']['items']; + $assign['formAtts']['array_fake_item'] = $array_fake_item; + if (isset($assign['formAtts']['itemscustom']) && $assign['formAtts']['itemscustom'] != '') { + $array_item_custom = Tools::jsonDecode($assign['formAtts']['itemscustom']); + $array_item_custom_tmp = array(); + $array_number_item = array(); + foreach ($array_item_custom as $array_item_custom_val) { + $size_window = $array_item_custom_val[0]; + $number_item = $array_item_custom_val[1]; + if (0 <= $size_window && $size_window < 576) { + $array_item_custom_tmp['m'] = $number_item; + } else if (576 <= $size_window && $size_window < 768) { + $array_item_custom_tmp['sm'] = $number_item; + } else if (768 <= $size_window && $size_window < 992) { + $array_item_custom_tmp['md'] = $number_item; + } else if (992 <= $size_window && $size_window < 1200) { + $array_item_custom_tmp['lg'] = $number_item; + } else if ($size_window >= 1200) { + $array_item_custom_tmp['xl'] = $number_item; + } + $array_item_custom_tmp[$size_window] = $number_item; + $array_number_item[] = $number_item; + }; + $assign['formAtts']['array_fake_item'] = array_merge($array_fake_item, $array_item_custom_tmp); + + if (max($array_number_item) > $assign['formAtts']['items']) { + $assign['formAtts']['number_fake_item'] = max($array_number_item); + } + } + }; + + if ($assign['formAtts']['carousel_type'] == 'slickcarousel') { + if (isset($assign['formAtts']['slick_items_custom'])) { + $assign['formAtts']['slick_items_custom'] = str_replace($this->str_search, $this->str_relace, $assign['formAtts']['slick_items_custom']); + } + if (isset($assign['formAtts']['slick_custom'])) { + $str_relace = array('&', '\"', '\'', '', '', '', '[', ']'); + $assign['formAtts']['slick_custom'] = str_replace($this->str_search, $str_relace, $assign['formAtts']['slick_custom']); + } + if (isset($assign['formAtts']['slick_items_custom'])) { + $assign['formAtts']['slick_items_custom'] = Tools::jsonDecode($assign['formAtts']['slick_items_custom']); + } + + //DONGND:: build data for fake item loading + $assign['formAtts']['number_fake_item'] = $assign['formAtts']['slick_slidestoshow']*$assign['formAtts']['slick_row']; + + if (isset($assign['formAtts']['slick_items_custom']) && $assign['formAtts']['slick_items_custom'] != '') { + $array_item_custom = $assign['formAtts']['slick_items_custom']; + $array_item_custom_tmp = array(); + $array_number_item = array(); + foreach ($array_item_custom as $array_item_custom_val) { + $size_window = $array_item_custom_val[0]; + $number_item = $array_item_custom_val[1]; + if (0 <= $size_window && $size_window < 576) { + $array_item_custom_tmp['m'] = $number_item; + } else if (576 <= $size_window && $size_window < 768) { + $array_item_custom_tmp['sm'] = $number_item; + } else if (768 <= $size_window && $size_window < 992) { + $array_item_custom_tmp['md'] = $number_item; + } else if (992 <= $size_window && $size_window < 1200) { + $array_item_custom_tmp['lg'] = $number_item; + } else if ($size_window >= 1200) { + $array_item_custom_tmp['xl'] = $assign['formAtts']['slick_slidestoshow']; + } + $number_item = $number_item*$assign['formAtts']['slick_row']; + $array_item_custom_tmp[$size_window] = $number_item; + $array_number_item[] = $number_item; + }; + $assign['formAtts']['array_fake_item'] = $array_item_custom_tmp; + + if (max($array_number_item) > $assign['formAtts']['slick_slidestoshow']) { + $assign['formAtts']['number_fake_item'] = max($array_number_item); + } + } + } + } else { + // validate module + $assign['formAtts']['isEnabled'] = false; + $assign['formAtts']['lib_has_error'] = true; + $assign['formAtts']['lib_error'] = 'Can not show LeoBlog via Appagebuilder. Please enable LeoBlog module.'; + } + return $assign; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApButton.php b/modules/appagebuilder/classes/shortcodes/ApButton.php new file mode 100644 index 00000000..6e268773 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApButton.php @@ -0,0 +1,250 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApButton extends ApShortCodeBase +{ + public $name = 'ApButton'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Buttons'), + 'position' => 5, + 'desc' => $this->l('Custom color, size and create a link for button'), + 'icon_class' => 'icon-edit', + 'tag' => 'content control'); + } + + public function getConfigList() + { + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'form_group_class' => 'aprow_general', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'text', + 'name' => 'name', + 'label' => $this->l('Name'), + 'lang' => 'true', + 'form_group_class' => 'aprow_general', + 'default' => 'Button' + ), + array( + 'type' => 'select', + 'label' => $this->l('Use Outline Button'), + 'class' => 'form-action', + 'name' => 'use_outline_button', + 'options' => array( + 'query' => array( + array('id' => 'no', 'name' => $this->l('No')), + array('id' => 'yes', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => '0' + ), + array( + 'type' => 'select', + 'label' => $this->l('Button Type'), + 'name' => 'button_type', + 'options' => array('query' => $this->getDataButtonType(), + 'id' => 'value', + 'name' => 'text'), + 'default' => '1', + 'form_group_class' => 'use_outline_button_sub use_outline_button-no', + ), + array( + 'type' => 'select', + 'label' => $this->l('Button Type'), + 'name' => 'outline_button_type', + 'options' => array('query' => $this->getDataOutlineButtonType(), + 'id' => 'value', + 'name' => 'text'), + 'default' => '1', + 'form_group_class' => 'use_outline_button_sub use_outline_button-yes', + ), + array( + 'type' => 'select', + 'label' => $this->l('Button Size'), + 'name' => 'button_size', + 'options' => array('query' => $this->getDataSize(), + 'id' => 'value', + 'name' => 'text'), + 'default' => 'btn-lg', + 'desc' => $this->l('Select a button size') + ), + array( + 'type' => 'switch', + 'label' => $this->l('Is Block'), + 'name' => 'is_block', + 'desc' => $this->l('If is block, will display width is full 100%'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0' + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
' + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => '' + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => $this->l('You can add code in ').'here' + ), + array( + 'type' => 'text', + 'name' => 'url', + 'label' => $this->l('Url'), + 'desc' => $this->l('Exmaple: http://prestashop.com'), + 'lang' => 'true', + 'default' => '' + ), + array( + 'type' => 'switch', + 'label' => $this->l('Open new window'), + 'name' => 'is_blank', + 'desc' => $this->l('If is Yes, will open new tab with url when click'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0' + ), + ); + return $inputs; + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + + if ($assign['formAtts']['use_outline_button'] == 'yes') { + $assign['formAtts']['button_type'] = $assign['formAtts']['outline_button_type']; + } + return $assign; + } + + + + + private function getDataButtonType() + { + $data = array( + array( + 'value' => 'btn-primary', + 'text' => $this->l('Button Primary') + ), + array( + 'value' => 'btn-secondary', + 'text' => $this->l('Button Secondary') + ), + array( + 'value' => 'btn-success', + 'text' => $this->l('Button Success') + ), + array( + 'value' => 'btn-info', + 'text' => $this->l('Button Info') + ), + array( + 'value' => 'btn-warning', + 'text' => $this->l('Button Warning') + ), + array( + 'value' => 'btn-danger', + 'text' => $this->l('Button Danger') + ), + array( + 'value' => 'btn-link', + 'text' => $this->l('Button Link') + ) + ); + + return $data; + } + + private function getDataOutlineButtonType() + { + $data = array( + array( + 'value' => 'btn-outline-primary', + 'text' => $this->l('Button Outline Primary') + ), + array( + 'value' => 'btn-outline-secondary', + 'text' => $this->l('Button Outline Secondary') + ), + array( + 'value' => 'btn-outline-success', + 'text' => $this->l('Button Outline Success') + ), + array( + 'value' => 'btn-outline-info', + 'text' => $this->l('Button Outline Info') + ), + array( + 'value' => 'btn-outline-warning', + 'text' => $this->l('Button Outline Warning') + ), + array( + 'value' => 'btn-outline-danger', + 'text' => $this->l('Button Outline Danger') + ), + ); + + return $data; + } + + private function getDataSize() + { + $data = array( + array( + 'value' => 'btn-lg', + 'text' => $this->l('Size Large') + ), + array( + 'value' => 'btn-sm', + 'text' => $this->l('Size Small') + ), + ); + + return $data; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApCategoryImage.php b/modules/appagebuilder/classes/shortcodes/ApCategoryImage.php new file mode 100644 index 00000000..e2565ff3 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApCategoryImage.php @@ -0,0 +1,314 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApCategoryImage extends ApShortCodeBase +{ + public $name = 'ApCategoryImage'; + public $for_module = 'manage'; + public $module_name = 'appagebuilder'; + public $level = 4; + + public function getInfo() + { + return array('label' => $this->l('Images of categories'), + 'position' => 5, + 'desc' => $this->l('Choosing images for categories'), + 'icon_class' => 'icon-picture', + 'tag' => 'content'); + } + + public function getConfigList() + { + $root = Category::getRootCategory(); + $selected_cat = array(); + $selected_cates = ''; + $selected_images = ''; +// $image_list = $this->getImages(); + $image_list = array(); + if (Tools::getIsset('categorybox')) { + $category_box = Tools::getValue('categorybox'); + $selected_cat = explode(',', $category_box); + } + if (Tools::getIsset('category_img')) { + $selected_images = str_replace($this->str_search, $this->str_relace_html, Tools::getValue('category_img')); + } + if (Tools::getIsset('selected_cates')) { + $selected_cates = Tools::getValue('selected_cates'); + } + $tree = new HelperTreeCategories('categorybox', 'All Categories'); + // fix tree category with ps version 1.6.1 or newer + if (version_compare(_PS_VERSION_, '1.6.1', '>=')) { + $tree->setRootCategory($root->id)->setUseCheckBox(true)->setFullTree(true)->setSelectedCategories($selected_cat)->setInputName('categorybox'); + } else { + $tree->setRootCategory($root->id)->setUseCheckBox(true)->setSelectedCategories($selected_cat)->setInputName('categorybox'); + } + $orderby = array( + array( + 'order' => 'position', + 'name' => $this->l('Position') + ), + array( + 'order' => 'depth', + 'name' => $this->l('Depth') + ), + array( + 'order' => 'name', + 'name' => $this->l('Name') + ) + ); + $showicons = array( + array( + 'show' => '1', + 'name' => $this->l('Yes') + ), + array( + 'show' => '2', + 'name' => $this->l('Level 1 categories') + ), + array( + 'show' => '0', + 'name' => $this->l('No') + ) + ); + $path_image = apPageHelper::getImgThemeUrl('icon'); + Context::getContext()->smarty->assign('path_image', $path_image); + $href = Context::getContext()->link->getAdminLink('AdminApPageBuilderImages').'&ajax=1&action=manageimage&imgDir=icon'; + $tree_html = $tree->render(); + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => '' + ), + array( + 'type' => 'img_cat', + 'name' => 'img_cat', + 'imageList' => $image_list, + 'selected_images' => $selected_images, + 'selected_cates' => $selected_cates, + 'lang' => true, + 'tree' => $tree_html, + 'href_image' => $href, + 'path_image' => $path_image, + 'default' => '', + ), + array( + 'type' => 'text', + 'label' => $this->l('Depth'), + 'name' => 'cate_depth', + 'default' => '1', + ), + array( + 'type' => 'select', + 'label' => $this->l('Order By:'), + 'name' => 'orderby', + 'default' => 'position', + 'options' => array( + 'query' => $orderby, + 'id' => 'order', + 'name' => 'name' + ) + ), + array( + 'type' => 'select', + 'label' => $this->l('Show icons:'), + 'name' => 'showicons', + 'default' => '1', + 'options' => array( + 'query' => $showicons, + 'id' => 'show', + 'name' => 'name' + ) + ), + array( + 'type' => 'text', + 'label' => $this->l('Limit'), + 'name' => 'limit', + 'default' => '5', + ), + array( + 'type' => 'hidden', + 'name' => 'id_root', + 'default' => '2', + ), + array( + 'type' => 'hidden', + 'name' => 'id_lang', + 'default' => '1', + ) + ); + return $inputs; + } + + public function endRenderForm() + { + $this->helper->module = new $this->module_name(); + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + $form_atts = $assign['formAtts']; + $images = array(); + if (isset($form_atts['category_img']) && $form_atts['category_img']) { + $selected_images = str_replace($this->str_search, $this->str_relace_html, $form_atts['category_img']); + $images = Tools::jsonDecode($selected_images, true); + } + $sql_filter = ''; + $sql_sort = ''; + if (isset($form_atts['orderby']) && $form_atts['orderby']) { + if ($form_atts['orderby'] == 'depth') { + $sql_sort = ' ORDER BY c.`level_depth` ASC'; + } + if ($form_atts['orderby'] == 'position') { + $sql_sort = ' ORDER BY c.`level_depth` ASC, category_shop.`position` ASC'; + } + if ($form_atts['orderby'] == 'name') { + $sql_sort = ' ORDER BY c.`level_depth` ASC, cl.`name` ASC'; + } + } + $catids = (isset($form_atts['categorybox']) && $form_atts['categorybox']) ? ($form_atts['categorybox']) : ''; + $catids = explode(',', $catids); + $result = array(); + $this->level = (int)$form_atts['cate_depth']; + $limit = (isset($form_atts['limit']) && $form_atts['limit']) ? ((int)$form_atts['limit']) : 0; + $limit++; + foreach ($catids as $cate_id) { + if ($cate_id && Validate::isInt($cate_id)) { + $result_cate = $this->getNestedCategories($cate_id, 1, $images, $limit); + if ($result_cate) { + $result[] = $result_cate; + } + } + } + $assign['categories'] = $result; + $assign['random'] = 'categories-image-'.ApPageSetting::getRandomNumber(); + $assign['type'] = 'category_image'; + // validate module + unset($sql_filter); + unset($sql_sort); + return $assign; + } + + public function getImages() + { + $oimages = array(); + + $img_theme_dir = apPageHelper::getImgThemeDir(); + $icon_theme_dir = apPageHelper::getImgThemeDir('icon'); + $icon_theme_url = apPageHelper::getImgThemeUrl('icon'); + + if (!file_exists($img_theme_dir)) { + mkdir($img_theme_dir, 0755, true); + } + if (!file_exists($icon_theme_dir)) { + mkdir($icon_theme_dir, 0755, true); + } + + if (is_dir($img_theme_dir) && is_dir($icon_theme_dir)) { + $images = glob($icon_theme_dir.'*.*'); + $exts = array('jpg', 'gif', 'png'); + foreach ($images as $key => $image) { + $ext = Tools::substr($image, Tools::strlen($image) - 3, Tools::strlen($image)); + if (in_array(Tools::strtolower($ext), $exts)) { + $aimage = array(); + $aimage['path'] = $icon_theme_url.basename($image); + $aimage['name'] = basename($image); + $oimages[] = $aimage; + } + // validate module + unset($key); + } + } + return $oimages; + } + + public function getNestedCategories($parent, $level, $images, $limit) + { + $buff = array(); + if ($level <= $this->level) { + $lang = Context::getContext()->language->id; + $current = array(); + $child = array(); +// $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? 'https://' : 'http://'; + $image_path = apPageHelper::getImgThemeUrl('icon'); + $sql = ' + SELECT c.*, cl.* + FROM `'._DB_PREFIX_.'category` c'.Shop::addSqlAssociation('category', 'c').' + LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON c.`id_category` = cl.`id_category`'.Shop::addSqlRestrictionOnLang('cl').' + WHERE c.id_parent='.(int)$parent.' AND `id_lang` = '.(int)$lang.' + AND c.`active` = 1 + ORDER BY c.`level_depth` ASC, category_shop.`position` ASC'; + $result = Db::getInstance()->executeS($sql); + $current_category = Db::getInstance()->executeS('SELECT c.*, cl.* + FROM `'._DB_PREFIX_.'category` c'.Shop::addSqlAssociation('category', 'c').' + LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON c.`id_category` = cl.`id_category`'.Shop::addSqlRestrictionOnLang('cl').' + WHERE c.id_category='.(int)$parent.' AND `id_lang` = '.(int)$lang.' + AND c.`active` = 1'); + if ($current_category) { + if (array_key_exists($current_category[0]['id_category'], $images)) { + $current_category[0]['image'] = $image_path.$images[$current_category[0]['id_category']]; + } + if ($result) { + foreach ($result as &$row) { + if ($row && isset($row['id_category'])) { + $child = $this->getNestedCategories($row['id_category'], $level + 1, $images, $limit); + if ($child) { + foreach ($child as $item) { + if (array_key_exists($item['id_category'], $images)) { + $item['image'] = $image_path.$images[$item['id_category']]; + } + $current[$row['id_category']] = $item; + } + } + $buff[$row['id_parent']] = $current_category[0]; + if ($current) { + $buff[$row['id_parent']]['children'] = &$current; + } + } + } + } else { + // validate module + $buff[$parent] = $current_category[0]; + } + } + } + return $buff; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApColumn.php b/modules/appagebuilder/classes/shortcodes/ApColumn.php new file mode 100644 index 00000000..2b885312 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApColumn.php @@ -0,0 +1,279 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApColumn extends ApShortCodeBase +{ + public $name = 'ApColumn'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Column'), 'position' => 2, 'desc' => $this->l('A column can have one or more widget'), + 'tag' => 'content structure'); + } + + public function getAdditionConfig() + { + return array( + array( + 'type' => '', + 'name' => 'xl', + 'default' => '12' + ), + array( + 'type' => '', + 'name' => 'lg', + 'default' => '12' + ), + array( + 'type' => '', + 'name' => 'md', + 'default' => '12' + ), + array( + 'type' => '', + 'name' => 'sm', + 'default' => '12' + ), + array( + 'type' => '', + 'name' => 'xs', + 'default' => '12' + ), + array( + 'type' => '', + 'name' => 'sp', + 'default' => '12' + ) + ); + } + + public function getConfigList() + { + $input = array( + array( + 'type' => 'tabConfig', + 'name' => 'tabConfig', + 'values' => array( + 'aprow_general' => $this->l('General'), + 'aprow_style' => $this->l('Width'), + // 'aprow_animation' => $this->l('Animation'), + 'aprow_exceptions' => $this->l('Exceptions')) + ), + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'form_group_class' => 'aprow_general', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'form_group_class' => 'aprow_general', + 'default' => '' + ), + array( + 'type' => 'text', + 'name' => 'id', + 'label' => $this->l('ID'), + 'form_group_class' => 'aprow_general', + 'desc' => $this->l('Use for css and javascript'), + 'default' => '' + ), + array( + 'type' => 'ApColumnclass', + 'name' => 'class', + 'leolabel' => $this->l('CSS Class'), + 'values' => '', + 'default' => '', + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'column_width', + 'name' => 'width', + 'values' => '', + 'columnGrids' => ApPageSetting::getColumnGrid(), + 'form_group_class' => 'aprow_style', + ), + array( + 'type' => 'select', + 'label' => $this->l('Specific Controller'), + 'name' => 'specific_type', + 'class' => 'form-action', + 'options' => array( + 'query' => array( + array( + 'id' => 'all', + 'name' => $this->l('Show on all Page Controller'), + ), + array( + 'id' => 'index', + 'name' => $this->l('Show on only Index'), + ), + array( + 'id' => 'category', + 'name' => $this->l('Show on only Category'), + ), + array( + 'id' => 'product', + 'name' => $this->l('Show on only Product'), + ), + array( + 'id' => 'cms', + 'name' => $this->l('Show on only CMS'), + ) + ), + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'aprow_exceptions', + 'default' => 'all' + ), + array( + 'type' => 'reloadControler', + 'label' => $this->l('AJAX Reload Controller'), + 'name' => 'reloadControler', + 'default' => '', + 'form_group_class' => 'aprow_exceptions specific_type_sub specific_type-all', + 'hint' => 'If website have new a Controller, click to generate Controller again.', + ), + array( + 'type' => 'text', + 'label' => $this->l('Controller ID'), + 'name' => 'controller_id', + 'desc' => $this->l('Example: 1,2,3'), + 'default' => '', + 'form_group_class' => 'aprow_exceptions specific_type_sub specific_type-category specific_type-product specific_type-cms', + ), + array( + 'type' => 'apExceptions', + 'name' => 'controller_pages', + 'form_group_class' => 'aprow_exceptions specific_type_sub specific_type-all', + ), + ); + return $input; + } + + public function endRenderForm() + { + $this->helper->module = new $this->module_name(); + $this->helper->tpl_vars['exception_list'] = $this->displayModuleExceptionList(); + } + + public function displayModuleExceptionList() + { + $controllers = array(); + $controllers_modules = array(); + $controllers_modules['admin'] = array(); + $controllers_modules['front'] = array(); + + if (Tools::getValue('reloadControllerException')) { + $controllers = Dispatcher::getControllers(_PS_FRONT_CONTROLLER_DIR_); + $controllers_modules = array( + 'admin' => Dispatcher::getModuleControllers('admin'), + 'front' => Dispatcher::getModuleControllers('front'), + ); + + Configuration::updateValue('AP_CACHE_FRONT_CONTROLLER_EXCEPTION', apPageHelper::correctEnCodeData(Tools::jsonEncode($controllers))); + Configuration::updateValue('AP_CACHE_FRONT_MODULE_EXCEPTION', apPageHelper::correctEnCodeData(Tools::jsonEncode($controllers_modules['admin']))); + Configuration::updateValue('AP_CACHE_ADMIN_MODULE_EXCEPTION', apPageHelper::correctEnCodeData(Tools::jsonEncode($controllers_modules['front']))); + } else { + if (Configuration::get('AP_CACHE_FRONT_CONTROLLER_EXCEPTION') === false) { + # First Time : write to config + $controllers = Dispatcher::getControllers(_PS_FRONT_CONTROLLER_DIR_); + Configuration::updateValue('AP_CACHE_FRONT_CONTROLLER_EXCEPTION', apPageHelper::correctEnCodeData(Tools::jsonEncode($controllers))); + } else { + # Second Time : read from config + $controllers = Tools::jsonDecode(apPageHelper::correctDeCodeData(Configuration::get('AP_CACHE_FRONT_CONTROLLER_EXCEPTION')), true); + } + + if (Configuration::get('AP_CACHE_FRONT_MODULE_EXCEPTION') === false) { + # First Time : write to config + $controllers_modules['admin'] = Dispatcher::getModuleControllers('admin'); + Configuration::updateValue('AP_CACHE_FRONT_MODULE_EXCEPTION', apPageHelper::correctEnCodeData(Tools::jsonEncode($controllers_modules['admin']))); + } else { + # Second Time : read from config + $controllers_modules['admin'] = Tools::jsonDecode(apPageHelper::correctDeCodeData(Configuration::get('AP_CACHE_FRONT_MODULE_EXCEPTION')), true); + } + + if (Configuration::get('AP_CACHE_ADMIN_MODULE_EXCEPTION') === false) { + # First Time : write to config + $controllers_modules['front'] = Dispatcher::getModuleControllers('front'); + Configuration::updateValue('AP_CACHE_ADMIN_MODULE_EXCEPTION', apPageHelper::correctEnCodeData(Tools::jsonEncode($controllers_modules['front']))); + } else { + # Second Time : read from config + $controllers_modules['front'] = Tools::jsonDecode(apPageHelper::correctDeCodeData(Configuration::get('AP_CACHE_ADMIN_MODULE_EXCEPTION')), true); + } + } + + $controller = Tools::getValue('controller_pages'); + $arr_controllers = explode(',', $controller); + $arr_controllers = array_map('trim', $arr_controllers); + + $modules_controllers_type = array('front' => $this->l('Front modules controller'), 'admin' => $this->l('Admin modules controller')); + Context::getContext()->smarty->assign(array( + '_core_' => $this->l('________________________________________ CORE ________________________________________'), + 'controller' => $controller, + 'arr_controllers' => $arr_controllers, + 'controllers' => $controllers, + 'modules_controllers_type' => $modules_controllers_type, + 'controllers_modules' => $controllers_modules, + )); + $content = Context::getContext()->smarty->fetch(apPageHelper::getShortcodeTemplatePath('ApColumn.tpl')); + return $content; + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + if (!isset($assign['formAtts']['animation']) || $assign['formAtts']['animation'] == 'none') { + $assign['formAtts']['animation'] = 'none'; + $assign['formAtts']['animation_delay'] = ''; + } elseif ($assign['formAtts']['animation'] != 'none') { + // validate module + //DONGND:: add more config for animation + if ((int)$assign['formAtts']['animation_delay'] >= 0) { + $assign['formAtts']['animation_delay'] .= 's'; + } else { + $assign['formAtts']['animation_delay'] = '1s'; + } + if (isset($assign['formAtts']['animation_duration']) && (int)$assign['formAtts']['animation_duration'] >= 0) { + $assign['formAtts']['animation_duration'] .= 's'; + } else { + $assign['formAtts']['animation_duration'] = '1s'; + } + if (isset($assign['formAtts']['animation_iteration_count']) && (int)$assign['formAtts']['animation_iteration_count'] > 0) { + $assign['formAtts']['animation_iteration_count'] = (int)$assign['formAtts']['animation_iteration_count']; + } else { + $assign['formAtts']['animation_iteration_count'] = 1; + } + }; + $assign['formAtts']['class'] = str_replace('.', '-', $assign['formAtts']['class']); + return $assign; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApCountdown.php b/modules/appagebuilder/classes/shortcodes/ApCountdown.php new file mode 100644 index 00000000..d3f644cf --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApCountdown.php @@ -0,0 +1,200 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApCountdown extends ApShortCodeBase +{ + public $name = 'ApCountdown'; + public $for_module = 'manage'; + + public function getInfo() + { + return array( + 'label' => $this->l('Countdown'), + 'position' => 3, + 'desc' => $this->l('Show a __________________'), + 'icon_class' => 'icon-picture', 'tag' => 'content slider' + ); + } + + public function getConfigList() + { + $html_content = " + + + + + + + "; + + $input = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => 'container' + ), + array( + 'type' => 'text', + 'label' => $this->l('Time From'), + 'name' => 'time_from', + 'class' => 'datepicker', + 'default' => '' + ), + array( + 'type' => 'text', + 'label' => $this->l('Time To'), + 'name' => 'time_to', + 'default' => '', + 'class' => 'datepicker', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Open new tab'), + 'desc' => $this->l('Open new tab when click to link in slider'), + 'name' => 'new_tab', + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + ), + array( + 'type' => 'text', + 'name' => 'link_label', + 'label' => $this->l('Link Label'), + 'lang' => 'true', + 'default' => '' + ), + array( + 'type' => 'text', + 'name' => 'link', + 'label' => $this->l('Link'), + 'lang' => 'true', + 'default' => '', + 'class' => 'item-add-slide ignore-lang', + 'form_group_class' => 'apfullslider-row link-slide', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => $html_content, + ), + array( + 'type' => 'textarea', + 'label' => $this->l('Widget Description'), + 'name' => 'description', + 'cols' => 40, + 'rows' => 10, + 'value' => true, + 'lang' => true, + 'default' => '', + 'class' => 'item-add-slide ignore-lang', + 'form_group_class' => 'apfullslider-row description-slide', + ), + ); + return $input; + } + + public function getListGroup($list) + { + + $result = array(); + foreach ($list as $item) { + $status = ' ('.($item['active'] ? $this->l('Active') : $this->l('Deactive')).')'; + $result[] = array('id' => $item['id_leoslideshow_groups'], 'name' => $item['title'].$status); + } + return $result; + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + + $productCdown = Configuration::get('APPAGEBUILDER_LOAD_COUNT'); + if (!$productCdown) { + $assign['formAtts']['lib_has_error'] = true; + $assign['formAtts']['lib_error'] = 'Can not show Countdown Widget via Appagebuilder. Please enable AJAX Show Count Down Product.'; + return $assign; + } + + $from = strtotime($assign['formAtts']['time_from']); + $now = time(); + $end = strtotime($assign['formAtts']['time_to']); + + if (($from <= $now) && ($now < $end)) { + $start = true; + } else { + $start = false; + } + + if ($start) { + # RUNNING + $assign['formAtts']['time_to'] = str_replace('-', '/', $assign['formAtts']['time_to']); + $assign['formAtts']['active'] = 1; + } else { + $assign['formAtts']['active'] = 0; + } + + return $assign; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApFacebook.php b/modules/appagebuilder/classes/shortcodes/ApFacebook.php new file mode 100644 index 00000000..dc7b2e9b --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApFacebook.php @@ -0,0 +1,126 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApFacebook extends ApShortCodeBase +{ + public $name = 'ApFacebook'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Facebook'), + 'position' => 5, + 'desc' => $this->l('You can config Facebook Like box'), + 'icon_class' => 'icon-facebook-sign', + 'tag' => 'social'); + } + + public function getConfigList() + { + $soption = ApPageSetting::returnYesNo(); + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'form_group_class' => 'aprow_general', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'text', + 'label' => $this->l('Page URL'), + 'name' => 'page_url', + 'class' => 'ap_facebook', + 'default' => 'https://www.facebook.com/prestashop', + ), +// array( +// 'type' => 'switch', +// 'label' => $this->l('Is Border'), +// 'name' => 'border', +// 'values' => $soption, +// 'default' => '1', +// ), + array( + 'type' => 'select', + 'label' => $this->l('Color'), + 'name' => 'target', + 'options' => array('query' => array( + array('id' => 'dark', 'name' => $this->l('Dark')), + array('id' => 'light', 'name' => $this->l('Light')), + ), + 'id' => 'id', + 'name' => 'name'), + 'default' => '_self', + ), + array( + 'type' => 'text', + 'label' => $this->l('Width'), + 'name' => 'width', + 'default' => '', + ), + array( + 'type' => 'text', + 'label' => $this->l('Height'), + 'name' => 'height', + 'default' => '', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show Stream'), + 'name' => 'show_stream', + 'values' => $soption, + 'default' => '0', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show Faces'), + 'name' => 'show_faces', + 'values' => $soption, + 'default' => '1', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show Header'), + 'name' => 'show_header', + 'values' => $soption, + 'default' => '0', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show Border'), + 'name' => 'show_border', + 'values' => $soption, + 'default' => '0', + ) + ); + return $inputs; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApFontAwesome.php b/modules/appagebuilder/classes/shortcodes/ApFontAwesome.php new file mode 100644 index 00000000..34cc7f14 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApFontAwesome.php @@ -0,0 +1,173 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApFontAwesome extends ApShortCodeBase +{ + public $name = 'ApFontAwesome'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Font Awesome'), + 'position' => 5, + 'desc' => $this->l('Add a font Awesome'), + 'icon_class' => 'icon icon-font', + 'tag' => 'content control'); + } + + public function getConfigList() + { + $rotate = array( + array( + 'value' => 'normal', + 'text' => $this->l('Normal') + ), + array( + 'value' => 'icon-rotate-90', + 'text' => $this->l('Rotate Left') + ), + array( + 'value' => 'icon-rotate-180', + 'text' => $this->l('Rotate Inverser') + ), + array( + 'value' => 'icon-rotate-270', + 'text' => $this->l('Rotate Right') + ), + array( + 'value' => 'icon-flip-horizontal', + 'text' => $this->l('Flip Horizontal') + ), + array( + 'value' => 'icon-flip-vertical', + 'text' => $this->l('Flip Vertical') + ), + ); + $sizes = array( + array( + 'value' => 'size-default', + 'text' => $this->l('Size Default') + ), + array( + 'value' => 'icon-large', + 'text' => $this->l('Size Large') + ), + array( + 'value' => 'icon-2x', + 'text' => $this->l('Size 2x') + ), + array( + 'value' => 'icon-3x', + 'text' => $this->l('Size 3x') + ), + array( + 'value' => 'icon-4x', + 'text' => $this->l('Size 4x') + ) + ); + $default_font = Tools::getIsset('font_name') ? Tools::getValue('font_name') : 'icon-font'; + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'form_group_class' => 'aprow_general', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
'.$this->renderListFont($default_font).'
' + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
' + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Rotate'), + 'name' => 'font_type', + 'options' => array('query' => $rotate, + 'id' => 'value', + 'name' => 'text'), + 'default' => '', + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Size'), + 'name' => 'font_size', + 'options' => array('query' => $sizes, + 'id' => 'value', + 'name' => 'text'), + 'default' => 'size-default', + ), + array( + 'type' => 'select', + 'label' => $this->l('Is Spin'), + 'name' => 'is_spin', + 'options' => array('query' => array( + array('value' => '', 'text' => $this->l('No spin')), + array('value' => 'icon-spin', 'text' => $this->l('Spin')), + ), + 'id' => 'value', + 'name' => 'text'), + 'default' => 'btn-lg', + ), + ); + return $inputs; + } + + public function renderListFont($default = 'icon-font') + { + $list = ApPageSetting::listFontAwesome(); + $result = ''; + foreach ($list as $item) { + $cls = ''; + if ($default === $item['value']) { + $cls = 'selected'; + } + $result .= '
  • '; + } + return "
      $result
    "; + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + $assign['formAtts']['font_name'] = str_replace('icon', 'fa', $assign['formAtts']['font_name']); + + return $assign; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApFullSlider.php b/modules/appagebuilder/classes/shortcodes/ApFullSlider.php new file mode 100644 index 00000000..9812685b --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApFullSlider.php @@ -0,0 +1,258 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApFullSlider extends ApShortCodeBase +{ + public $name = 'ApFullSlider'; + + public function getInfo() + { + return array('label' => $this->l('Full Slider'), 'position' => 6, + 'desc' => $this->l('You can create Inner slideshow'), 'icon_class' => 'icon icon-chevron-right', + 'tag' => 'content slider'); + } + + public function getConfigList() + { + $href = Context::getContext()->link->getAdminLink('AdminApPageBuilderImages').'&ajax=1&action=manageimage&imgDir=images'; + $ad = __PS_BASE_URI__.basename(_PS_ADMIN_DIR_); + $iso_tiny_mce = Context::getContext()->language->iso_code; + $iso_tiny_mce = (file_exists(_PS_JS_DIR_.'tiny_mce/langs/'.$iso_tiny_mce.'.js') ? $iso_tiny_mce : 'en'); + $list_slider = '
    '; + $list_slider_button = '
    +
    +
    + + + +
    +
    + +
    +
    '; + $input = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => 'container' + ), + array( + 'type' => 'text', + 'label' => $this->l('Width slider'), + 'desc' => $this->l('Example: 100%, 1170px'), + 'name' => 'width', + 'default' => '100%' + ), + array( + 'type' => 'text', + 'label' => $this->l('Height slider'), + 'name' => 'height', + 'default' => '400px', + 'desc' => $this->l('Example: 100%, 400px'), + ), + array( + 'type' => 'text', + 'label' => $this->l('Interval'), + 'name' => 'interval', + 'default' => 2000, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Display title in slider'), + 'name' => 'display_title', + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Display indicators in slider'), + 'name' => 'display_indicators', + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Open new tab'), + 'desc' => $this->l('Open new tab when click to link in slider'), + 'name' => 'is_open', + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Next step: Add content for sliders').'
    ' + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => $list_slider + ), + array( + 'label' => $this->l('Image'), + 'type' => 'selectImg', + 'href' => $href, + 'name' => 'temp_image', + 'lang' => true, + 'class' => 'item-add-slide ignore-lang', + 'form_group_class' => 'apfullslider-row select-img', + ), + array( + 'type' => 'text', + 'name' => 'temp_title', + 'label' => $this->l('Title'), + 'lang' => 'true', + 'default' => '', + 'class' => 'item-add-slide ignore-lang', + 'form_group_class' => 'apfullslider-row title-slide', + ), + array( + 'type' => 'text', + 'name' => 'temp_link', + 'label' => $this->l('Link'), + 'lang' => 'true', + 'default' => '', + 'class' => 'item-add-slide ignore-lang', + 'form_group_class' => 'apfullslider-row link-slide', + ), + array( + 'type' => 'textarea', + 'label' => $this->l('Description'), + 'name' => 'temp_descript', + 'cols' => 40, + 'rows' => 10, + 'value' => true, + 'lang' => true, + 'default' => '', + 'class' => 'item-add-slide ignore-lang', + 'form_group_class' => 'apfullslider-row description-slide', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => $list_slider_button + ), + array( + 'type' => 'hidden', + 'name' => 'total_slider', + 'default' => '' + ), + ); + return $input; + } + + public function endRenderForm() + { + $this->helper->module = new $this->module_name(); + } + + public function addConfigList($values) + { + // Get value with keys special + $config_val = array(); + $total = isset($values['total_slider']) ? $values['total_slider'] : ''; + $arr = explode('|', $total); + $inputs = array('tit', 'img', 'link', 'descript'); + $languages = Language::getLanguages(false); + foreach ($arr as $i) { + foreach ($inputs as $config) { + foreach ($languages as $lang) { + $config_val[$config][$i][$lang['id_lang']] = str_replace($this->str_search, $this->str_relace_html_admin, Tools::getValue($config.'_'.$i.'_'.$lang['id_lang'], '')); + // print_r($config_val); + // echo '===='; + } + } + } + + Context::getContext()->smarty->assign(array( + 'lang' => $lang = new Language((int)Configuration::get('PS_LANG_DEFAULT')), + 'default_lang' => $lang->id, + 'arr' => $arr, + 'languages' => $languages, + 'config_val' => $config_val, + 'path' => $this->theme_img_module, + )); + $list_slider = Context::getContext()->smarty->fetch(apPageHelper::getShortcodeTemplatePath('ApFullSlider.tpl')); + $input = array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => $list_slider + ); + $this->config_list[] = $input; + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + $total_slider = isset($assign['formAtts']['total_slider']) ? $assign['formAtts']['total_slider'] : ''; + $list = explode('|', $total_slider); + $sliders = array(); + $lang = Language::getLanguage(Context::getContext()->language->id); + $lang_default = $lang['id_lang']; + foreach ($list as $item) { + if ($item) { + $temp = $item.'_'.$lang_default; + $slider = array(); + $slider['id'] = $item; + $slider['title'] = isset($assign['formAtts']['tit_'.$temp]) ? $assign['formAtts']['tit_'.$temp] : ''; + $slider['link'] = isset($assign['formAtts']['link_'.$temp]) ? $assign['formAtts']['link_'.$temp] : ''; + if (isset($assign['formAtts']['img_'.$temp]) && $assign['formAtts']['img_'.$temp]) { + // validate module + $slider['img'] = $this->theme_img_module.$assign['formAtts']['img_'.$temp]; + } else { + // validate module + $slider['img'] = ''; + } + + $desc = isset($assign['formAtts']['descript_'.$temp]) ? $assign['formAtts']['descript_'.$temp] : ''; + $slider['descript'] = str_replace($this->str_search, $this->str_relace_html, $desc); + //$slider['descript'] = $assign['formAtts']['descript_'.$temp]; + $sliders[] = $slider; + } + } + $assign['formAtts']['is_open'] = isset($assign['formAtts']['is_open']) ? $assign['formAtts']['is_open'] : 0; + $assign['formAtts']['slides'] = $sliders; + return $assign; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApGenCode.php b/modules/appagebuilder/classes/shortcodes/ApGenCode.php new file mode 100644 index 00000000..dc995899 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApGenCode.php @@ -0,0 +1,115 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApGenCode extends ApShortCodeBase +{ + public $name = 'ApGenCode'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Generate Code'), + 'position' => 8, + 'desc' => $this->l('Generate Code for tpl file. This function for web developer'), + 'icon_class' => 'icon-edit', + 'tag' => 'content'); + } + + public function getConfigList() + { + $inputs = array( + array( + 'type' => 'hidden', + 'value' => 'abcd', + 'name' => 'id_gencode', + 'default' => uniqid('id_gencode_').'_'.time(), + ), + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'lang' => 'true', + 'default' => '', + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'textarea', + 'name' => 'content_html', + 'class' => 'ap_html_raw raw-'.time(), + 'rows' => '10', + 'label' => $this->l('Code'), + 'values' => '', + 'default' => '', + 'desc' => $this->l('Typing code for file tpl.'), + ), + ); + return $inputs; + } + + public function prepareFontContent($assign, $module = null) + { + $this->generateFile($assign, $module); + + $file_name = $assign['formAtts']['id_gencode'].'.tpl'; + $profile_data = $module->getProfileData(); + $profile_folder = $profile_data['profile_key']; + $file_url = apPageHelper::getConfigDir('theme_profiles').$profile_folder.'/'.$file_name; + // check file tồn tại + if (file_exists($file_url)) { + $assign['formAtts']['tpl_file'] = $file_url; + } else { + $title = $assign['formAtts']['title']; + $assign['formAtts']['error_file'] = '1'; + $assign['formAtts']['error_message'] = "ERROR!!! Generate Code + '$title'. Physical file does not exist "._THEME_NAME_.'/'.$profile_folder.'/'.$file_name; + } + return $assign; + } + + /** + * Create code file in profile folder + */ + public function generateFile($assign, $module = null) + { + $folder_profiles = apPageHelper::getConfigDir('theme_profiles'); + if (!is_dir($folder_profiles)) { + mkdir($folder_profiles, 0755, true); + } + + $file = $assign['formAtts']['id_gencode'].'.tpl'; + $profile_data = $module->getProfileData(); + $folder = $folder_profiles.$profile_data['profile_key']; + $value = isset($assign['formAtts']['content_html']) ? $assign['formAtts']['content_html'] : ''; + + if (!is_dir($folder)) { + mkdir($folder, 0755, true); + } + + ApPageSetting::writeFile($folder, $file, $value); + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApGmap.php b/modules/appagebuilder/classes/shortcodes/ApGmap.php new file mode 100644 index 00000000..3565af73 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApGmap.php @@ -0,0 +1,289 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApGmap extends ApShortCodeBase +{ + public $name = 'ApGmap'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Google Map'), + 'position' => 5, + 'desc' => $this->l('Create a Google Map'), + 'icon_class' => 'icon-map-marker', + 'tag' => 'content'); + } + + public function getConfigList() + { + $iselect = Tools::getValue('display_store'); + + if ($iselect === false) { + $script_update_select = ''; + } elseif ($iselect == 1) { + $script_update_select = ''; + } + // Get all store of shop + $base_model = new ApPageBuilderModel(); + $data_list = $base_model->getAllStoreByShop(); + // Options for switch elements + $zoom_option = array(); + for ($i = 1; $i <= 20; $i++) { + $zoom_option[] = array('id' => $i, 'value' => $i); + } + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'form_group_class' => 'aprow_general', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'text', + 'label' => $this->l('Google Key'), + 'name' => 'gkey', + 'desc' => $this->l('Example: AIzaSyCWJmaoDNR_l3GVkP6uRnMzsGG5iuuU_AM'), + 'default' => '', + ), + array( + 'type' => 'select', + 'label' => $this->l('Zoom'), + 'name' => 'zoom', + 'default' => '11', + 'options' => array( + 'query' => $zoom_option, + 'id' => 'id', + 'name' => 'value' + ) + ), + array( + 'type' => 'text', + 'label' => $this->l('Width'), + 'name' => 'width', + 'desc' => $this->l('Example: 100%, 100px'), + 'default' => '100%', + ), + array( + 'type' => 'text', + 'label' => $this->l('Height'), + 'name' => 'height', + 'desc' => $this->l('Example: 100%, 100px'), + 'default' => '300px', + ), + array( + 'type' => 'checkbox', + 'name' => 'display', + 'label' => $this->l('Select display store on map'), + 'class' => 'checkbox-group', +// 'desc' => $this->l('Uncheck is display all stores'), + 'values' => array( + 'query' => array( + array( + 'id' => 'store', + 'name' => $this->l('Select store'), + 'val' => '1' + ) + ), + 'id' => 'id', + 'name' => 'name' + ) + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Uncheck to Display all stores').'
    '.$script_update_select, + ), + array( + 'type' => 'select', + 'label' => $this->l('List stores'), + 'desc' => $this->l('Can select multi store'), + 'name' => 'store[]', + 'multiple' => true, + 'options' => array( + 'query' => $data_list, + 'id' => 'id_store', + 'name' => 'name' + ), + 'form_group_class' => 'aprow_exceptions', + 'default' => 'all', + 'form_group_class' => 'display_store', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show Store Menu'), + 'name' => 'is_display_list', + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0' + ), + array( + 'type' => 'switch', + 'label' => $this->l('Enable Gmap at Our_Stores page'), + 'name' => 'stores', + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0' + ), + array( + 'type' => 'switch', + 'label' => $this->l('Enable Gmap at Sitemap page'), + 'name' => 'sitemap', + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0' + ) + ); + return $inputs; + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + // Get all store of shop + $base_model = new ApPageBuilderModel(); + $data_list = $base_model->getAllStoreByShop(); + $form_atts = $assign['formAtts']; + $not_all = (isset($form_atts['display_store']) && $form_atts['display_store']); + $store_ids = explode(',', (isset($form_atts['store']) && $form_atts['store']) ? $form_atts['store'] : ''); + $assign['hasListStore'] = (isset($form_atts['is_display_list']) && $form_atts['is_display_list']) ? 'is_display_list' : ''; + $markers = array(); + if ($not_all) { + foreach ($store_ids as $id) { + foreach ($data_list as $store) { + if ($id == $store['id_store']) { + $markers[] = $store; + break; + } + } + } + } else { + $markers = $data_list; + } + foreach ($markers as &$marker) { + $address = $this->processStoreAddress($marker); + $marker['other'] = $this->renderStoreWorkingHours($marker); + $marker['address'] = $address; + $marker['has_store_picture'] = file_exists(_PS_STORE_IMG_DIR_.(int)$marker['id_store'].'.jpg'); + } + + $assign['marker_center'] = Tools::jsonEncode($this->getMarkerCenter($markers)); + $assign['marker_list'] = Tools::jsonEncode($markers); + + $assign['apGMap'] = Tools::jsonEncode(array( + 'translation_5' => $this->l('Click to to larger Map'), + 'logo_store' => Configuration::get('PS_STORES_ICON'), + 'img_store_dir' => _THEME_STORE_DIR_, + 'img_ps_dir' => _PS_IMG_, + )); + + return $assign; + } + + /** + * Get formatted string address + */ + protected function processStoreAddress($store) + { + $ignore_field = array( + 'firstname', + 'lastname' + ); + $out_datas = array(); + $address_datas = AddressFormat::getOrderedAddressFields($store['id_country'], false, true); + $state = (isset($store['id_state'])) ? new State($store['id_state']) : null; + foreach ($address_datas as $data_line) { + $data_fields = explode(' ', $data_line); + $addr_out = array(); + $data_fields_mod = false; + foreach ($data_fields as $field_item) { + $field_item = trim($field_item); + if (!in_array($field_item, $ignore_field) && !empty($store[$field_item])) { + $addr_out[] = ($field_item == 'city' && $state && isset($state->iso_code) && Tools::strlen($state->iso_code)) ? + $store[$field_item].', '.$state->iso_code : $store[$field_item]; + $data_fields_mod = true; + } + } + if ($data_fields_mod) { + $out_datas[] = implode(' ', $addr_out); + } + } + $out = implode('
    ', $out_datas); + return $out; + } + + public function renderStoreWorkingHours($store) + { + $days = array(); + $days[1] = 'Monday'; + $days[2] = 'Tuesday'; + $days[3] = 'Wednesday'; + $days[4] = 'Thursday'; + $days[5] = 'Friday'; + $days[6] = 'Saturday'; + $days[7] = 'Sunday'; + + $hours_temp = $store['hours']; + $hours_temp = Tools::jsonDecode($hours_temp); + $hours = array(); + //DONGND:: fix when stores do not have the data of open time + if (count($hours_temp) > 0) { + foreach ($hours_temp as $h) { + $hours[] = implode(' | ', $h); + } + } + + if (!empty($hours)) { + $result = ''; + for ($i = 1; $i < 8; $i++) { + if (isset($hours[(int)$i - 1])) { + Context::getContext()->smarty->assign(array( + 'days' => $days, + 'hours' => $hours, + 'i' => $i, + )); + + $file_name = _PS_MODULE_DIR_.'appagebuilder/views/templates/front/shortcodes/ApGmap.tpl'; + $result .= Context::getContext()->smarty->fetch($file_name); + } + } + return $result; + } + return false; + } + + private function getMarkerCenter($markers) + { + //'default lat/long = 21.010904,105.787736 is location of LeoTheme + $lat = 21.010904; + $long = 105.787736; + return (is_array($markers) && count($markers) > 0) ? $markers[0] : array('latitude' => $lat, 'longitude' => $long); + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApHtml.php b/modules/appagebuilder/classes/shortcodes/ApHtml.php new file mode 100644 index 00000000..61b4e5c2 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApHtml.php @@ -0,0 +1,97 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApHtml extends ApShortCodeBase +{ + public $name = 'ApHtml'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Html'), 'position' => 3, 'desc' => $this->l('You can put html'), + 'icon_class' => 'icon-html5', 'tag' => 'content structure'); + } + + public function getConfigList() + { + $accordion_type = array( + array( + 'value' => 'full', + 'text' => $this->l('Always Full') + ), + array( + 'value' => 'accordion', + 'text' => $this->l('Always Accordion') + ), + array( + 'value' => 'accordion_small_screen', + 'text' => $this->l('Accordion at small screen') + ), + ); + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'lang' => 'true', + 'default' => '', + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'autoload_rte' => false, + 'values' => '', + 'class' => 'sub_title', + 'default' => '', + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => '' + ), + array( + 'type' => 'select', + 'label' => $this->l('Accordion Type'), + 'name' => 'accordion_type', + 'options' => array( + 'query' => $accordion_type, + 'id' => 'value', + 'name' => 'text' ), + 'default' => 'full', + 'hint' => $this->l('Select a Accordion Type'), + ), + array( + 'type' => 'textarea', + 'name' => 'content_html', + 'class' => 'ap_html', + 'rows' => '50', + 'lang' => true, + 'label' => $this->l('Html'), + 'values' => '', + 'autoload_rte' => true, + 'default' => "
    \n
    " + ), + ); + return $inputs; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApImage.php b/modules/appagebuilder/classes/shortcodes/ApImage.php new file mode 100644 index 00000000..7daf8bc9 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApImage.php @@ -0,0 +1,180 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApImage extends ApShortCodeBase +{ + public $name = 'ApImage'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Image'), + 'position' => 5, + 'desc' => $this->l('Single Image'), + 'icon_class' => 'icon-image', + 'tag' => 'content'); + } + + public function getConfigList() + { + Context::getContext()->smarty->assign('path_image', apPageHelper::getImgThemeUrl()); + $href = Context::getContext()->link->getAdminLink('AdminApPageBuilderImages').'&ajax=1&action=manageimage&imgDir=images'; + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'select', + 'label' => $this->l('Animations'), + 'name' => 'animation', + 'class' => 'animation-select', + 'options' => array( + 'optiongroup' => array( + 'label' => 'name', + 'query' => ApPageSetting::getAnimations(), + ), + 'options' => array( + 'id' => 'id', + 'name' => 'name', + 'query' => 'query', + ), + ), + 'form_group_class' => 'apimage_animation', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    Prestashop.com
    ', + 'form_group_class' => 'apimage_animation animate_sub', + ), + array( + 'type' => 'text', + 'label' => $this->l('Delay'), + 'name' => 'animation_delay', + 'default' => '0.5', + 'suffix' => 's', + 'class' => 'fixed-width-xs', + 'form_group_class' => 'apimage_animation animate_sub', + ), + array( + 'label' => $this->l('Image'), + 'type' => 'selectImg', + 'href' => $href, + 'name' => 'image', + 'lang' => true, + 'show_image' => true, + ), + array( + 'type' => 'text', + 'name' => 'alt', + 'label' => $this->l('Alt'), + 'default' => '' + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => '' + ), + array( + 'type' => 'text', + 'name' => 'url', + 'label' => $this->l('Link to'), + 'lang' => true, + 'desc' => 'Example: http://prestashop.com', + 'default' => '' + ), + array( + 'type' => 'switch', + 'label' => $this->l('Open new tab'), + 'name' => 'is_open', + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + ), + array( + 'type' => 'text', + 'name' => 'width', + 'label' => $this->l('Image size width'), + 'desc' => $this->l('Example: auto, 100%, 100px'), + 'default' => '100%' + ), + array( + 'type' => 'text', + 'name' => 'height', + 'label' => $this->l('Image size height'), + 'desc' => $this->l('Example: auto, 100%, 100px'), + 'default' => 'auto' + ), + array( + 'type' => 'textarea', + 'label' => $this->l('Description'), + 'name' => 'description', + 'cols' => 40, + 'rows' => 10, + 'value' => true, + 'lang' => true, + 'default' => '', + 'autoload_rte' => true, + ) + ); + return $inputs; + } + + public function endRenderForm() + { + $this->helper->module = new $this->module_name(); + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + $assign['path'] = apPageHelper::getImgThemeUrl(); + + if (!isset($assign['formAtts']['animation']) || $assign['formAtts']['animation'] == 'none') { + $assign['formAtts']['animation'] = 'none'; + $assign['formAtts']['animation_delay'] = ''; + } elseif ($assign['formAtts']['animation'] != 'none' && (int)$assign['formAtts']['animation_delay'] > 0) { + // validate module + $assign['formAtts']['animation_delay'] .= 's'; + } elseif ($assign['formAtts']['animation'] != 'none' && (int)$assign['formAtts']['animation_delay'] <= 0) { + // Default delay + $assign['formAtts']['animation_delay'] = '1s'; + } + if (isset($assign['formAtts']['image'])) { + $assign['formAtts']['image'] = trim($assign['formAtts']['image']); + } + return $assign; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApImage360.php b/modules/appagebuilder/classes/shortcodes/ApImage360.php new file mode 100644 index 00000000..ef10e72b --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApImage360.php @@ -0,0 +1,421 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApImage360 extends ApShortCodeBase +{ + public $name = 'ApImage360'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Image 360'), 'position' => 20, 'desc' => $this->l('Adds multiple 360 images, rotating display objects'), + 'icon_class' => 'icon-image', 'tag' => 'content structure'); + } + + public function getConfigList() + { + $href = Context::getContext()->link->getAdminLink('AdminApPageBuilderImages').'&ajax=1&action=manageimage&imgDir=images&widget=ApImage360'; + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'lang' => 'true', + 'default' => '', + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), +// array( +// 'type' => 'switch', +// 'label' => $this->l('Magnifier enable'), +// 'name' => 'magnify', +// 'is_bool' => true, +// 'values' => ApPageSetting::returnYesNo(), +// 'default' => 1, +// ), +// array( +// 'type' => 'text', +// 'name' => 'magnifier_width', +// 'label' => $this->trans("Magnifier's width"), +// 'default' => '80%', +// ), +// array( +// 'type' => 'select', +// 'label' => $this->trans("Magnifier's shape"), +// 'name' => 'magnifier_shape', +// 'options' => array( +// 'query' => array( +// array('id' => 'inner', 'name' => $this->l('Inner')), +// array('id' => 'circle', 'name' => $this->l('Circle')), +// array('id' => 'square', 'name' => $this->l('Square')), +// ), +// 'id' => 'id', +// 'name' => 'name' +// ), +// ), +// array( +// 'type' => 'switch', +// 'label' => $this->l('Fullscreen enable'), +// 'name' => 'fullscreen', +// 'is_bool' => true, +// 'values' => ApPageSetting::returnYesNo(), +// 'default' => 1, +// ), + array( + 'type' => 'select', + 'label' => $this->l('Spin'), + 'name' => 'spin', + 'options' => array( + 'query' => array( + array('id' => 'drag', 'name' => $this->l('Drag')), + array('id' => 'hover', 'name' => $this->l('Hover')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'desc' => $this->l('Method for spinning the image'), + ), + array( + 'type' => 'text', + 'name' => 'speed', + 'label' => $this->l('Speed'), +// 'lang' => 'true', + 'default' => '50', + 'desc' => $this->l('Mouse drag distance in pixels to next image (1 - 100). Ex 50'), + ), + array( + 'type' => 'text', + 'name' => 'mousewheel_step', + 'label' => $this->l('Mousewheel Step'), +// 'lang' => 'true', + 'default' => '1', + 'desc' => $this->l('Number of image to spin on mousewheel'), + ), + array( + 'type' => 'switch', + 'label' => $this->l('Smoothing'), + 'name' => 'smoothing', + 'is_bool' => true, + 'values' => ApPageSetting::returnYesNo(), + 'default' => 1, + 'desc' => $this->l('Smoothly stop the image spinning'), + ), + array( + 'type' => 'select', + 'label' => $this->l('Initialization'), + 'name' => 'initialize_on', + 'options' => array( + 'query' => array( + array('id' => 'hover', 'name' => $this->l('hover')), + array('id' => 'click', 'name' => $this->l('click')), + array('id' => 'load', 'name' => $this->l('load')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => 'load', + 'desc' => $this->l('Start automatic spin on page load, click or hover'), + ), + array( + 'type' => 'select', + 'label' => $this->l('Autospin duration'), + 'name' => 'autospin', + 'options' => array( + 'query' => array( + array('id' => 'once', 'name' => $this->l('Once')), + array('id' => 'twice', 'name' => $this->l('Twice')), + array('id' => 'infinite', 'name' => $this->l('Infinite')), + array('id' => 'off', 'name' => $this->l('Off')), + ), + 'id' => 'id', + 'name' => 'name' + ), +// 'desc' => $this->l('Method for spinning the image'), + ), + array( + 'type' => 'select', + 'label' => $this->l('Autospin start'), + 'name' => 'autospin_start', + 'options' => array( + 'query' => array( + array('id' => 'load', 'name' => $this->l('load')), + array('id' => 'hover', 'name' => $this->l('hover')), + array('id' => 'click', 'name' => $this->l('click')), + array('id' => 'load,hover', 'name' => $this->l('load,hover')), + array('id' => 'load,click', 'name' => $this->l('load,click')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'desc' => $this->l('Start automatic spin on page load, click or hover'), + ), + array( + 'type' => 'select', + 'label' => $this->l('Autospin stops'), + 'name' => 'autospin_stop', + 'options' => array( + 'query' => array( + array('id' => 'hover', 'name' => $this->l('hover')), + array('id' => 'click', 'name' => $this->l('click')), + array('id' => 'never', 'name' => $this->l('never')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'desc' => $this->l('Start automatic spin on page load, click or hover'), + ), + array( + 'type' => 'text', + 'name' => 'autospin_speed', + 'label' => $this->l('Autospin Time'), +// 'lang' => 'true', + 'default' => '2000', + 'desc' => $this->l('Value is milisecond. Ex 2000 (2s)'), + ), + array( + 'type' => 'select', + 'label' => $this->l('Autospin direction'), + 'name' => 'autospin_direction', + 'options' => array( + 'query' => array( + array('id' => 'clockwise', 'name' => $this->l('Clockwise')), + array('id' => 'anticlockwise', 'name' => $this->l('Anticlockwise')), + array('id' => 'alternate-clockwise', 'name' => $this->l('Alternate Clockwise')), + array('id' => 'alternate-anticlockwise', 'name' => $this->l('Alternate Anticlockwise')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'desc' => $this->l('Method for spinning the image'), + ), + array( + 'type' => 'text', + 'name' => 'start_column', + 'label' => $this->l('Start Column'), + 'default' => '1', + 'desc' => $this->l('Column from which to start spin. auto means to start from the middle'), + ), +// array( +// 'type' => 'text', +// 'name' => 'start_row', +// 'label' => $this->l('Start Row'), +// 'default' => 'auto', +// 'desc' => $this->l('Row from which to start spin. auto means to start from the middle'), +// ), + array( + 'type' => 'switch', + 'label' => $this->l('Loop Column'), + 'name' => 'loop_column', + 'is_bool' => true, + 'values' => ApPageSetting::returnYesNo(), + 'default' => 1, + 'desc' => $this->l('Continue spin after the last image on X-axis'), + ), +// array( +// 'type' => 'switch', +// 'label' => $this->l('Loop Row'), +// 'name' => 'loop_row', +// 'is_bool' => true, +// 'values' => ApPageSetting::returnYesNo(), +// 'default' => 1, +// 'desc' => $this->l('Continue spin after the last image on Y-axis'), +// ), + array( + 'type' => 'switch', + 'label' => $this->l('Reverse rotation on X-axis'), + 'name' => 'reverse_column', + 'is_bool' => true, + 'values' => ApPageSetting::returnYesNo(), + 'default' => 0, + ), +// array( +// 'type' => 'switch', +// 'label' => $this->l('Reverse rotation on Y-axis'), +// 'name' => 'reverse_row', +// 'is_bool' => true, +// 'values' => ApPageSetting::returnYesNo(), +// 'default' => 1, +// ), +// array( +// 'type' => 'text', +// 'name' => 'column_increment', +// 'label' => $this->l('Column increment'), +// 'default' => '1', +// 'desc' => $this->l('Load only every second (2) or third (3) column so that spins load faster'), +// ), +// array( +// 'type' => 'text', +// 'name' => 'row_increment', +// 'label' => $this->l('Row increment'), +// 'default' => '1', +// 'desc' => $this->l('Load only every second (2) or third (3) row so that spins load faster'), +// ), + array( + 'type' => 'text', + 'name' => 'message', + 'label' => $this->l('Message under image'), + 'default' => 'Drag image to spin', + 'lang' => true, + ), +// array( +// 'type' => 'text', +// 'name' => 'message_loading', +// 'label' => $this->l('Message Loading'), +// 'default' => 'Text displayed while images are loading.', +// 'lang' => true, +// ), +// array( +// 'type' => 'text', +// 'name' => 'message_loading_fullscreen', +// 'label' => $this->l('Message Fullscren Loading'), +// 'default' => 'Loading...', +// 'lang' => true, +// ), + array( + 'type' => 'switch', + 'label' => $this->l('Show hint message'), + 'name' => 'hint', + 'is_bool' => true, + 'values' => ApPageSetting::returnYesNo(), + 'default' => 1, + ), + array( + 'type' => 'text', + 'name' => 'message_desktop_hint', + 'label' => $this->l('Message Desktop Hint'), + 'default' => 'Drag to spin', + 'lang' => true, + 'desc' => $this->l('Text of the hint on Desktop'), + ), + array( + 'type' => 'text', + 'name' => 'message_mobile_hint', + 'label' => $this->l('Message Mobile Hint'), + 'default' => 'Swipe to spin', + 'lang' => true, + 'desc' => $this->l('Text of the hint on iOS/Android devices'), + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show Slider'), + 'name' => 'show_slider', + 'is_bool' => true, + 'values' => ApPageSetting::returnYesNo(), + 'default' => false, + ), + array( + 'type' => 'hidden', + 'name' => 'total_slider', + 'default' => '', + ), + array( + 'label' => $this->l('Image'), + 'type' => 'selectImg', + 'href' => $href, + 'name' => 'image_360', + 'lang' => false, + 'class' => 'item-add-slide ignore-lang', + 'form_group_class' => 'apfullslider-row select-img', + 'show_image' => false, + ) + ); + return $inputs; + } + + public function endRenderForm() + { + $this->helper->module = new $this->module_name(); + } + + /** + * Widget can override this method and add more config at here + */ + public function addConfigList($values) + { + // Get value with keys special + $config_val = array(); + $total = isset($values['total_slider']) ? $values['total_slider'] : ''; + + $arr = explode('|', $total); + $inputs = array('image360'); +// $languages = Language::getLanguages(false); + foreach ($arr as $i) { + foreach ($inputs as $config) { + $config_val[$config][$i] = str_replace($this->str_search, $this->str_relace_html_admin, Tools::getValue($config.'_'.$i, '')); + } + } + + Context::getContext()->smarty->assign(array( + 'arr' => $arr, + 'config_val' => $config_val, + 'image_folder' => apPageHelper::getImgThemeUrl(), + )); + $list_slider = Context::getContext()->smarty->fetch(apPageHelper::getShortcodeTemplatePath('ApImage360.tpl')); + $input = array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => $list_slider + ); + $this->config_list[] = $input; + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + + if (!Configuration::get('APPAGEBUILDER_LOAD_IMAGE360')) { + $assign['formAtts']['lib_has_error'] = true; + $assign['formAtts']['lib_error'] = 'Please enable Image360 library in Appagebuilder Configuration.'; + return $assign; + } + + $total_slider = isset($assign['formAtts']['total_slider']) ? $assign['formAtts']['total_slider'] : ''; + $list = explode('|', $total_slider); + + + $image_list = array(); + $image_path = apPageHelper::getImgThemeUrl(); + + foreach ($list as $item) { + if (isset($assign['formAtts']['image360_'.$item])) { + $image_list[] = $assign['formAtts']['image360_'.$item]; + } + } + + $assign['formAtts']['image_path'] = $image_path; + $assign['formAtts']['columns'] = count($list); + $assign['formAtts']['row'] = 1; + $assign['formAtts']['image_list'] = $image_list; + + // IMAGE DEFAULT + $min_key = min(array_keys($image_list)); + $assign['formAtts']['image_default'] = $image_list[$min_key]; + + return $assign; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApImageGallery.php b/modules/appagebuilder/classes/shortcodes/ApImageGallery.php new file mode 100644 index 00000000..3cf79255 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApImageGallery.php @@ -0,0 +1,236 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApImageGallery extends ApShortCodeBase +{ + public $name = 'ApImageGallery'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Image Gallery'), + 'position' => 7, + 'desc' => $this->l('Create Images Mini Gallery From A Folder'), + 'icon_class' => 'icon-th', + 'tag' => 'content'); + } + + private function addCustomJS() + { + return Context::getContext()->smarty->fetch(apPageHelper::getShortcodeTemplatePath($this->name.'.tpl')); + } + + public function getConfigList() + { + $path_info = 'Example: themes/'._THEME_NAME_.'/assets/img/modules/appagebuilder/images/yourFolderImage'; + $path = 'themes/'._THEME_NAME_.'/assets/img/modules/appagebuilder/images/'; + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'form_group_class' => 'aprow_general', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => '' + ), + array( + 'type' => 'text', + 'name' => 'path', + 'label' => $this->l('Path'), + 'desc' => $this->trans($path_info), + 'form_group_class' => 'aprow_general', + 'default' => $path, + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '' . $this->addCustomJS(), + ), + array( + 'type' => 'text', + 'label' => $this->l('Limit'), + 'name' => 'limit', + 'default' => '12', + 'desc' => $this->l('Enter a number') + ), + array( + 'type' => 'select', + 'label' => $this->l('Columns'), + 'name' => 'columns', + 'options' => array('query' => array( + array('id' => '1', 'name' => $this->l('1 Column')), + array('id' => '2', 'name' => $this->l('2 Columns')), + array('id' => '3', 'name' => $this->l('3 Columns')), + array('id' => '4', 'name' => $this->l('4 Columns')), + array('id' => '5', 'name' => $this->l('5 Columns')), + array('id' => '6', 'name' => $this->l('6 Columns')), + ), + 'id' => 'id', + 'name' => 'name'), + 'default' => '4', + ), + array( + 'type' => 'select', + 'label' => $this->l('Load more'), + 'name' => 'load_more', + 'options' => array('query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name'), + 'default' => '0', + 'desc' => $this->l('Show button load more image. Auto hide the button if all images is showed'), + ) + ); + return $inputs; + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + $form_atts = $assign['formAtts']; + $form_atts['path'] = ltrim($form_atts['path'], '/'); + $form_atts['path'] = rtrim($form_atts['path'], '/'); + + $limit = (int)$form_atts['limit']; + $images = array(); + $link = new Link(); + $current_link = $link->getPageLink('', false, Context::getContext()->language->id); + $path = _PS_ROOT_DIR_.'/'.str_replace($current_link, '', isset($form_atts['path']) ? $form_atts['path'] : ''); + $arr_exten = array('jpg', 'jpge', 'gif', 'png'); + + $count = 0; + if ($path && is_dir($path)) { + if ($handle = scandir($path)) { + + if (($key = array_search('.', $handle)) !== false) { + unset($handle[$key]); + } + if (($key = array_search('..', $handle)) !== false) { + unset($handle[$key]); + } + + foreach ($handle as $entry) { + if ($entry != '.' && $entry != '..' && is_file($path.'/'.$entry)) { + $ext = Tools::strtolower(pathinfo($path.'/'.$entry, PATHINFO_EXTENSION)); + if (in_array($ext, $arr_exten)) { + # FIX 1.7 + $images[] = __PS_BASE_URI__.str_replace($current_link, '', $form_atts['path']).'/'.$entry; + $count++; + if ($count == $limit) { + break; + } + } + } + } + } + } + + $total = count($handle); + $total_nerver_show = (int)( $total - $count ); + + if( isset($form_atts['load_more']) && (int) $form_atts['load_more'] == 1 && $total_nerver_show) + { + # SHOW BUTTON SHOW_MORE + $assign['show_number'] = $count; + $assign['show_more_btn'] = 1; + } + + + $c = (int)$form_atts['columns']; + $assign['columns'] = $c > 0 ? $c : 4; + $assign['images'] = $images; + if( isset($assign['tpl_dir'])) { + unset($assign['tpl_dir']); + } + $assign['assign'] = Tools::jsonEncode($assign); + + return $assign; + } + + /** + * AJAX : create folder image follow user type url + */ + public function ajaxCallBackCreateDir() + { + $path = Tools::getValue('path'); + +// $domain = strpos($url, _PS_BASE_URL_.__PS_BASE_URI__ ); +// if ($domain === false) +// { +// # CHECK NOT SAME DOMAIN +// # http://localhost/prestashop/ps_1700_RC03_local != http://prestashop/ps_1700_RC03_local +// die(Tools::jsonEncode(array( +// 'hasError' => true, +// 'error' => $this->l('Domain is incorrect. Please type this at first: '), +// 'img_dir' => _PS_BASE_URL_.__PS_BASE_URI__, +// ))); +// } + + $img_dir = str_replace(_PS_BASE_URL_.__PS_BASE_URI__, '', $path); + $img_dir = _PS_ROOT_DIR_.'/'.$img_dir; + $img_dir = str_replace('\\', '/', $img_dir); + $img_dir = str_replace('//', '/', $img_dir); + + if (file_exists($img_dir)) { + # CHECK FOLDER EXIST + die(Tools::jsonEncode(array( + 'hasError' => true, + 'error' => $this->l('Folder is exist'), + 'img_dir' => $img_dir, + ))); + } + + try { + $result = mkdir($img_dir, 0755, true); + if ($result) { + die(Tools::jsonEncode(array( + 'success' => true, + 'information' => $this->l('Create folder successful'), + 'img_dir' => $img_dir, + ))); + } + } catch (Exception $ex) { + die(Tools::jsonEncode(array( + 'hasError' => true, + 'error' => $this->l('Can NOT create folder'), + 'img_dir' => $img_dir, + ))); + } + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApImageGalleryProduct.php b/modules/appagebuilder/classes/shortcodes/ApImageGalleryProduct.php new file mode 100644 index 00000000..94b82868 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApImageGalleryProduct.php @@ -0,0 +1,262 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApImageGalleryProduct extends ApShortCodeBase +{ + public $name = 'ApImageGalleryProduct'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Image Gallery Product'), + 'position' => 7, + 'desc' => $this->l('Create Images Mini Gallery From Product'), + 'icon_class' => 'icon-th', + 'tag' => 'content'); + } + + public function getConfigList() + { + $source = array( + array( + 'value' => 'ip_pcategories', + 'name' => $this->l('Category') + ), + array( + 'value' => 'ip_pproductids', + 'name' => $this->l('Product Ids') + ) + ); + $pimagetypes = $this->getImageTypes(); + $selected_categories = array(); + if (Tools::getIsset('categorybox')) { + $category_box = Tools::getValue('categorybox'); + $category_box = explode(',', $category_box); + $selected_categories = $category_box; + } + $id_root_category = Context::getContext()->shop->getCategory(); + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'form_group_class' => 'aprow_general', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'select', + 'label' => $this->l('Source'), + 'name' => 'ip_source', + 'class' => 'group form-action', + 'default' => '', + 'options' => array( + 'query' => $source, + 'id' => 'value', + 'name' => 'name' + ), + 'desc' => 'Select source type' + ), + array( + 'type' => 'categories', + 'label' => $this->l('Select Category'), + 'name' => 'categorybox', + 'tree' => array( + 'root_category' => $id_root_category, + 'use_search' => false, + 'id' => 'categorybox', + 'use_checkbox' => true, + 'selected_categories' => $selected_categories, + ), + 'form_group_class' => 'ip_source_sub ip_source-ip_pcategories' + ), + array( + 'type' => 'text', + 'label' => $this->l('Product Ids'), + 'form_group_class' => 'ip_source_sub ip_source-ip_pproductids', + 'name' => 'ip_pproductids', + 'default' => '', + 'desc' => $this->l('Enter Product Ids with format id1,id2,...') + ), + array( + 'type' => 'select', + 'label' => $this->l('Small image'), + 'name' => 'smallimage', + 'class' => 'group', + 'id' => 'psmallimagetypes', + 'default' => '', + 'options' => array( + 'query' => $pimagetypes, + 'id' => 'name', + 'name' => 'name' + ) + ), + array( + 'type' => 'select', + 'label' => $this->l('Thick image'), + 'name' => 'thickimage', + 'id' => 'pthickimagetypes', + 'default' => ApPageSetting::getDefaultNameImage('thickbox'), + 'options' => array( + 'query' => $pimagetypes, + 'id' => 'name', + 'name' => 'name' + ) + ), + array( + 'type' => 'text', + 'label' => $this->l('Limit'), + 'name' => 'limit', + 'default' => '12', + 'desc' => $this->l('Enter a number') + ), + array( + 'type' => 'select', + 'label' => $this->l('Columns'), + 'name' => 'columns', + 'options' => array('query' => array( + array('id' => '1', 'name' => $this->l('1 Column')), + array('id' => '2', 'name' => $this->l('2 Columns')), + array('id' => '3', 'name' => $this->l('3 Columns')), + array('id' => '4', 'name' => $this->l('4 Columns')), + array('id' => '5', 'name' => $this->l('5 Columns')), + array('id' => '6', 'name' => $this->l('6 Columns')), + ), + 'id' => 'id', + 'name' => 'name'), + 'default' => '4', + ) + ); + return $inputs; + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + $form_atts = $assign['formAtts']; + $limit = (int)$form_atts['limit']; + $images = array(); + $smallimage = ($form_atts['smallimage']) ? ($form_atts['smallimage']) : ApPageSetting::getDefaultNameImage('small'); + $thickimage = ($form_atts['thickimage']) ? ($form_atts['thickimage']) : ApPageSetting::getDefaultNameImage('thickbox'); + switch ($form_atts['ip_source']) { + case 'ip_pproductids': + if (empty($form_atts['ip_pproductids'])) { + return false; + } + $pproductids = $form_atts['ip_pproductids']; + if ($pproductids) { + $images = $this->getImagesByProductId($pproductids, 0, $limit, (int)Context::getContext()->language->id); + } + break; + case 'ip_pcategories': + $catids = (isset($form_atts['categorybox']) && $form_atts['categorybox']) ? ($form_atts['categorybox']) : array(); + if ($catids) { + $images = $this->getImagesByCategory($catids, 0, $limit, (int)Context::getContext()->language->id); + } + break; + } + $c = (int)$form_atts['columns']; + $assign['columns'] = $c > 0 ? $c : 4; + $assign['thickimage'] = $thickimage; + $assign['smallimage'] = $smallimage; + $assign['images'] = $images; + return $assign; + } + + public function getImagesByProductId($productids, $start, $limit, $id_lang) + { + $sql = 'SELECT DISTINCT(i.`id_image`), pl.`link_rewrite` + FROM + `'._DB_PREFIX_.'image` i + LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON(i.`id_image` = il.`id_image`) + LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON( + i.`id_product` = pl.`id_product`)'; + $sql .= ' WHERE i.`id_product` IN ('.$productids.') + AND il.`id_lang` ='.(int)$id_lang. + ' AND pl.`id_lang` ='.(int)$id_lang. + ' AND i.cover = 1 + ORDER BY + i.`position` ASC'.($limit > 0 ? ' LIMIT '.(int)$start.','.(int)$limit : ''); + $results = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); + return $results; + } + + public static function getImagesByCategory($categories, $start, $limit, $id_lang, Context $context = null) + { + if (!$context) { + $context = Context::getContext(); + } + $front = true; + if (!in_array($context->controller->controller_type, array('front', 'modulefront'))) { + $front = false; + } + $sql_groups = ''; + if (Group::isFeatureActive()) { + $groups = FrontController::getCurrentCustomerGroups(); + $sql_groups = 'AND cg.`id_group` '.(count($groups) ? 'IN ('.pSQL(implode(',', $groups)).')' : '= 1'); + } + $sql = 'SELECT i.`id_image`, pl.`link_rewrite` + FROM + `'._DB_PREFIX_.'image` i + INNER JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image`) + INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (i.`id_product` = pl.`id_product`) + INNER JOIN `'._DB_PREFIX_.'image_shop` ish ON (i.`id_image` = ish.`id_image`)'; + $sql .= 'WHERE i.`id_product` IN ( + SELECT cp.`id_product` + FROM `'._DB_PREFIX_.'category_product` cp + '.(Group::isFeatureActive() ? 'INNER JOIN `'._DB_PREFIX_.'category_group` cg ON cp.`id_category` = cg.`id_category`' : '').' + INNER JOIN `'._DB_PREFIX_.'category` c ON cp.`id_category` = c.`id_category` + INNER JOIN `'._DB_PREFIX_.'product` p ON cp.`id_product` = p.`id_product` + '.Shop::addSqlAssociation('product', 'p', false).' + LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` '.Shop::addSqlRestrictionOnLang('pl').') + WHERE c.`active` = 1 + AND product_shop.`active` = 1 + '.($front ? ' AND product_shop.`visibility` IN ("both", "catalog")' : '') + .pSQL($sql_groups).' AND cp.id_category in ('.pSQL($categories).') AND pl.id_lang ='.(int)$id_lang.') + AND il.`id_lang` ='.$id_lang. + ' AND pl.id_lang = '.(int)$id_lang. + ' AND pl.id_shop = '.(int)$context->shop->id. + ' AND ish.id_shop = '.(int)$context->shop->id. + ' AND ish.cover = 1 + ORDER BY i.`position` ASC'.((int)$limit > 0 ? ' LIMIT '.(int)$start.','.(int)$limit : ''); + return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); + } + + public function getImageTypes() + { + $pimagetypes = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' + SELECT tp.id_image_type,tp.name + FROM '._DB_PREFIX_.'image_type tp + WHERE tp.products = 1 + ORDER BY tp.name ASC'); + return $pimagetypes; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApImageHotspot.php b/modules/appagebuilder/classes/shortcodes/ApImageHotspot.php new file mode 100644 index 00000000..3d8bebb2 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApImageHotspot.php @@ -0,0 +1,516 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApImageHotspot extends ApShortCodeBase +{ + public $name = 'ApImageHotspot'; + public $for_module = 'manage'; + + public $inputs_lang = array('temp_title', 'temp_image', 'temp_description'); + public $inputs = array('temp_top', 'temp_left', 'temp_hpcolor', 'temp_location', 'temp_textalign', 'temp_trigger', 'temp_opacity', 'temp_width', 'temp_margin', 'temp_padding', 'temp_textcolor', 'temp_backcolor', 'temp_class', 'temp_imagealign'); + + public function getInfo() + { + return array('label' => $this->l('Image Hotspot'), + 'position' => 5, + 'desc' => $this->l('Display tooltip in your image when user hover over points'), + 'icon_class' => 'icon-image', + 'tag' => 'content'); + } + + public function getConfigList() + { + Context::getContext()->smarty->assign('path_image', apPageHelper::getImgThemeUrl()); + $href = Context::getContext()->link->getAdminLink('AdminApPageBuilderImages').'&ajax=1&action=manageimage&imgDir=images'; + $ad = __PS_BASE_URI__.basename(_PS_ADMIN_DIR_); + $iso_tiny_mce = Context::getContext()->language->iso_code; + $iso_tiny_mce = (file_exists(_PS_JS_DIR_.'tiny_mce/langs/'.$iso_tiny_mce.'.js') ? $iso_tiny_mce : 'en'); + $list_slider = '
    '; + $list_slider_button = '
    +
    +
    + + + +
    +
    + +
    +
    '; + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'label' => $this->l('Image'), + 'type' => 'selectImg', + 'href' => $href, + 'name' => 'image', + 'lang' => true, + 'show_image' => true, + ), + array( + 'type' => 'text', + 'name' => 'alt', + 'label' => $this->l('Alt'), + 'default' => '' + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => '' + ), + array( + 'type' => 'text', + 'name' => 'url', + 'label' => $this->l('Link to'), + 'lang' => true, + 'desc' => 'Example: http://prestashop.com', + 'default' => '' + ), + array( + 'type' => 'switch', + 'label' => $this->l('Open new tab'), + 'name' => 'is_open', + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + ), + array( + 'type' => 'text', + 'name' => 'width', + 'label' => $this->l('Image size width'), + 'desc' => $this->l('Example: auto, 100%, 100px'), + 'default' => '100%' + ), + array( + 'type' => 'text', + 'name' => 'height', + 'label' => $this->l('Image size height'), + 'desc' => $this->l('Example: auto, 100%, 100px'), + 'default' => 'auto' + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => $list_slider + ), + array( + 'type' => 'text', + 'name' => 'temp_title', + 'label' => $this->l('Title'), + 'lang' => 'true', + 'default' => '', + 'class' => 'input-level2 temp_title js-multilang', + 'form_group_class' => 'row-level2 row2-title', + ), + array( + 'label' => $this->l('Image'), + 'type' => 'selectImg', + 'href' => $href, + 'name' => 'temp_image', + 'lang' => true, + 'class' => 'input-level2 temp_image js-multilang', + 'form_group_class' => 'row-level2 row2-image', + ), + array( + 'type' => 'select', + 'label' => $this->l('Image Align'), + 'name' => 'temp_imagealign', + 'options' => array( + 'query' => array( + array( + 'id' => 'left', + 'name' => $this->l('Left'), + ), + array( + 'id' => 'right', + 'name' => $this->l('Right'), + ), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => 'left', + 'class' => 'input-level2 temp_imagealign', + 'form_group_class' => 'row-level2', + ), + array( + 'type' => 'textarea', + 'label' => $this->l('Description'), + 'name' => 'temp_description', + 'cols' => 40, + 'rows' => 10, + 'value' => true, + 'lang' => true, + 'default' => '', + 'class' => 'input-level2 temp_description js-multilang', + 'form_group_class' => 'row-level2 row2-description', + ), + array( + 'type' => 'text', + 'name' => 'temp_top', + 'label' => $this->l('Hotpot Top'), + 'lang' => false, + 'default' => '', + 'class' => 'input-level2 temp_top', + 'form_group_class' => 'row-level2', + ), + array( + 'type' => 'text', + 'name' => 'temp_left', + 'label' => $this->l('Hotpot Left'), + 'lang' => false, + 'default' => '', + 'class' => 'input-level2 temp_left', + 'form_group_class' => 'row-level2', + ), + array( + 'type' => 'color', + 'name' => 'temp_hpcolor', + 'label' => $this->l('Hotpot Color'), + 'lang' => false, + 'default' => '', + 'class' => 'input-level2 temp_hpcolor', + 'form_group_class' => 'row-level2', + ), + array( + 'type' => 'select', + 'label' => $this->l('Location'), + 'name' => 'temp_location', + 'options' => array( + 'query' => array( + array( + 'id' => 'top', + 'name' => $this->l('top'), + ), + array( + 'id' => 'right', + 'name' => $this->l('right'), + ), + array( + 'id' => 'bottom', + 'name' => $this->l('bottom'), + ), + array( + 'id' => 'left', + 'name' => $this->l('left'), + ), + array( + 'id' => 'top-left', + 'name' => $this->l('top-left'), + ), + array( + 'id' => 'top-right', + 'name' => $this->l('top-right'), + ), + array( + 'id' => 'right-top', + 'name' => $this->l('right-top'), + ), + array( + 'id' => 'right-bottom', + 'name' => $this->l('right-bottom'), + ), + array( + 'id' => 'bottom-left', + 'name' => $this->l('bottom-left'), + ), + array( + 'id' => 'bottom-right', + 'name' => $this->l('bottom-right'), + ), + array( + 'id' => 'left-top', + 'name' => $this->l('left-top'), + ), + array( + 'id' => 'left-bottom', + 'name' => $this->l('left-bottom'), + ), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => 'none', + 'class' => 'input-level2 temp_location', + 'form_group_class' => 'row-level2', + ), + array( + 'type' => 'select', + 'label' => $this->l('Text Align'), + 'name' => 'temp_textalign', + 'options' => array( + 'query' => array( + array( + 'id' => 'left', + 'name' => $this->l('Left'), + ), + array( + 'id' => 'top', + 'name' => $this->l('Top'), + ), + array( + 'id' => 'right', + 'name' => $this->l('Right'), + ), + array( + 'id' => 'center', + 'name' => $this->l('Center'), + ), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => 'left', + 'class' => 'input-level2 temp_textalign', + 'form_group_class' => 'row-level2', + ), + array( + 'type' => 'select', + 'label' => $this->l('Mouse event'), + 'name' => 'temp_trigger', + 'options' => array( + 'query' => array( + array( + 'id' => 'hover', + 'name' => $this->l('hover'), + ), + array( + 'id' => 'hoverable', + 'name' => $this->l('hoverable'), + ), + array( + 'id' => 'click', + 'name' => $this->l('click'), + ), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => 'hover', + 'class' => 'input-level2 temp_trigger', + 'form_group_class' => 'row-level2', + ), + array( + 'type' => 'text', + 'name' => 'temp_opacity', + 'label' => $this->l('Opacity'), + 'lang' => false, + 'default' => '0.6', + 'class' => 'input-level2 temp_opacity', + 'form_group_class' => 'row-level2', + ), + array( + 'type' => 'text', + 'name' => 'temp_class', + 'label' => $this->l('Class'), + 'lang' => false, + 'default' => '', + 'class' => 'input-level2 temp_class', + 'form_group_class' => 'row-level2', + ), + array( + 'type' => 'text', + 'name' => 'temp_width', + 'label' => $this->l('Width'), + 'lang' => false, + 'default' => '200px', + 'class' => 'input-level2 temp_width', + 'form_group_class' => 'row-level2', + ), + array( + 'type' => 'text', + 'name' => 'temp_margin', + 'label' => $this->l('Margin'), + 'lang' => false, + 'default' => '', + 'class' => 'input-level2 temp_margin', + 'form_group_class' => 'row-level2', + ), + array( + 'type' => 'text', + 'name' => 'temp_padding', + 'label' => $this->l('Padding'), + 'lang' => false, + 'default' => '', + 'class' => 'input-level2 temp_padding', + 'form_group_class' => 'row-level2', + ), + array( + 'type' => 'color', + 'name' => 'temp_textcolor', + 'label' => $this->l('Text Color'), + 'lang' => false, + 'default' => '', + 'class' => 'input-level2 temp_textcolor', + 'form_group_class' => 'row-level2', + ), + array( + 'type' => 'color', + 'name' => 'temp_backcolor', + 'label' => $this->l('Backgroud Color'), + 'lang' => false, + 'default' => '', + 'class' => 'input-level2 temp_backcolor', + 'form_group_class' => 'row-level2', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => $list_slider_button + ), + array( + 'type' => 'hidden', + 'name' => 'total_slider', + 'default' => '' + ), + ); + return $inputs; + } + + public function addConfigList($values) + { + // Get value with keys special + $config_val = array(); + $total = isset($values['total_slider']) ? $values['total_slider'] : ''; + $arr = explode('|', $total); + + $inputs_lang = $this->inputs_lang; + $inputs = $this->inputs; + + + $languages = Language::getLanguages(false); + foreach ($arr as $i) { + foreach ($inputs_lang as $config) { + foreach ($languages as $lang) { + $config_val[$config][$i][$lang['id_lang']] = str_replace($this->str_search, $this->str_relace_html_admin, Tools::getValue($config.'_'.$i.'_'.$lang['id_lang'], '')); + } + } + foreach ($inputs as $config) { + $config_val[$config][$i] = str_replace($this->str_search, $this->str_relace_html_admin, Tools::getValue($config.'_'.$i, '')); + } + } + + Context::getContext()->smarty->assign(array( + 'lang' => $lang = new Language((int)Configuration::get('PS_LANG_DEFAULT')), + 'default_lang' => $lang->id, + 'arr' => $arr, + 'languages' => $languages, + 'config_val' => $config_val, + 'path' => apPageHelper::getImgThemeUrl(), + 'inputs_lang' => $this->inputs_lang, + 'inputs' => $this->inputs, + )); + $list_slider = Context::getContext()->smarty->fetch(apPageHelper::getShortcodeTemplatePath('ApImageHotspot.tpl')); + + $input = array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => $list_slider, + ); + // Append new input type html + $this->config_list[] = $input; + } + + public function endRenderForm() + { + $this->helper->module = new $this->module_name(); + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + if (!Configuration::get('APPAGEBUILDER_LOAD_IMAGEHOTPOT')) { + $assign['formAtts']['lib_has_error'] = true; + $assign['formAtts']['lib_error'] = 'Please enable Image Hotpot library in Appagebuilder Configuration.'; + return $assign; + } + $assign['path'] = apPageHelper::getImgThemeUrl(); + $total_slider = isset($assign['formAtts']['total_slider']) ? $assign['formAtts']['total_slider'] : ''; + $list = explode('|', $total_slider); + $list_items = array(); + $lang = Language::getLanguage(Context::getContext()->language->id); + $id_lang = $lang['id_lang']; + + $inputs_lang = $this->inputs_lang; + $inputs = $this->inputs; + + foreach ($list as $number) { + if ($number) { + $item = array(); + $item['id'] = $number; + + foreach ($inputs_lang as $key) { + # MULTI-LANG + $name = $key.'_'.$number.'_'.$id_lang; + $item[$key] = isset($assign['formAtts'][$name]) ? $assign['formAtts'][$name] : ''; + + // Description + if ($key == 'temp_description' && isset($assign['formAtts'][$name]) && $assign['formAtts'][$name]) { + $item[$key] = str_replace($this->str_search, $this->str_relace_html, $assign['formAtts'][$name]); + } + + // Image + if ($key == 'temp_image' && isset($assign['formAtts'][$name]) && $assign['formAtts'][$name]) { + $item[$key] = apPageHelper::getImgThemeUrl() . $assign['formAtts'][$name]; + } else if ($key == 'temp_image') { + $item[$key] = ''; + } + } + foreach ($inputs as $key) { + # SINGLE-LANG + $name = $key.'_'.$number; + $item[$key] = isset($assign['formAtts'][$name]) ? $assign['formAtts'][$name] : ''; + } + + $list_items[] = $item; + } + } + $assign['formAtts']['items'] = $list_items; + + return $assign; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApInstagram.php b/modules/appagebuilder/classes/shortcodes/ApInstagram.php new file mode 100644 index 00000000..dce08dc4 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApInstagram.php @@ -0,0 +1,559 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApInstagram extends ApShortCodeBase +{ + public $name = 'ApInstagram'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Instagram'), + 'position' => 6, + 'desc' => $this->l('You can config Instagram box'), + 'icon_class' => 'icon-instagram', + 'tag' => 'social'); + } + + public function getConfigList() + { + $accordion_type = array( + array( + 'value' => 'full', + 'text' => $this->l('Always Full') + ), + array( + 'value' => 'accordion', + 'text' => $this->l('Always Accordion') + ), + array( + 'value' => 'accordion_small_screen', + 'text' => $this->l('Accordion at small screen') + ), + ); +// $soption = ApPageSetting::returnYesNo(); +// $get = array( +// array( +// 'id' => 'popular', +// 'label' => $this->l('Popular') +// ), +// array( +// 'id' => 'tagged', +// 'label' => $this->l('Tagged'), +// ), +// array( +// 'id' => 'location', +// 'label' => $this->l('Location') +// ), +// array( +// 'id' => 'user', +// 'label' => $this->l('User') +// ), +// ); + $sort = array( + array( + 'id' => 'none', + 'label' => $this->l('None') + ), + array( + 'id' => 'most-recent', + 'label' => $this->l('Newest to oldest.'), + ), + array( + 'id' => 'least-recent', + 'label' => $this->l('Oldest to newest.') + ), + array( + 'id' => 'most-liked', + 'label' => $this->l('Highest # of likes to lowest.') + ), + array( + 'id' => 'least-liked', + 'label' => $this->l('Lowest # likes to highest.') + ), + array( + 'id' => 'most-commented', + 'label' => $this->l('Highest # of comments to lowest.') + ), + array( + 'id' => 'least-commented', + 'label' => $this->l('Lowest # of comments to highest.') + ), + array( + 'id' => 'random', + 'label' => $this->l('Random order.') + ), + ); + $resolution = array( + array( + 'id' => 'thumbnail', + 'label' => $this->l('thumbnail - 150x150') + ), + array( + 'id' => 'low_resolution', + 'label' => $this->l('low_resolution - 306x306'), + ), + array( + 'id' => 'standard_resolution', + 'label' => $this->l('standard_resolution - 612x612') + ) + ); +// $display_type = array( +// array( +// 'id' => 'list', +// 'label' => $this->l('Display as List') +// ), +// array( +// 'id' => 'carousel', +// 'label' => $this->l('Display as Boostrap Carousel'), +// ), +// array( +// 'id' => 'owl-carousel', +// 'label' => $this->l('Display as Owl Carousel') +// ) +// ); + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'form_group_class' => 'aprow_general', + 'desc' => $this->l('The script was get from http://instafeedjs.com/'), + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => '' + ), + array( + 'type' => 'select', + 'label' => $this->l('Accordion Type'), + 'name' => 'accordion_type', + 'options' => array( + 'query' => $accordion_type, + 'id' => 'value', + 'name' => 'text' ), + 'default' => 'full', + 'hint' => $this->l('Select a Accordion Type'), + ), + array( + 'type' => 'text', + 'label' => $this->l('Client ID'), + 'name' => 'client_id', + 'class' => 'ap_instagram', + 'desc' => $this->l('Your API client id from Instagram. Required.'), + 'default' => '3e4a239f6a704208ba131d140a751098', + ), + array( + 'type' => 'text', + 'label' => $this->l('Access Token'), + 'name' => 'access_token', + 'class' => 'ap_instagram', +// 'desc' => $this->l('A valid oAuth token. Required to use get: "user".'), + 'default' => '3953969014.3e4a239.993032cd15cc463cabd9eea3ce9d1639', + ), +// array( +// 'type' => 'text', +// 'label' => $this->l('Target'), +// 'name' => 'target', +// 'class' => 'ap_instagram', +// 'desc' => $this->l('The ID of a DOM element you want to add the images to.'), +// 'default' => '', +// ), +// array( +// 'type' => 'textarea', +// 'label' => $this->l('Template'), +// 'name' => 'template', +// 'class' => 'ap_instagram', +// 'desc' => $this->l('(Developer Only) Custom HTML template to use for images.'), +// 'default' => '', +// ), +// array( +// 'type' => 'select', +// 'label' => $this->l('Get'), +// 'name' => 'get', +// 'class' => 'ap_instagram', +// 'options' => array( +// 'query' => $get, +// 'id' => 'id', +// 'name' => 'label' +// ), +// 'desc' => $this->l('Customize what Instafeed fetches'), +// 'default' => 'user', +// ), +// array( +// 'type' => 'text', +// 'label' => $this->l('Tag Name'), +// 'name' => 'tag_name', +// 'desc' => $this->l('Name of the tag to get. Use with get: "tagged".'), +// 'default' => '', +// ), +// array( +// 'type' => 'text', +// 'label' => $this->l('Location ID'), +// 'name' => 'location_id', +// 'desc' => $this->l('(number) Unique id of a location to get. Use with get: "location".'), +// 'default' => '', +// ), + array( + 'type' => 'text', + 'label' => $this->l('User ID'), + 'name' => 'user_id', + 'desc' => $this->l('User ID of Instagram Account. Type Number'), + 'default' => '3953969014', + ), + array( + 'type' => 'select', + 'label' => $this->l('Sort By'), + 'name' => 'sort_by', + 'class' => 'ap_instagram', + 'options' => array( + 'query' => $sort, + 'id' => 'id', + 'name' => 'label' + ), + 'desc' => $this->l('Sort the images in a set order. Available options are'), + 'default' => 'none', + ), + array( + 'type' => 'text', + 'label' => $this->l('Links'), + 'desc' => $this->l('Wrap the images with a link to the photo on Instagram. Set empty to use link of Instagram Image'), + 'name' => 'links', + 'default' => '', + ), + array( + 'type' => 'text', + 'label' => $this->l('Limit'), + 'desc' => $this->l('Number of Images want to get. Max is 20 images, this is rule of Instagram.'), + 'name' => 'limit', + 'default' => '20', + ), + array( + 'type' => 'select', + 'label' => $this->l('Resolution'), + 'name' => 'resolution', + 'class' => 'ap_instagram', + 'options' => array( + 'query' => $resolution, + 'id' => 'id', + 'name' => 'label' + ), + 'desc' => $this->l('Size of the images to show.'), + 'default' => 'thumbnail', + ), + array( + 'type' => 'text', + 'label' => $this->l('Profile Link'), + 'desc' => $this->l('Create link in footer link to profile'), + 'name' => 'profile_link', + 'default' => '', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Template Type').'
    ', + ), + array( + 'type' => 'select', + 'label' => $this->l('Carousel Type'), + 'class' => 'form-action', + 'name' => 'carousel_type', + 'options' => array( + 'query' => array( + array('id' => 'list', 'name' => $this->l('Normal List')), + array('id' => 'owlcarousel', 'name' => $this->l('Owl Carousel')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => 'list' + ), + //Owl Carousel begin + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Items per Row').'
    ', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'items', + 'label' => $this->l('Items'), + 'desc' => $this->l('Typing number of items. Default'), + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + 'default' => '5', + ), + array( + 'type' => 'text', + 'name' => 'itemsdesktop', + 'label' => $this->l('Items_Desktop'), + 'desc' => $this->l('Typing number of items ( with Screen < 1200 )'), + 'default' => '4', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemsdesktopsmall', + 'label' => $this->l('Items_Desktop_Small'), + 'desc' => $this->l('Typing number of items ( with Screen < 992 )'), + 'default' => '3', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemstablet', + 'label' => $this->l('Items_Tablet'), + 'desc' => $this->l('Typing number of items ( with Screen < 768 )'), + 'default' => '2', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemsmobile', + 'label' => $this->l('Items_Mobile'), + 'desc' => $this->l('Typing number of items ( with Screen < 576 )'), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemscustom', + 'label' => $this->l('Items_Custom'), + 'desc' => $this->l('(Advance User) Example: [[0, 2], [576, 3], [768, 4], [992, 5], [1200, 6]]. The format is [x,y] whereby x=browser width and y=number of slides displayed'), + 'default' => '', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itempercolumn', + 'label' => $this->l('Items per Column'), + 'desc' => $this->l('Number of item per one column. Same with number of line for one page'), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Effect').'
    ', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Autoplay'), + 'name' => 'autoplay', + 'is_bool' => true, + 'desc' => $this->l('Yes - scroll per page. No - scroll per item. This affect next/prev buttons and mouse/touch dragging.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Stop on Hover'), + 'name' => 'stoponhover', + 'is_bool' => true, + 'desc' => $this->l('Stop autoplay on mouse hover'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Responsive'), + 'name' => 'responsive', + 'is_bool' => true, + 'desc' => $this->l('You can use Owl Carousel on desktop-only websites too! Just change that to "false" to disable resposive capabilities'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Navigation'), + 'name' => 'navigation', + 'is_bool' => true, + 'desc' => $this->l('Display "next" and "prev" buttons.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Auto Height'), + 'name' => 'autoHeight', + 'is_bool' => true, + 'desc' => $this->l('Add height to owl-wrapper-outer so you can use diffrent heights on slides. Use it only for one item per page setting.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Mouse Drag'), + 'name' => 'mouseDrag', + 'is_bool' => true, + 'desc' => $this->l('On DeskTop - Turn off/on mouse events.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Touch Drag'), + 'name' => 'touchdrag', + 'is_bool' => true, + 'desc' => $this->l('On Mobile - Turn off/on touch events.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Lazy Load: This function is only work when have one item per column').'
    ', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Lazy Load'), + 'name' => 'lazyload', + 'values' => ApPageSetting::returnYesNo(), + 'desc' => $this->l('Delays loading of images. Images outside of viewport will not be loaded before user scrolls to them. Great for mobile devices to speed up page loadings'), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Lazy Follow'), + 'name' => 'lazyfollow', + 'is_bool' => true, + 'desc' => $this->l('When pagination used, it skips loading the images from pages that got skipped. It only loads the images that get displayed in viewport. If set to false, all images get loaded when pagination used. It is a sub setting of the lazy load function.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'select', + 'label' => $this->l('Lazy Effect'), + 'name' => 'lazyeffect', + 'options' => array( + 'query' => array( + array('id' => 'fade', 'name' => $this->l('fade')), + array('id' => 'false', 'name' => $this->l('No')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'desc' => $this->l('Default is fadeIn on 400ms speed. Use false to remove that effect.'), + 'default' => 'fade', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Pagination Enable'), + 'name' => 'pagination', + 'is_bool' => true, + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'desc' => $this->l('Show Pagination below owl-carousel.'), + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Pagination Numbers'), + 'name' => 'paginationnumbers', + 'is_bool' => true, + 'desc' => $this->l('Show numbers inside Pagination'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('NEXT PAGE').'
    ', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Scroll per Page'), + 'name' => 'scrollPerPage', + 'is_bool' => true, + 'desc' => $this->l('Yes - scroll per Page. No - scroll per Item. This affect next/prev buttons and mouse/touch dragging.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'label' => $this->l('Scroll Page Speed'), + 'name' => 'paginationspeed', + 'desc' => $this->l('Time to next page. Ex 800 ( Milliseconds )'), + 'default' => '800', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'label' => $this->l('Scroll Item Speed'), + 'name' => 'slidespeed', + 'desc' => $this->l('Time to next item. Ex 200 (Milliseconds)'), + 'default' => '200', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + //Owl Carousel end + ); + return $inputs; + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + + if (!Configuration::get('APPAGEBUILDER_LOAD_INSTAFEED')) { + $assign['formAtts']['lib_has_error'] = true; + $assign['formAtts']['lib_error'] = 'Can not show Instagram. Please enable Instafeed library in Appagebuilder Configuration.'; + return $assign; + } elseif (isset($assign['formAtts']['carousel_type']) && $assign['formAtts']['carousel_type'] == 'owlcarousel') { + if (!Configuration::get('APPAGEBUILDER_LOAD_OWL')) { + $assign['formAtts']['lib_has_error'] = true; + $assign['formAtts']['lib_error'] = 'Can not show Instagram. Please enable Owl Carousel library in Appagebuilder Configuration.'; + return $assign; + } + } + + $assign['formAtts']['get'] = 'user'; + return $assign; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApManuFacturersCarousel.php b/modules/appagebuilder/classes/shortcodes/ApManuFacturersCarousel.php new file mode 100644 index 00000000..dab96d24 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApManuFacturersCarousel.php @@ -0,0 +1,950 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApManuFacturersCarousel extends ApShortCodeBase +{ + public $name = 'ApManuFacturersCarousel'; + + public function getInfo() + { + return array('label' => $this->l('Manufacturers carousel'), 'position' => 6, + 'desc' => $this->l('Show manufacturers in Carousel'), 'icon_class' => 'icon icon-chevron-right', + 'tag' => 'content slider'); + } + + public function getConfigList() + { + //get all manufacture + $manufacturers = Manufacturer::getManufacturers(false, 0, true, false, false, false, true); + // get image type + $imagetype = ImageType::getImagesTypes('manufacturers'); + $iselect = Tools::getValue('value_by_manufacture'); + if ($iselect === '0') { + $script_update_select = ''; + } else { + $script_update_select = ''; + } + + $input = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => '' + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '. + $this->l('Step 1: Use latest manufacturers or select Manufacturers').'
    '.$script_update_select, + ), + array( + 'type' => 'checkbox', + 'name' => 'value_by', + 'label' => $this->l('Select manufacturers'), + 'class' => 'checkbox-group', + 'desc' => $this->l('Unchecked to show latest manufacturers'), + 'values' => array( + 'query' => array( + array( + 'id' => 'manufacture', + 'name' => $this->l('Select Manufacturers'), + 'val' => '0' + ) + ), + 'id' => 'id', + 'name' => 'name' + ) + ), + array( + 'type' => 'select', + 'label' => $this->l('Manufacture'), + 'name' => 'manuselect[]', + 'multiple' => true, + 'options' => array( + 'query' => $manufacturers, + 'id' => 'id_manufacturer', + 'name' => 'name' + ), + 'default' => 'all', + 'form_group_class' => 'value_by_manufacture', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Step 2: Select image type').'
    ', + ), + array( + 'type' => 'select', + 'label' => $this->l('Image:'), + 'desc' => $this->l('Select image type for manufacture.'), + 'name' => 'imagetype', + 'default' => ApPageSetting::getDefaultNameImage('small'), + 'options' => array( + 'query' => $imagetype, + 'id' => 'name', + 'name' => 'name' + ) + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Step 3: Product Order And Limit').'
    ', + ), + array( + 'type' => 'select', + 'label' => $this->l('Order Way'), + 'class' => 'form-action', + 'name' => 'order_way', + 'options' => array( + 'query' => array( + array('id' => 'asc', 'name' => $this->l('Asc')), + array('id' => 'desc', 'name' => $this->l('Desc')), + array('id' => 'random', 'name' => $this->l('Random'))), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => 'all', + 'form_group_class' => 'value_by_manufacture', + ), + array( + 'type' => 'select', + 'label' => $this->l('Order By'), + 'name' => 'order_by', + 'options' => array( + 'query' => ApPageSetting::getOrderByManu(), + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'order_type_sub order_type-asc order_type-desc', + 'default' => 'all', + 'form_group_class' => 'value_by_manufacture', + ), + array( + 'type' => 'text', + 'name' => 'manu_limit', + 'label' => $this->l('Limit'), + 'default' => '10', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Step 3: Carousel Setting').'
    ', + ), + array( + 'type' => 'select', + 'label' => $this->l('Carousel Type'), + 'class' => 'form-action', + 'name' => 'carousel_type', + 'options' => array( + 'query' => array( + array('id' => 'boostrap', 'name' => $this->l('Bootstrap')), + array('id' => 'owlcarousel', 'name' => $this->l('Owl Carousel')), + array('id' => 'slickcarousel', 'name' => $this->l('Slick Carousel')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => 'boostrap' + ), + //Owl Carousel begin + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Items per Row').'
    ', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'items', + 'label' => $this->l('Items'), + 'desc' => $this->l('Typing number of items. Default'), + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + 'default' => '5', + ), + array( + 'type' => 'text', + 'name' => 'itemsdesktop', + 'label' => $this->l('Items_Desktop'), + 'desc' => $this->l('Typing number of items ( with Screen < 1200 )'), + 'default' => '4', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemsdesktopsmall', + 'label' => $this->l('Items_Desktop_Small'), + 'desc' => $this->l('Typing number of items ( with Screen < 992 )'), + 'default' => '3', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemstablet', + 'label' => $this->l('Items_Tablet'), + 'desc' => $this->l('Typing number of items ( with Screen < 768 )'), + 'default' => '2', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemsmobile', + 'label' => $this->l('Items_Mobile'), + 'desc' => $this->l('Typing number of items ( with Screen < 576 )'), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemscustom', + 'label' => $this->l('Items_Custom'), + 'desc' => $this->l('(Advance User) Example: [[0, 2], [576, 3], [768, 4], [992, 5], [1200, 6]]. The format is [x,y] whereby x=browser width and y=number of slides displayed'), + 'default' => '', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itempercolumn', + 'label' => $this->l('Items per Column'), + 'desc' => $this->l('Number of item per one column. Same with number of line for one page'), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Effect').'
    ', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Autoplay'), + 'name' => 'autoplay', + 'is_bool' => true, + 'desc' => $this->l('Yes - scroll per page. No - scroll per item. This affect next/prev buttons and mouse/touch dragging.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Stop on Hover'), + 'name' => 'stoponhover', + 'is_bool' => true, + 'desc' => $this->l('Stop autoplay on mouse hover'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Responsive'), + 'name' => 'responsive', + 'is_bool' => true, + 'desc' => $this->l('You can use Owl Carousel on desktop-only websites too! Just change that to "false" to disable resposive capabilities'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Navigation'), + 'name' => 'navigation', + 'is_bool' => true, + 'desc' => $this->l('Display "next" and "prev" buttons.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Auto Height'), + 'name' => 'autoHeight', + 'is_bool' => true, + 'desc' => $this->l('Add height to owl-wrapper-outer so you can use diffrent heights on slides. Use it only for one item per page setting.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Mouse Drag'), + 'name' => 'mouseDrag', + 'is_bool' => true, + 'desc' => $this->l('On DeskTop - Turn off/on mouse events.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Touch Drag'), + 'name' => 'touchdrag', + 'is_bool' => true, + 'desc' => $this->l('On Mobile - Turn off/on touch events.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Lazy Load: This function is only work when have one item per column').'
    ', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Lazy Load'), + 'name' => 'lazyload', + 'values' => ApPageSetting::returnYesNo(), + 'desc' => $this->l('Delays loading of images. Images outside of viewport will not be loaded before user scrolls to them. Great for mobile devices to speed up page loadings'), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Lazy Follow'), + 'name' => 'lazyfollow', + 'is_bool' => true, + 'desc' => $this->l('When pagination used, it skips loading the images from pages that got skipped. It only loads the images that get displayed in viewport. If set to false, all images get loaded when pagination used. It is a sub setting of the lazy load function.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'select', + 'label' => $this->l('Lazy Effect'), + 'name' => 'lazyeffect', + 'options' => array( + 'query' => array( + array('id' => 'fade', 'name' => $this->l('fade')), + array('id' => 'false', 'name' => $this->l('No')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'desc' => $this->l('Default is fadeIn on 400ms speed. Use false to remove that effect.'), + 'default' => 'fade', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Pagination Enable'), + 'name' => 'pagination', + 'is_bool' => true, + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'desc' => $this->l('Show Pagination below owl-carousel.'), + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Pagination Numbers'), + 'name' => 'paginationnumbers', + 'is_bool' => true, + 'desc' => $this->l('Show numbers inside Pagination'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('NEXT PAGE').'
    ', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Scroll per Page'), + 'name' => 'scrollPerPage', + 'is_bool' => true, + 'desc' => $this->l('Yes - scroll per Page. No - scroll per Item. This affect next/prev buttons and mouse/touch dragging.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'label' => $this->l('Scroll Page Speed'), + 'name' => 'paginationspeed', + 'desc' => $this->l('Time to next page. Ex 800 ( Milliseconds )'), + 'default' => '800', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'label' => $this->l('Scroll Item Speed'), + 'name' => 'slidespeed', + 'desc' => $this->l('Time to next item. Ex 200 (Milliseconds)'), + 'default' => '200', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + //Owl Carousel end + //boostrap carousel begin + array( + 'type' => 'text', + 'name' => 'nbitemsperpage', + 'label' => $this->l('Number of Item per Page'), + 'desc' => $this->l('How many product you want to display in a Page. divisible by Item per Line (Desktop, Table, mobile)(default:12)'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + 'default' => '12', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Items per Row').'
    ', + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_Desktop ( >= 1200 )'), + 'name' => 'nbitemsperline_desktop', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + array('id' => '12', 'name' => $this->l('12 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 4'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_SmallDesktop ( >= 992 )'), + 'name' => 'nbitemsperline_smalldesktop', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + array('id' => '12', 'name' => $this->l('12 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 3'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_Tablet ( >= 768 )'), + 'name' => 'nbitemsperline_tablet', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + array('id' => '12', 'name' => $this->l('12 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 3'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_SmallDevices ( >= 576 )'), + 'name' => 'nbitemsperline_smalldevices', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 2'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_ExtraSmallDevices ( >= 480 )'), + 'name' => 'nbitemsperline_extrasmalldevices', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 1'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_Smartphone ( < 480 )'), + 'name' => 'nbitemsperline_smartphone', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 1'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'text', + 'name' => 'interval', + 'label' => $this->l('interval'), + 'desc' => $this->l('The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle.'), + 'default' => '5000', + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + + //Slick carousel start + array( + 'type' => 'select', + 'label' => $this->l('Vertical'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'name' => 'slick_vertical', + 'options' => array( + 'query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => '0' + ), + array( + 'type' => 'select', + 'name' => 'slick_autoplay', + 'label' => $this->l('Auto play'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'options' => array('query' => array( + array('id' => '1', 'name' => $this->l('Yes')), + array('id' => '0', 'name' => $this->l('No')), + ), + 'id' => 'id', + 'name' => 'name') + ), + array( + 'type' => 'select', + 'name' => 'slick_pauseonhover', + 'label' => $this->l('Pause on Hover'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'options' => array('query' => array( + array('id' => '1', 'name' => $this->l('Yes')), + array('id' => '0', 'name' => $this->l('No')), + ), + 'id' => 'id', + 'name' => 'name') + ), + array( + 'type' => 'select', + 'name' => 'slick_loopinfinite', + 'label' => $this->l('Loop Infinite'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '0', + 'options' => array('query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'name' => 'slick_arrows', + 'label' => $this->l('Prev/Next Arrows'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'options' => array('query' => array( + array('id' => '1', 'name' => $this->l('Yes')), + array('id' => '0', 'name' => $this->l('No')), + ), + 'id' => 'id', + 'name' => 'name') + ), + array( + 'type' => 'select', + 'name' => 'slick_dot', + 'label' => $this->l('Show dot indicators'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '0', + 'options' => array('query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name') + ), + array( + 'type' => 'select', + 'name' => 'slick_centermode', + // 'class' => 'form-action', + 'label' => $this->l('Center mode'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '0', + 'options' => array('query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name') + ), + array( + 'type' => 'text', + 'name' => 'slick_centerpadding', + 'label' => $this->l('Center padding'), + 'desc' => $this->l('Only for center mode. Unit is px (pixel). Default: 60(px)'), + 'default' => '60', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + array( + 'type' => 'text', + 'name' => 'slick_row', + 'label' => $this->l('Num Row'), + 'desc' => $this->l('Show number row display. Ex 1 or 1,2,3,4 '), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + array( + 'type' => 'text', + 'name' => 'slick_slidestoshow', + 'label' => $this->l('Slides To Show'), + 'desc' => $this->l('Show number row display. Ex 1 or 1,2,3,4 '), + 'default' => '5', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + array( + 'type' => 'text', + 'name' => 'slick_slidestoscroll', + 'label' => $this->l('Slides To Scroll'), + 'desc' => $this->l('Show number row display. Ex 1 or 1,2,3,4 '), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + array( + 'type' => 'text', + 'name' => 'slick_items_custom', + 'label' => $this->l('Display for other screen'), + 'desc' => $this->l('(Advance User) Example: [[1200, 6],[992, 5],[768, 4], [576, 3],[480, 2]]. The format is [x,y] whereby x=browser width and y=number of slides displayed'), + 'default' => '[[1200, 6],[992, 5],[768, 4], [576, 3],[480, 2]]', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + + array( + 'type' => 'select', + 'name' => 'slick_custom_status', + // 'class' => 'form-action', + 'label' => $this->l('Enable custom js slick'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l('Only for developers and advanced users. Goto http://kenwheeler.github.io/slick/ for option'), + 'options' => array('query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name'), + 'default' => '0' + ), + array( + 'type' => 'textarea', + 'name' => 'slick_custom', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'label' => $this->l('Custom js Slick'), + 'values' => '', + 'autoload_rte' => false, + 'default' => '{ + dots: true, + infinite: false, + speed: 300, + slidesToShow: 4, + slidesToScroll: 4, + responsive: [ + { + breakpoint: 1024, + settings: { + slidesToShow: 3, + slidesToScroll: 3, + infinite: true, + dots: true + } + }, + { + breakpoint: 600, + settings: { + slidesToShow: 2, + slidesToScroll: 2 + } + }, + { + breakpoint: 480, + settings: { + slidesToShow: 1, + slidesToScroll: 1 + } + } + ] +}', + // 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + + //Slick carousel end + + + ); + return $input; + } + + public function endRenderForm() + { + // KEEP OLD DATA + if (Tools::getIsset('nbitemsperline') && Tools::getValue('nbitemsperline')) { + $this->helper->tpl_vars['fields_value']['nbitemsperline_desktop'] = Tools::getValue('nbitemsperline'); + $this->helper->tpl_vars['fields_value']['nbitemsperline_smalldesktop'] = Tools::getValue('nbitemsperline'); + $this->helper->tpl_vars['fields_value']['nbitemsperline_tablet'] = Tools::getValue('nbitemsperline'); + } + + if (Tools::getIsset('nbitemsperlinetablet') && Tools::getValue('nbitemsperlinetablet')) { + $this->helper->tpl_vars['fields_value']['nbitemsperline_smalldevices'] = Tools::getValue('nbitemsperlinetablet'); + } + + if (Tools::getIsset('nbitemsperlinemobile') && Tools::getValue('nbitemsperlinemobile')) { + $this->helper->tpl_vars['fields_value']['nbitemsperline_extrasmalldevices'] = Tools::getValue('nbitemsperlinemobile'); + $this->helper->tpl_vars['fields_value']['nbitemsperline_smartphone'] = Tools::getValue('nbitemsperlinemobile'); + } + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + if (isset($assign['formAtts']['carousel_type']) && $assign['formAtts']['carousel_type'] == 'owlcarousel') { + if (!Configuration::get('APPAGEBUILDER_LOAD_OWL')) { + $assign['formAtts']['lib_has_error'] = true; + $assign['formAtts']['lib_error'] = 'Can not show ManuFacturer Carousel. Please enable Owl Carousel library in Appagebuilder Configuration.'; + return $assign; + } + } + if (isset($assign['formAtts']['value_by_manufacture']) && $assign['formAtts']['value_by_manufacture'] == '0') { + require_once(_PS_MODULE_DIR_.'appagebuilder/libs/LeoProcessData.php'); + $assign['manuselect'] = LeoProcessData::getManufacturersSelect($assign['formAtts']); + } else { + // validate module + $assign['manuselect'] = Manufacturer::getManufacturers(false, 0, true, 1, (int)$assign['formAtts']['manu_limit'], false, true); + } + $assign['manufacturers'] = $assign['manuselect']; + $assign['image_type'] = ($assign['formAtts']['imagetype']) ? ($assign['formAtts']['imagetype']) : ApPageSetting::getDefaultNameImage('small'); + $assign['carouselName'] = 'carousel-'.ApPageSetting::getRandomNumber(); + if ($assign['formAtts']['carousel_type'] == 'boostrap') { + if (isset($assign['formAtts']['nbitemsperline']) && $assign['formAtts']['nbitemsperline']) { + $assign['formAtts']['nbitemsperline_desktop'] = $assign['formAtts']['nbitemsperline']; + $assign['formAtts']['nbitemsperline_smalldesktop'] = $assign['formAtts']['nbitemsperline']; + $assign['formAtts']['nbitemsperline_tablet'] = $assign['formAtts']['nbitemsperline']; + } + if (isset($assign['formAtts']['nbitemsperlinetablet']) && $assign['formAtts']['nbitemsperlinetablet']) { + $assign['formAtts']['nbitemsperline_smalldevices'] = $assign['formAtts']['nbitemsperlinetablet']; + } + if (isset($assign['formAtts']['nbitemsperlinemobile']) && $assign['formAtts']['nbitemsperlinemobile']) { + $assign['formAtts']['nbitemsperline_extrasmalldevices'] = $assign['formAtts']['nbitemsperlinemobile']; + $assign['formAtts']['nbitemsperline_smartphone'] = $assign['formAtts']['nbitemsperlinemobile']; + } + + $assign['formAtts']['nbitemsperline_desktop'] = isset($assign['formAtts']['nbitemsperline_desktop']) && $assign['formAtts']['nbitemsperline_desktop'] ? (int)$assign['formAtts']['nbitemsperline_desktop'] : 4; + $assign['formAtts']['nbitemsperline_smalldesktop'] = isset($assign['formAtts']['nbitemsperline_smalldesktop']) && $assign['formAtts']['nbitemsperline_smalldesktop'] ? (int)$assign['formAtts']['nbitemsperline_smalldesktop'] : 4; + $assign['formAtts']['nbitemsperline_tablet'] = isset($assign['formAtts']['nbitemsperline_tablet']) && $assign['formAtts']['nbitemsperline_tablet'] ? (int)$assign['formAtts']['nbitemsperline_tablet'] : 3; + $assign['formAtts']['nbitemsperline_smalldevices'] = isset($assign['formAtts']['nbitemsperline_smalldevices']) && $assign['formAtts']['nbitemsperline_smalldevices'] ? (int)$assign['formAtts']['nbitemsperline_smalldevices'] : 2; + $assign['formAtts']['nbitemsperline_extrasmalldevices'] = isset($assign['formAtts']['nbitemsperline_extrasmalldevices']) && $assign['formAtts']['nbitemsperline_extrasmalldevices'] ? (int)$assign['formAtts']['nbitemsperline_extrasmalldevices'] : 1; + $assign['formAtts']['nbitemsperline_smartphone'] = isset($assign['formAtts']['nbitemsperline_smartphone']) && $assign['formAtts']['nbitemsperline_smartphone'] ? (int)$assign['formAtts']['nbitemsperline_smartphone'] : 1; + + $assign['tabname'] = 'carousel-'.ApPageSetting::getRandomNumber(); + $assign['itemsperpage'] = (int)$assign['formAtts']['nbitemsperpage']; + $assign['nbItemsPerLine'] = (int)$assign['formAtts']['nbitemsperline_desktop']; + + $assign['scolumn'] = ''; + + if ($assign['formAtts']['nbitemsperline_desktop'] == '5') { + $assign['scolumn'] .= ' col-xl-2-4'; + } else { + $assign['scolumn'] .= ' col-xl-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_desktop'])); + } + + if ($assign['formAtts']['nbitemsperline_smalldesktop'] == '5') { + $assign['scolumn'] .= ' col-lg-2-4'; + } else { + $assign['scolumn'] .= ' col-lg-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_smalldesktop'])); + } + + if ($assign['formAtts']['nbitemsperline_tablet'] == '5') { + $assign['scolumn'] .= ' col-md-2-4'; + } else { + $assign['scolumn'] .= ' col-md-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_tablet'])); + } + + if ($assign['formAtts']['nbitemsperline_smalldevices'] == '5') { + $assign['scolumn'] .= ' col-sm-2-4'; + } else { + $assign['scolumn'] .= ' col-sm-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_smalldevices'])); + } + + if ($assign['formAtts']['nbitemsperline_extrasmalldevices'] == '5') { + $assign['scolumn'] .= ' col-xs-2-4'; + } else { + $assign['scolumn'] .= ' col-xs-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_extrasmalldevices'])); + } + + if ($assign['formAtts']['nbitemsperline_smartphone'] == '5') { + $assign['scolumn'] .= ' col-sp-2-4'; + } else { + $assign['scolumn'] .= ' col-sp-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_smartphone'])); + } + } + //DONGND:: create data for owl carousel with item custom + if ($assign['formAtts']['carousel_type'] == 'owlcarousel') { + //DONGND:: build data for fake item loading + $assign['formAtts']['number_fake_item'] = $assign['formAtts']['items']; + $array_fake_item = array(); + $array_fake_item['m'] = $assign['formAtts']['itemsmobile']; + $array_fake_item['sm'] = $assign['formAtts']['itemstablet']; + $array_fake_item['md'] = $assign['formAtts']['itemsdesktopsmall']; + $array_fake_item['lg'] = $assign['formAtts']['itemsdesktop']; + $array_fake_item['xl'] = $assign['formAtts']['items']; + $assign['formAtts']['array_fake_item'] = $array_fake_item; + + if (isset($assign['formAtts']['itemscustom']) && $assign['formAtts']['itemscustom'] != '') { + $array_item_custom = Tools::jsonDecode($assign['formAtts']['itemscustom']); + $array_item_custom_tmp = array(); + $array_number_item = array(); + foreach ($array_item_custom as $array_item_custom_val) { + $size_window = $array_item_custom_val[0]; + $number_item = $array_item_custom_val[1]; + if (0 <= $size_window && $size_window < 576) { + $array_item_custom_tmp['m'] = $number_item; + } else if (576 <= $size_window && $size_window < 768) { + $array_item_custom_tmp['sm'] = $number_item; + } else if (768 <= $size_window && $size_window < 992) { + $array_item_custom_tmp['md'] = $number_item; + } else if (992 <= $size_window && $size_window < 1200) { + $array_item_custom_tmp['lg'] = $number_item; + } else if ($size_window >= 1200) { + $array_item_custom_tmp['xl'] = $number_item; + } + $array_item_custom_tmp[$size_window] = $number_item; + $array_number_item[] = $number_item; + }; + $assign['formAtts']['array_fake_item'] = array_merge($array_fake_item, $array_item_custom_tmp); + + if (max($array_number_item) > $assign['formAtts']['items']) { + $assign['formAtts']['number_fake_item'] = max($array_number_item); + } + } + } + if ($assign['formAtts']['carousel_type'] == 'slickcarousel') { + if (isset($assign['formAtts']['slick_items_custom'])) { + $assign['formAtts']['slick_items_custom'] = str_replace($this->str_search, $this->str_relace, $assign['formAtts']['slick_items_custom']); + } + if (isset($assign['formAtts']['slick_custom'])) { + $str_relace = array('&', '\"', '\'', '', '', '', '[', ']'); + $assign['formAtts']['slick_custom'] = str_replace($this->str_search, $str_relace, $assign['formAtts']['slick_custom']); + } + if (isset($assign['formAtts']['slick_items_custom'])) { + $assign['formAtts']['slick_items_custom'] = Tools::jsonDecode($assign['formAtts']['slick_items_custom']); + } + + //DONGND:: build data for fake item loading + $assign['formAtts']['number_fake_item'] = $assign['formAtts']['slick_slidestoshow']*$assign['formAtts']['slick_row']; + + if (isset($assign['formAtts']['slick_items_custom']) && $assign['formAtts']['slick_items_custom'] != '') { + $array_item_custom = $assign['formAtts']['slick_items_custom']; + $array_item_custom_tmp = array(); + $array_number_item = array(); + foreach ($array_item_custom as $array_item_custom_val) { + $size_window = $array_item_custom_val[0]; + $number_item = $array_item_custom_val[1]; + if (0 <= $size_window && $size_window < 576) { + $array_item_custom_tmp['m'] = $number_item; + } else if (576 <= $size_window && $size_window < 768) { + $array_item_custom_tmp['sm'] = $number_item; + } else if (768 <= $size_window && $size_window < 992) { + $array_item_custom_tmp['md'] = $number_item; + } else if (992 <= $size_window && $size_window < 1200) { + $array_item_custom_tmp['lg'] = $number_item; + } else if ($size_window >= 1200) { + $array_item_custom_tmp['xl'] = $assign['formAtts']['slick_slidestoshow']; + } + $number_item = $number_item*$assign['formAtts']['slick_row']; + $array_item_custom_tmp[$size_window] = $number_item; + $array_number_item[] = $number_item; + }; + $assign['formAtts']['array_fake_item'] = $array_item_custom_tmp; + + if (max($array_number_item) > $assign['formAtts']['slick_slidestoshow']) { + $assign['formAtts']['number_fake_item'] = max($array_number_item); + } + } + } + return $assign; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApMegamenu.php b/modules/appagebuilder/classes/shortcodes/ApMegamenu.php new file mode 100644 index 00000000..6e42df24 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApMegamenu.php @@ -0,0 +1,147 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApMegamenu extends ApShortCodeBase +{ + public $name = 'ApMegamenu'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Megamenu Module'), 'position' => 3, 'desc' => $this->l('You can get group from leobootstrapmenu module'), + 'icon_class' => 'icon icon-chevron-right', 'tag' => 'content'); + } + + public function getConfigList() + { + if (Module::isInstalled('leobootstrapmenu') && Module::isEnabled('leobootstrapmenu')) { + include_once(_PS_MODULE_DIR_.'leobootstrapmenu/leobootstrapmenu.php'); + $module = new Leobootstrapmenu(); + $list = $module->getGroups(); + // $controller = 'AdminModules'; +// $id_lang = Context::getContext()->language->id; + // $params = array('token' => Tools::getAdminTokenLite($controller), + // 'configure' => 'Leobootstrapmenu', + // 'tab_module' => 'front_office_features', + // 'module_name' => 'Leobootstrapmenu'); + //$url = dirname($_SERVER['PHP_SELF']).'/'.Dispatcher::getInstance()->createUrl($controller, $id_lang, $params, false); + $url = Context::getContext()->link->getAdminLink('AdminLeoBootstrapMenuModule'); + if ($list && count($list) > 0) { + $inputs = array( + array( + 'type' => 'select', + 'label' => $this->l('Select a group for megamenu'), + 'name' => 'megamenu_group', + 'options' => array( + 'query' => $this->getListGroup($list), + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'value_by_categories', + 'default' => 'all' + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '' + ) + ); + } else { + // Go to page setting of the module LeoSlideShow + $inputs = array( + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '. + $this->l('There is no group in Leobootstrapmenu Module.'). + '

    ' + ) + ); + } + } else { + $inputs = array( + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '. + $this->l('"Leobootstrapmenu" Module must be installed and enabled before using.'). + '

    You can take this module at leo-theme or apollo-theme

    ' + ) + ); + } + return $inputs; + } + + public function getListGroup($list) + { + $result = array(); + foreach ($list as $item) { + $status = ' (ID: '.$item['id_btmegamenu_group'].' - '.($item['active'] ? $this->l('Active') : $this->l('Deactive')).')'; + $result[] = array('id' => $item['randkey'], 'name' => $item['title'].$status); + } + return $result; + } + + public function prepareFontContent($assign, $module = null) + { + if (Module::isInstalled('leobootstrapmenu') && Module::isEnabled('leobootstrapmenu')) { + $id_shop = (int)Context::getContext()->shop->id; + $assign['formAtts']['isEnabled'] = true; + include_once(_PS_MODULE_DIR_.'leobootstrapmenu/leobootstrapmenu.php'); + $module = new Leobootstrapmenu(); + $link_array = explode(',', $assign['formAtts']['megamenu_group']); + if ($link_array && !is_numeric($link_array['0'])) { + $randkey_group = ''; + foreach ($link_array as $val) { + // validate module + $randkey_group .= ($randkey_group == '') ? "'".pSQL($val)."'" : ",'".pSQL($val)."'"; + } + + $where = ' WHERE randkey IN ('.$randkey_group.') AND id_shop = ' . (int)$id_shop; + $sql = 'SELECT id_btmegamenu_group FROM `'._DB_PREFIX_.'btmegamenu_group` '.$where; + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); + + if (is_array($result) && empty($result)) { + $assign['formAtts']['isEnabled'] = false; + $assign['formAtts']['lib_has_error'] = true; + $assign['formAtts']['lib_error'] = 'Can not show LeoBootstrapMenu via Appagebuilder. Please check that The Group of LeoBootstrapMenu is exist.'; + return $assign; + } + + $where = ''; + foreach ($result as $blog) { + // validate module + $where .= ($where == '') ? $blog['id_btmegamenu_group'] : ','.$blog['id_btmegamenu_group']; + } + $assign['formAtts']['megamenu_group'] = $where; + } + $form_id = explode("_", $assign['formAtts']['form_id']); + $assign['content_megamenu'] = $module->processHookCallBack($assign['formAtts']['megamenu_group'], $form_id[1]); + } else { + // validate module + $assign['formAtts']['isEnabled'] = false; + $assign['formAtts']['lib_has_error'] = true; + $assign['formAtts']['lib_error'] = 'Can not show LeoBootstrapMenu via Appagebuilder. Please enable LeoBootstrapMenu module.'; + } + return $assign; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApModule.php b/modules/appagebuilder/classes/shortcodes/ApModule.php new file mode 100644 index 00000000..b2b5f8d6 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApModule.php @@ -0,0 +1,241 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +use PrestaShop\PrestaShop\Core\Module\WidgetInterface; + +class ApModule extends ApShortCodeBase +{ + public $name = 'ApModule'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Module'), + 'position' => 5, + 'desc' => $this->l('Custom moule'), + 'icon_class' => 'icon-copy', + 'tag' => 'module'); + } + + public function getConfigList() + { + if (Tools::getIsset('edit')) { + $name_module = Tools::getValue('name_module'); + } else { + $name_module = Tools::getValue('type_shortcode'); + } + if (!$name_module) { + return array(); + } + + $module_WidgetInterface = false; + # GET HOOK + if (($module_instance = Module::getInstanceByName($name_module))) { + if ($module_instance instanceof WidgetInterface) { + # module has method function renderWidget() + $module_WidgetInterface = true; + $hooks = ApPageSetting::getOverrideHook(); + $arr = array( + array( + 'id' => '', + 'name' => $this->l('--------- Select a Hook ---------') + ) + ); + foreach ($hooks as $hook) { + $arr[] = array( + 'id' => $hook, + 'name' => $hook, + ); + } + } + } + + # GET HOOK + if ($module_WidgetInterface == false) { + // Get list hook by id (this source code was coped from AdminApPageBuilderShortcodesController) + $hook_assign = array('rightcolumn', 'leftcolumn', 'home', 'top', 'footer'); + $module_instance = ModuleCore::getInstanceByName($name_module); + $hooks = array(); + $result = array(); + foreach ($hook_assign as $hook) { + $retro_hook_name = Hook::getRetroHookName($hook); + if (is_callable(array($module_instance, 'hook'.$hook)) || is_callable(array($module_instance, 'hook'.$retro_hook_name))) { + $hooks[] = $retro_hook_name; + } + } + if ($hooks) { + $randkey_hook = ''; + foreach ($hooks as $val) { + // validate module + $randkey_hook .= ($randkey_hook == '') ? "'".pSQL($val)."'" : ",'".pSQL($val)."'"; + } + + $result = Db::getInstance()->ExecuteS(' + SELECT `id_hook`, `name` FROM `'._DB_PREFIX_.'hook` + WHERE `name` IN ('.$randkey_hook.')'); + } + $arr = array(array('id' => '', 'name' => $this->l('--------- Select a Hook ---------'))); + $len = count($result); + if ($result && $len > 0) { + for ($i = 0; $i < $len; $i++) { + $arr[] = array('id' => $result[$i]['name'], 'name' => $result[$i]['name']); + } + } + } + + + $inputs = array( + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    Module name: "'.$name_module + .'" + +
    ', + ), + array( + 'type' => 'select', + 'id' => 'select-hook', + 'label' => $this->l('Select hook of module (*)'), + 'name' => 'hook', + 'options' => array('query' => $arr, + 'id' => 'id', + 'name' => 'name' + ) + ), + array( + 'type' => 'switch', + 'label' => $this->l('Remove display'), + 'desc' => $this->l('This module will remove in this hook'), + 'name' => 'is_display', + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Please consider using this function. + This function is only for advance user, + It will load other module and display in column of Appagebuilder. + With some module have ID in wrapper DIV, your site will have Javascript Conflicts. + We will not support this error.').'
    ', + ) + ); + return $inputs; + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + $form_attr = $assign['formAtts']; + $context = Context::getContext(); + if (isset($form_attr['hook']) && isset($form_attr['name_module']) && Module::isEnabled($form_attr['name_module'])) { + $assign['apContent'] = $this->execModuleHook($form_attr['hook'], array(), $form_attr['name_module'], false, $context->shop->id); + } + return $assign; + } + + public static function execModuleHook($hook_name = null, $hook_args = array(), $module_name = null, $use_push = false, $id_shop = null) + { + static $disable_non_native_modules = null; + if ($disable_non_native_modules === null) { + $disable_non_native_modules = (bool)Configuration::get('PS_DISABLE_NON_NATIVE_MODULE'); + } + // Check arguments validity + if (!Validate::isModuleName($module_name) || !Validate::isHookName($hook_name)) { + return ''; + } + //throw new PrestaShopException('Invalid module name or hook name'); + // If no modules associated to hook_name or recompatible hook name, we stop the function + if (!Hook::getHookModuleExecList($hook_name)) { + return ''; + } + // Check if hook exists + if (!$id_hook = Hook::getIdByName($hook_name)) { + return false; + } + // Store list of executed hooks on this page + Hook::$executed_hooks[$id_hook] = $hook_name; + $context = Context::getContext(); + if (!isset($hook_args['cookie']) || !$hook_args['cookie']) { + $hook_args['cookie'] = $context->cookie; + } + if (!isset($hook_args['cart']) || !$hook_args['cart']) { + $hook_args['cart'] = $context->cart; + } + $retro_hook_name = Hook::getRetroHookName($hook_name); + // Look on modules list + $altern = 0; + $output = ''; + if ($disable_non_native_modules && !isset(Hook::$native_module)) { + Hook::$native_module = Module::getNativeModuleList(); + } + $different_shop = false; + if ($id_shop !== null && Validate::isUnsignedId($id_shop) && $id_shop != $context->shop->getContextShopID()) { + $old_context = $context->shop->getContext(); + $old_shop = clone $context->shop; + $shop = new Shop((int)$id_shop); + if (Validate::isLoadedObject($shop)) { + $context->shop = $shop; + $context->shop->setContext(Shop::CONTEXT_SHOP, $shop->id); + $different_shop = true; + } + } + // Check errors + if ((bool)$disable_non_native_modules && Hook::$native_module && count(Hook::$native_module) && !in_array($module_name, self::$native_module)) { + return; + } + if (!($module_instance = Module::getInstanceByName($module_name))) { + return; + } + if ($use_push && !$module_instance->allow_push) { + return; + } + // Check which / if method is callable + $hook_callable = is_callable(array($module_instance, 'hook'.$hook_name)); + $hook_retro_callable = is_callable(array($module_instance, 'hook'.$retro_hook_name)); + if (($hook_callable || $hook_retro_callable)) { + $hook_args['altern'] = ++$altern; + if ($use_push && isset($module_instance->push_filename) && file_exists($module_instance->push_filename)) { + Tools::waitUntilFileIsModified($module_instance->push_filename, $module_instance->push_time_limit); + } + if ($hook_callable) { + // Call hook method + $display = $module_instance->{'hook'.$hook_name}($hook_args); + } elseif ($hook_retro_callable) { + $display = $module_instance->{'hook'.$retro_hook_name}($hook_args); + } + $output .= $display; + } elseif (Hook::isDisplayHookName($hook_name)) { + if ($module_instance instanceof WidgetInterface) { + $display = Hook::coreRenderWidget($module_instance, $hook_name, $hook_args); + + $output .= $display; + } + } + + if ($different_shop) { + $context->shop = $old_shop; + $context->shop->setContext($old_context, $shop->id); + } + return $output; // Return html string + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApProductCarousel.php b/modules/appagebuilder/classes/shortcodes/ApProductCarousel.php new file mode 100644 index 00000000..596be75e --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApProductCarousel.php @@ -0,0 +1,1168 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +use PrestaShop\PrestaShop\Adapter\Image\ImageRetriever; +use PrestaShop\PrestaShop\Adapter\Product\PriceFormatter; +use PrestaShop\PrestaShop\Core\Product\ProductListingPresenter; +use PrestaShop\PrestaShop\Adapter\Product\ProductColorsRetriever; + +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageBuilderProductsModel.php'); + +class ApProductCarousel extends ApShortCodeBase +{ + public $name = 'ApProductCarousel'; + + public function getInfo() + { + return array('label' => $this->l('Product Carousel'), 'position' => 3, + 'desc' => $this->l('You can select product from category'), + 'icon_class' => 'icon icon-chevron-right', + 'tag' => 'content slider'); + } + + public function getAdditionConfig() + { + return array( + array( + 'type' => '', + 'name' => 'value_by_categories', + 'default' => '0' + ), + array( + 'type' => '', + 'name' => 'value_by_product_type', + 'default' => '0' + ), + array( + 'type' => '', + 'name' => 'value_by_manufacture', + 'default' => '0' + ), + array( + 'type' => '', + 'name' => 'value_by_supplier', + 'default' => '0' + ), + array( + 'type' => '', + 'name' => 'value_by_product_id', + 'default' => '0' + ), + array( + 'type' => '', + 'name' => 'value_by_tags', + 'default' => '0' + ) + ); + } + + public function getConfigList() + { + $selected_categories = array(); + if (Tools::getIsset('categorybox')) { + $category_box = Tools::getValue('categorybox'); + $selected_categories = explode(',', $category_box); + } + //get all manufacture + $manufacturers = Manufacturer::getManufacturers(false, 0, true, false, false, false, true); + $suppliers = Supplier::getSuppliers(); + $profile = new ApPageBuilderProductsModel(); + $profile_list = $profile->getAllProductProfileByShop(); + $product_active = ApPageBuilderProductsModel::getActive(); + $product_class = $product_active['class']; + $data_class = array(array('plist_key' => 'default', 'class' => $product_class)); + foreach ($profile_list as $item) { + $data_class[] = array('plist_key' => $item['plist_key'], 'class' => $item['class']); + } + $script = ''; + array_unshift($profile_list, array('plist_key' => 'default', 'name' => $this->l('Use Default'))); + $id_root_category = Context::getContext()->shop->getCategory(); + $input = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => '' + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => $script.'
    '.$this->l('Step 1: Product Filter').'
    ', + ), + array( + 'type' => 'checkbox', + 'name' => 'value_by', + 'label' => $this->l('Select By'), + 'class' => 'checkbox-group', + 'desc' => $this->l('Select Product Condition'), + 'values' => array( + 'query' => array( + array( + 'id' => 'categories', + 'name' => $this->l('Categories'), + 'val' => '1' + ), + array( + 'id' => 'product_type', + 'name' => $this->l('Product Type'), + 'val' => '1' + ), + array( + 'id' => 'manufacture', + 'name' => $this->l('Manufacture'), + 'val' => '1' + ), + array( + 'id' => 'supplier', + 'name' => $this->l('Supplier'), + 'val' => '1' + ), + array( + 'id' => 'product_id', + 'name' => $this->l('Product Ids'), + 'val' => '1' + ), + ), + 'id' => 'id', + 'name' => 'name' + ) + ), + array( + 'type' => 'categories', + 'label' => $this->l('Select Category'), + 'name' => 'categorybox', + 'desc' => $this->l('You can select one or more, if not select we will not search by category'), + 'tree' => array( + 'root_category' => $id_root_category, + 'use_search' => false, + 'id' => 'categorybox', + 'use_checkbox' => true, + 'selected_categories' => $selected_categories, + ), + 'form_group_class' => 'value_by_categories', + ), + array( + 'type' => 'select', + 'label' => $this->l('Product of Category'), + 'name' => 'category_type', + 'options' => array( + 'query' => array( + array('id' => 'all', 'name' => $this->l('Get All Product of Category')), + array('id' => 'default', 'name' => $this->l('Get Product if category is default category of product'))), + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'value_by_categories', + 'default' => 'all' + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'value_by_categories', + ), + array( + 'type' => 'select', + 'label' => $this->l('Product Type'), + 'name' => 'product_type', + 'options' => array( + 'query' => array( + array( + 'id' => 'all', + 'name' => $this->l('All Product'), + ), + array( + 'id' => 'new_product', + 'name' => $this->l('New Product'), + ), + array( + 'id' => 'best_sellers', + 'name' => $this->l('Best sellers'), + ), + array( + 'id' => 'price_drop', + 'name' => $this->l('Special'), + ), + array( + 'id' => 'home_featured', + 'name' => $this->l('Home Featured'), + ) + ), + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'value_by_product_type', + 'default' => 'all', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'value_by_product_type', + ), + array( + 'type' => 'select', + 'label' => $this->l('Manufacture'), + 'name' => 'manufacture[]', + 'multiple' => true, + 'options' => array( + 'query' => $manufacturers, + 'id' => 'id_manufacturer', + 'name' => 'name' + ), + 'form_group_class' => 'aprow_exceptions', + 'default' => 'all', + 'form_group_class' => 'value_by_manufacture', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'value_by_manufacture', + ), + array( + 'type' => 'select', + 'label' => $this->l('Supplier'), + 'name' => 'supplier[]', + 'multiple' => true, + 'options' => array( + 'query' => $suppliers, + 'id' => 'id_supplier', + 'name' => 'name' + ), + 'form_group_class' => 'value_by_supplier', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'value_by_supplier', + ), + array( + 'type' => 'text', + 'name' => 'product_id', + 'label' => $this->l('Product Ids'), + 'desc' => $this->l('Show product follow product id. Ex 1 or 1,2,3,4 '), + 'default' => '', + 'form_group_class' => 'value_by_product_id', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'value_by_product_id', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Step 2: Product Order And Limit').'
    ', + ), + array( + 'type' => 'select', + 'label' => $this->l('Order Way'), + 'class' => 'form-action', + 'name' => 'order_way', + 'options' => array( + 'query' => array( + array('id' => 'asc', 'name' => $this->l('Asc')), + array('id' => 'desc', 'name' => $this->l('Desc')), + array('id' => 'random', 'name' => $this->l('Random'))), // remove to increase speed + 'id' => 'id', + 'name' => 'name' + ), + 'default' => 'all' + ), + array( + 'type' => 'select', + 'label' => $this->l('Order By'), + 'name' => 'order_by', + 'options' => array( + 'query' => ApPageSetting::getOrderBy(), + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'order_type_sub order_type-asc order_type-desc', + 'default' => 'all' + ), + array( + 'type' => 'text', + 'name' => 'nb_products', + 'label' => $this->l('Limit'), + 'default' => '10', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Step 3: Carousel Setting').'
    ', + ), + array( + 'type' => 'select', + 'label' => $this->l('Carousel Type'), + 'class' => 'form-action', + 'name' => 'carousel_type', + 'options' => array( + 'query' => array( + array('id' => 'boostrap', 'name' => $this->l('Bootstrap')), + array('id' => 'owlcarousel', 'name' => $this->l('Owl Carousel')), + array('id' => 'slickcarousel', 'name' => $this->l('Slick Carousel')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => 'boostrap' + ), + //Owl Carousel begin + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Items per Row').'
    ', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'items', + 'label' => $this->l('Items'), + 'desc' => $this->l('Typing number of items. Default'), + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + 'default' => '5', + ), + array( + 'type' => 'text', + 'name' => 'itemsdesktop', + 'label' => $this->l('Items_Desktop'), + 'desc' => $this->l('Typing number of items ( with Screen < 1200 )'), + 'default' => '4', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemsdesktopsmall', + 'label' => $this->l('Items_Desktop_Small'), + 'desc' => $this->l('Typing number of items ( with Screen < 992 )'), + 'default' => '3', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemstablet', + 'label' => $this->l('Items_Tablet'), + 'desc' => $this->l('Typing number of items ( with Screen < 768 )'), + 'default' => '2', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemsmobile', + 'label' => $this->l('Items_Mobile'), + 'desc' => $this->l('Typing number of items ( with Screen < 576 )'), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itemscustom', + 'label' => $this->l('Items_Custom'), + 'desc' => $this->l('(Advance User) Example: [[0, 2], [576, 3], [768, 4], [992, 5], [1200, 6]]. The format is [x,y] whereby x=browser width and y=number of slides displayed'), + 'default' => '', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'name' => 'itempercolumn', + 'label' => $this->l('Items per Column'), + 'desc' => $this->l('Number of item per one column. Same with number of line for one page'), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Effect').'
    ', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Autoplay'), + 'name' => 'autoplay', + 'is_bool' => true, + 'desc' => $this->l('Yes - scroll per page. No - scroll per item. This affect next/prev buttons and mouse/touch dragging.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Stop on Hover'), + 'name' => 'stoponhover', + 'is_bool' => true, + 'desc' => $this->l('Stop autoplay on mouse hover'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Responsive'), + 'name' => 'responsive', + 'is_bool' => true, + 'desc' => $this->l('You can use Owl Carousel on desktop-only websites too! Just change that to "false" to disable resposive capabilities'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Navigation'), + 'name' => 'navigation', + 'is_bool' => true, + 'desc' => $this->l('Display "next" and "prev" buttons.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Auto Height'), + 'name' => 'autoHeight', + 'is_bool' => true, + 'desc' => $this->l('Add height to owl-wrapper-outer so you can use diffrent heights on slides. Use it only for one item per page setting.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Mouse Drag'), + 'name' => 'mouseDrag', + 'is_bool' => true, + 'desc' => $this->l('On DeskTop - Turn off/on mouse events.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Touch Drag'), + 'name' => 'touchdrag', + 'is_bool' => true, + 'desc' => $this->l('On Mobile - Turn off/on touch events.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Lazy Load: This function is only work when have one item per column').'
    ', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Lazy Load'), + 'name' => 'lazyload', + 'values' => ApPageSetting::returnYesNo(), + 'desc' => $this->l('Delays loading of images. Images outside of viewport will not be loaded before user scrolls to them. Great for mobile devices to speed up page loadings'), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Lazy Follow'), + 'name' => 'lazyfollow', + 'is_bool' => true, + 'desc' => $this->l('When pagination used, it skips loading the images from pages that got skipped. It only loads the images that get displayed in viewport. If set to false, all images get loaded when pagination used. It is a sub setting of the lazy load function.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'select', + 'label' => $this->l('Lazy Effect'), + 'name' => 'lazyeffect', + 'options' => array( + 'query' => array( + array('id' => 'fade', 'name' => $this->l('fade')), + array('id' => 'false', 'name' => $this->l('No')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'desc' => $this->l('Default is fadeIn on 400ms speed. Use false to remove that effect.'), + 'default' => 'fade', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Pagination Enable'), + 'name' => 'pagination', + 'is_bool' => true, + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'desc' => $this->l('Show Pagination below owl-carousel.'), + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Pagination Numbers'), + 'name' => 'paginationnumbers', + 'is_bool' => true, + 'desc' => $this->l('Show numbers inside Pagination'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('NEXT PAGE').'
    ', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Scroll per Page'), + 'name' => 'scrollPerPage', + 'is_bool' => true, + 'desc' => $this->l('Yes - scroll per Page. No - scroll per Item. This affect next/prev buttons and mouse/touch dragging.'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '0', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'label' => $this->l('Scroll Page Speed'), + 'name' => 'paginationspeed', + 'desc' => $this->l('Time to next page. Ex 800 ( Milliseconds )'), + 'default' => '800', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + array( + 'type' => 'text', + 'label' => $this->l('Scroll Item Speed'), + 'name' => 'slidespeed', + 'desc' => $this->l('Time to next item. Ex 200 (Milliseconds)'), + 'default' => '200', + 'form_group_class' => 'carousel_type_sub carousel_type-owlcarousel', + ), + //Owl Carousel end + //boostrap carousel begin + array( + 'type' => 'text', + 'name' => 'nbitemsperpage', + 'label' => $this->l('Number of Item per Page'), + 'desc' => $this->l('How many product you want to display in a Page. Divisible by Item per Line (Desktop, Table, mobile)(default:12)'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + 'default' => '12', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Items per Row').'
    ', + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_Desktop ( >= 1200 )'), + 'name' => 'nbitemsperline_desktop', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + array('id' => '12', 'name' => $this->l('12 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 4'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_SmallDesktop ( >= 992 )'), + 'name' => 'nbitemsperline_smalldesktop', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + array('id' => '12', 'name' => $this->l('12 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 3'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_Tablet ( >= 768 )'), + 'name' => 'nbitemsperline_tablet', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + array('id' => '12', 'name' => $this->l('12 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 3'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_SmallDevices ( >= 576 )'), + 'name' => 'nbitemsperline_smalldevices', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 2'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_ExtraSmallDevices ( >= 480 )'), + 'name' => 'nbitemsperline_extrasmalldevices', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 1'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'select', + 'label' => $this->l('Items_Smartphone ( < 480 )'), + 'name' => 'nbitemsperline_smartphone', + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 item')), + array('id' => '2', 'name' => $this->l('2 items')), + array('id' => '3', 'name' => $this->l('3 items')), + array('id' => '4', 'name' => $this->l('4 items')), + array('id' => '5', 'name' => $this->l('5 items')), + array('id' => '6', 'name' => $this->l('6 items')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many product you want to display in a row of page. Default 1'), + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + array( + 'type' => 'text', + 'name' => 'interval', + 'label' => $this->l('interval'), + 'desc' => $this->l('The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle.'), + 'default' => '5000', + 'form_group_class' => 'carousel_type_sub carousel_type-boostrap carousel_type-desc', + ), + //boostrap carousel end + + //Slick carousel start + array( + 'type' => 'select', + 'label' => $this->l('Vertical'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'name' => 'slick_vertical', + 'options' => array( + 'query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => '0' + ), + array( + 'type' => 'select', + 'name' => 'slick_autoplay', + 'label' => $this->l('Auto play'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '1', + 'options' => array('query' => array( + array('id' => '1', 'name' => $this->l('Yes')), + array('id' => '0', 'name' => $this->l('No')), + ), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'name' => 'slick_pauseonhover', + 'label' => $this->l('Pause on Hover'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '1', + 'options' => array('query' => array( + array('id' => '1', 'name' => $this->l('Yes')), + array('id' => '0', 'name' => $this->l('No')), + ), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'name' => 'slick_loopinfinite', + 'label' => $this->l('Loop Infinite'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '0', + 'options' => array('query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'name' => 'slick_arrows', + 'label' => $this->l('Prev/Next Arrows'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '1', + 'options' => array('query' => array( + array('id' => '1', 'name' => $this->l('Yes')), + array('id' => '0', 'name' => $this->l('No')), + ), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'name' => 'slick_dot', + 'label' => $this->l('Show dot indicators'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '0', + 'options' => array('query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'name' => 'slick_centermode', + // 'class' => 'form-action', + 'label' => $this->l('Center mode'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l(''), + 'default' => '0', + 'options' => array('query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name') + ), + array( + 'type' => 'text', + 'name' => 'slick_centerpadding', + 'label' => $this->l('Center padding'), + 'desc' => $this->l('Only for center mode. Unit is px (pixel). Default: 60(px)'), + 'default' => '60', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + array( + 'type' => 'text', + 'name' => 'slick_row', + 'label' => $this->l('Num Row'), + 'desc' => $this->l('Show number row display. Ex 1 or 1,2,3,4 '), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + array( + 'type' => 'text', + 'name' => 'slick_slidestoshow', + 'label' => $this->l('Slides To Show'), + 'desc' => $this->l('Show number row display. Ex 1 or 1,2,3,4 '), + 'default' => '5', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + array( + 'type' => 'text', + 'name' => 'slick_slidestoscroll', + 'label' => $this->l('Slides To Scroll'), + 'desc' => $this->l('Show number row display. Ex 1 or 1,2,3,4 '), + 'default' => '1', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + array( + 'type' => 'text', + 'name' => 'slick_items_custom', + 'label' => $this->l('Display for other screen'), + 'desc' => $this->l('(Advance User) Example: [[1200, 6],[992, 5],[768, 4], [576, 3],[480, 2]]. The format is [x,y] whereby x=browser width and y=number of slides displayed'), + 'default' => '[[1200, 6],[992, 5],[768, 4], [576, 3],[480, 2]]', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + array( + 'type' => 'select', + 'name' => 'slick_custom_status', + // 'class' => 'form-action', + 'label' => $this->l('Enable custom js slick'), + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'desc' => $this->l('Only for developers and advanced users. Goto http://kenwheeler.github.io/slick/ for option'), + 'options' => array('query' => array( + array('id' => '0', 'name' => $this->l('No')), + array('id' => '1', 'name' => $this->l('Yes')), + ), + 'id' => 'id', + 'name' => 'name', + ), + 'default' => '0', + ), + array( + 'type' => 'textarea', + 'name' => 'slick_custom', + 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + 'label' => $this->l('Custom js Slick'), + 'values' => '', + 'autoload_rte' => false, + 'default' => '{ + dots: true, + infinite: false, + speed: 300, + slidesToShow: 4, + slidesToScroll: 4, + responsive: [ + { + breakpoint: 1024, + settings: { + slidesToShow: 3, + slidesToScroll: 3, + infinite: true, + dots: true + } + }, + { + breakpoint: 600, + settings: { + slidesToShow: 2, + slidesToScroll: 2 + } + }, + { + breakpoint: 480, + settings: { + slidesToShow: 1, + slidesToScroll: 1 + } + } + ] +}', + // 'form_group_class' => 'carousel_type_sub carousel_type-slickcarousel', + ), + + //Slick carousel end + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Step 4: Product Template').'
    ', + ), + array( + 'type' => 'select', + 'label' => $this->l('Product Template'), + 'name' => 'profile', + 'options' => array( + 'query' => $profile_list, + 'id' => 'plist_key', + 'name' => 'name' + ), + 'default' => 'all' + ) + ); + return $input; + } + + public function endRenderForm() + { + // KEEP OLD DATA + if (Tools::getIsset('nbitemsperline') && Tools::getValue('nbitemsperline')) { + $this->helper->tpl_vars['fields_value']['nbitemsperline_desktop'] = Tools::getValue('nbitemsperline'); + $this->helper->tpl_vars['fields_value']['nbitemsperline_smalldesktop'] = Tools::getValue('nbitemsperline'); + $this->helper->tpl_vars['fields_value']['nbitemsperline_tablet'] = Tools::getValue('nbitemsperline'); + } + + if (Tools::getIsset('nbitemsperlinetablet') && Tools::getValue('nbitemsperlinetablet')) { + $this->helper->tpl_vars['fields_value']['nbitemsperline_smalldevices'] = Tools::getValue('nbitemsperlinetablet'); + } + + if (Tools::getIsset('nbitemsperlinemobile') && Tools::getValue('nbitemsperlinemobile')) { + $this->helper->tpl_vars['fields_value']['nbitemsperline_extrasmalldevices'] = Tools::getValue('nbitemsperlinemobile'); + $this->helper->tpl_vars['fields_value']['nbitemsperline_smartphone'] = Tools::getValue('nbitemsperlinemobile'); + } + } + + public function prepareFontContent($assign, $module = null) + { + if (isset($assign['formAtts']['carousel_type']) && $assign['formAtts']['carousel_type'] == 'owlcarousel') { + if (!Configuration::get('APPAGEBUILDER_LOAD_OWL')) { + $assign['formAtts']['lib_has_error'] = true; + $assign['formAtts']['lib_error'] = 'Can not show Product Carousel. Please enable Owl Carousel library in Appagebuilder Configuration.'; + return $assign; + } + } + $assign['products'] = $products = $module->getProductsFont($assign['formAtts'], $module); + $assign['carouselName'] = 'carousel-'.ApPageSetting::getRandomNumber(); + if ($assign['formAtts']['carousel_type'] == 'boostrap') { + if (isset($assign['formAtts']['nbitemsperline']) && $assign['formAtts']['nbitemsperline']) { + $assign['formAtts']['nbitemsperline_desktop'] = $assign['formAtts']['nbitemsperline']; + $assign['formAtts']['nbitemsperline_smalldesktop'] = $assign['formAtts']['nbitemsperline']; + $assign['formAtts']['nbitemsperline_tablet'] = $assign['formAtts']['nbitemsperline']; + } + if (isset($assign['formAtts']['nbitemsperlinetablet']) && $assign['formAtts']['nbitemsperlinetablet']) { + $assign['formAtts']['nbitemsperline_smalldevices'] = $assign['formAtts']['nbitemsperlinetablet']; + } + if (isset($assign['formAtts']['nbitemsperlinemobile']) && $assign['formAtts']['nbitemsperlinemobile']) { + $assign['formAtts']['nbitemsperline_extrasmalldevices'] = $assign['formAtts']['nbitemsperlinemobile']; + $assign['formAtts']['nbitemsperline_smartphone'] = $assign['formAtts']['nbitemsperlinemobile']; + } + + $assign['formAtts']['nbitemsperline_desktop'] = isset($assign['formAtts']['nbitemsperline_desktop']) && $assign['formAtts']['nbitemsperline_desktop'] ? (int)$assign['formAtts']['nbitemsperline_desktop'] : 4; + $assign['formAtts']['nbitemsperline_smalldesktop'] = isset($assign['formAtts']['nbitemsperline_smalldesktop']) && $assign['formAtts']['nbitemsperline_smalldesktop'] ? (int)$assign['formAtts']['nbitemsperline_smalldesktop'] : 4; + $assign['formAtts']['nbitemsperline_tablet'] = isset($assign['formAtts']['nbitemsperline_tablet']) && $assign['formAtts']['nbitemsperline_tablet'] ? (int)$assign['formAtts']['nbitemsperline_tablet'] : 3; + $assign['formAtts']['nbitemsperline_smalldevices'] = isset($assign['formAtts']['nbitemsperline_smalldevices']) && $assign['formAtts']['nbitemsperline_smalldevices'] ? (int)$assign['formAtts']['nbitemsperline_smalldevices'] : 2; + $assign['formAtts']['nbitemsperline_extrasmalldevices'] = isset($assign['formAtts']['nbitemsperline_extrasmalldevices']) && $assign['formAtts']['nbitemsperline_extrasmalldevices'] ? (int)$assign['formAtts']['nbitemsperline_extrasmalldevices'] : 1; + $assign['formAtts']['nbitemsperline_smartphone'] = isset($assign['formAtts']['nbitemsperline_smartphone']) && $assign['formAtts']['nbitemsperline_smartphone'] ? (int)$assign['formAtts']['nbitemsperline_smartphone'] : 1; + + $assign['tabname'] = 'carousel-'.ApPageSetting::getRandomNumber(); + $assign['itemsperpage'] = (int)$assign['formAtts']['nbitemsperpage']; + $assign['nbItemsPerLine'] = (int)$assign['formAtts']['nbitemsperline_desktop']; + + $assign['scolumn'] = ''; + + if ($assign['formAtts']['nbitemsperline_desktop'] == '5') { + $assign['scolumn'] .= ' col-xl-2-4'; + } else { + $assign['scolumn'] .= ' col-xl-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_desktop'])); + } + + if ($assign['formAtts']['nbitemsperline_smalldesktop'] == '5') { + $assign['scolumn'] .= ' col-lg-2-4'; + } else { + $assign['scolumn'] .= ' col-lg-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_smalldesktop'])); + } + + if ($assign['formAtts']['nbitemsperline_tablet'] == '5') { + $assign['scolumn'] .= ' col-md-2-4'; + } else { + $assign['scolumn'] .= ' col-md-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_tablet'])); + } + + if ($assign['formAtts']['nbitemsperline_smalldevices'] == '5') { + $assign['scolumn'] .= ' col-sm-2-4'; + } else { + $assign['scolumn'] .= ' col-sm-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_smalldevices'])); + } + + if ($assign['formAtts']['nbitemsperline_extrasmalldevices'] == '5') { + $assign['scolumn'] .= ' col-xs-2-4'; + } else { + $assign['scolumn'] .= ' col-xs-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_extrasmalldevices'])); + } + + if ($assign['formAtts']['nbitemsperline_smartphone'] == '5') { + $assign['scolumn'] .= ' col-sp-2-4'; + } else { + $assign['scolumn'] .= ' col-sp-' .str_replace('.', '-', ''.(int)(12 / $assign['formAtts']['nbitemsperline_smartphone'])); + } + } + + $assign['productClassWidget'] = $this->getProductClassByPListKey($assign['formAtts']['profile']); + + if (isset($assign['formAtts']['profile']) && $assign['formAtts']['profile'] != 'default' && file_exists(apPageHelper::getConfigDir('theme_profiles').$assign['formAtts']['profile'] . '.tpl')) { + $assign['product_item_path'] = apPageHelper::getConfigDir('theme_profiles') . $assign['formAtts']['profile'].'.tpl'; + } else { + // Default load file in theme + $assign['product_item_path'] = _PS_THEME_DIR_.'templates\catalog\_partials\miniatures\product.tpl'; + } + + # 1.7 + $assembler = new ProductAssembler(Context::getContext()); + $presenterFactory = new ProductPresenterFactory(Context::getContext()); + $presentationSettings = $presenterFactory->getPresentationSettings(); + $presenter = new ProductListingPresenter( + new ImageRetriever( + Context::getContext()->link + ), + Context::getContext()->link, + new PriceFormatter(), + new ProductColorsRetriever(), + Context::getContext()->getTranslator() + ); + + $products_for_template = array(); + foreach ($products as $rawProduct) { + $product_temp = $presenter->present( + $presentationSettings, + $assembler->assembleProduct($rawProduct), + Context::getContext()->language + ); + + # FIX 1.7.5.0 + if(is_object($product_temp) && method_exists($product_temp, 'jsonSerialize')) + { + $product_temp = $product_temp->jsonSerialize(); + } + + // FILTER SHORTCODE IN PRODUCT DESCRIPTION AND SHORT DESCRIPTION + $product_temp['description'] = $module->buildShortCode($product_temp['description']); + $product_temp['description_short'] = $module->buildShortCode($product_temp['description_short']); + $products_for_template[] = $product_temp; + } + + $assign['products'] = $products_for_template; + //DONGND:: create data for owl carousel with item custom + if ($assign['formAtts']['carousel_type'] == 'owlcarousel') { + //DONGND:: build data for fake item loading + $assign['formAtts']['number_fake_item'] = $assign['formAtts']['items']; + $array_fake_item = array(); + $array_fake_item['m'] = $assign['formAtts']['itemsmobile']; + $array_fake_item['sm'] = $assign['formAtts']['itemstablet']; + $array_fake_item['md'] = $assign['formAtts']['itemsdesktopsmall']; + $array_fake_item['lg'] = $assign['formAtts']['itemsdesktop']; + $array_fake_item['xl'] = $assign['formAtts']['items']; + $assign['formAtts']['array_fake_item'] = $array_fake_item; + + if (isset($assign['formAtts']['itemscustom']) && $assign['formAtts']['itemscustom'] != '') { + $array_item_custom = Tools::jsonDecode($assign['formAtts']['itemscustom']); + $array_item_custom_tmp = array(); + $array_number_item = array(); + foreach ($array_item_custom as $array_item_custom_val) { + $size_window = $array_item_custom_val[0]; + $number_item = $array_item_custom_val[1]; + if (0 <= $size_window && $size_window < 576) { + $array_item_custom_tmp['m'] = $number_item; + } else if (576 <= $size_window && $size_window < 768) { + $array_item_custom_tmp['sm'] = $number_item; + } else if (768 <= $size_window && $size_window < 992) { + $array_item_custom_tmp['md'] = $number_item; + } else if (992 <= $size_window && $size_window < 1200) { + $array_item_custom_tmp['lg'] = $number_item; + } else if ($size_window >= 1200) { + $array_item_custom_tmp['xl'] = $number_item; + } + $array_item_custom_tmp[$size_window] = $number_item; + $array_number_item[] = $number_item; + }; + $assign['formAtts']['array_fake_item'] = array_merge($array_fake_item, $array_item_custom_tmp); + + if (max($array_number_item) > $assign['formAtts']['items']) { + $assign['formAtts']['number_fake_item'] = max($array_number_item); + } + } + } + + if ($assign['formAtts']['carousel_type'] == 'slickcarousel') { + if (isset($assign['formAtts']['slick_items_custom'])) { + $assign['formAtts']['slick_items_custom'] = str_replace($this->str_search, $this->str_relace, $assign['formAtts']['slick_items_custom']); + } + if (isset($assign['formAtts']['slick_custom'])) { + $str_relace = array('&', '\"', '\'', '', '', '', '[', ']', '+', '{', '}'); + $assign['formAtts']['slick_custom'] = str_replace($this->str_search, $str_relace, $assign['formAtts']['slick_custom']); + } + if (isset($assign['formAtts']['slick_items_custom'])) { + $assign['formAtts']['slick_items_custom'] = Tools::jsonDecode($assign['formAtts']['slick_items_custom']); + } + + //DONGND:: build data for fake item loading + $assign['formAtts']['number_fake_item'] = $assign['formAtts']['slick_slidestoshow']*$assign['formAtts']['slick_row']; + + if (isset($assign['formAtts']['slick_items_custom']) && $assign['formAtts']['slick_items_custom'] != '') { + $array_item_custom = $assign['formAtts']['slick_items_custom']; + $array_item_custom_tmp = array(); + $array_number_item = array(); + foreach ($array_item_custom as $array_item_custom_val) { + $size_window = $array_item_custom_val[0]; + $number_item = $array_item_custom_val[1]; + if (0 <= $size_window && $size_window < 576) { + $array_item_custom_tmp['m'] = $number_item; + } else if (576 <= $size_window && $size_window < 768) { + $array_item_custom_tmp['sm'] = $number_item; + } else if (768 <= $size_window && $size_window < 992) { + $array_item_custom_tmp['md'] = $number_item; + } else if (992 <= $size_window && $size_window < 1200) { + $array_item_custom_tmp['lg'] = $number_item; + } else if ($size_window >= 1200) { + $array_item_custom_tmp['xl'] = $assign['formAtts']['slick_slidestoshow']; + } + $number_item = $number_item*$assign['formAtts']['slick_row']; + $array_item_custom_tmp[$size_window] = $number_item; + $array_number_item[] = $number_item; + }; + $assign['formAtts']['array_fake_item'] = $array_item_custom_tmp; + + if (max($array_number_item) > $assign['formAtts']['slick_slidestoshow']) { + $assign['formAtts']['number_fake_item'] = max($array_number_item); + } + } + } + return $assign; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApProductList.php b/modules/appagebuilder/classes/shortcodes/ApProductList.php new file mode 100644 index 00000000..fdff1499 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApProductList.php @@ -0,0 +1,527 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +use PrestaShop\PrestaShop\Adapter\Image\ImageRetriever; +use PrestaShop\PrestaShop\Adapter\Product\PriceFormatter; +use PrestaShop\PrestaShop\Core\Product\ProductListingPresenter; +use PrestaShop\PrestaShop\Adapter\Product\ProductColorsRetriever; + +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageBuilderProductsModel.php'); + +class ApProductList extends ApShortCodeBase +{ + public $name = 'ApProductList'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Product List'), + 'position' => 7, + 'desc' => $this->l('Create Product List'), + 'icon_class' => 'icon icon-th', + 'tag' => 'content'); + } + + public function getAdditionConfig() + { + return array( + array( + 'type' => '', + 'name' => 'value_by_categories', + 'default' => '0' + ), + array( + 'type' => '', + 'name' => 'value_by_product_type', + 'default' => '0' + ), + array( + 'type' => '', + 'name' => 'value_by_manufacture', + 'default' => '0' + ), + array( + 'type' => '', + 'name' => 'value_by_supplier', + 'default' => '0' + ), + array( + 'type' => '', + 'name' => 'value_by_product_id', + 'default' => '0' + ), + array( + 'type' => '', + 'name' => 'value_by_tags', + 'default' => '0' + ) + ); + } + + public function getConfigList() + { + $selected_categories = array(); + if (Tools::getIsset('categorybox')) { + $category_box = Tools::getValue('categorybox'); + $selected_categories = explode(',', $category_box); + } + //get all manufacture + $manufacturers = Manufacturer::getManufacturers(false, 0, true, false, false, false, true); + $suppliers = Supplier::getSuppliers(); +// $product_active = ApPageBuilderProductsModel::getActive(); +// $product_class = $product_active['class']; + $profile = new ApPageBuilderProductsModel(); + $profile_list = $profile->getAllProductProfileByShop(); + array_unshift($profile_list, array('plist_key' => 'default', 'name' => $this->l('Use Default'))); + $id_root_category = Context::getContext()->shop->getCategory(); + $input = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), 'lang' => 'true', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => '' + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Step 1: Product Filter').'
    ', + ), + array( + 'type' => 'checkbox', + 'name' => 'value_by', + 'label' => $this->l('Select By'), + 'class' => 'checkbox-group', + 'desc' => $this->l('Select Product Condition'), + 'values' => array( + 'query' => array( + array( + 'id' => 'categories', + 'name' => $this->l('Categories'), + 'val' => '1' + ), + array( + 'id' => 'product_type', + 'name' => $this->l('Product Type'), + 'val' => '1' + ), + array( + 'id' => 'manufacture', + 'name' => $this->l('Manufacture'), + 'val' => '1' + ), + array( + 'id' => 'supplier', + 'name' => $this->l('Supplier'), + 'val' => '1' + ), + array( + 'id' => 'product_id', + 'name' => $this->l('Product Ids'), + 'val' => '1' + ), + ), + 'id' => 'id', + 'name' => 'name' + ) + ), + array( + 'type' => 'categories', + 'label' => $this->l('Select Category'), + 'name' => 'categorybox', + 'desc' => $this->l('You can select one or more, if not select we will not search by category'), + 'tree' => array( + 'root_category' => $id_root_category, + 'use_search' => false, + 'id' => 'categorybox', + 'use_checkbox' => true, + 'selected_categories' => $selected_categories, + ), + 'form_group_class' => 'value_by_categories', + ), + array( + 'type' => 'select', + 'label' => $this->l('Product of Category'), + 'name' => 'category_type', + 'options' => array( + 'query' => array( + array('id' => 'all', 'name' => $this->l('Get All Product of Category')), + array('id' => 'default', 'name' => $this->l('Get Product if category is default category of product'))), + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'value_by_categories', + 'default' => 'all' + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'value_by_categories', + ), + array( + 'type' => 'select', + 'label' => $this->l('Product Type'), + 'name' => 'product_type', + 'options' => array( + 'query' => array( + array( + 'id' => 'all', + 'name' => $this->l('All Product'), + ), + array( + 'id' => 'new_product', + 'name' => $this->l('New Product'), + ), + array( + 'id' => 'best_sellers', + 'name' => $this->l('Best sellers'), + ), + array( + 'id' => 'price_drop', + 'name' => $this->l('Special'), + ), + array( + 'id' => 'home_featured', + 'name' => $this->l('Home Featured'), + ) + ), + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'value_by_product_type', + 'default' => 'all', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'value_by_product_type', + ), + array( + 'type' => 'select', + 'label' => $this->l('Manufacture'), + 'name' => 'manufacture[]', + 'multiple' => true, + 'options' => array( + 'query' => $manufacturers, + 'id' => 'id_manufacturer', + 'name' => 'name' + ), + 'form_group_class' => 'aprow_exceptions', + 'default' => 'all', + 'form_group_class' => 'value_by_manufacture', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'value_by_manufacture', + ), + array( + 'type' => 'select', + 'label' => $this->l('Supplier'), + 'name' => 'supplier[]', + 'multiple' => true, + 'options' => array( + 'query' => $suppliers, + 'id' => 'id_supplier', + 'name' => 'name' + ), + 'form_group_class' => 'value_by_supplier', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'value_by_supplier', + ), + array( + 'type' => 'text', + 'name' => 'product_id', + 'label' => $this->l('Product Ids'), + 'desc' => $this->l('Show product follow product id. Ex 1 or 1,2,3,4 '), + 'default' => '', + 'form_group_class' => 'value_by_product_id', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'value_by_product_id', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Step 2: Product Order And Limit').'
    ', + ), + array( + 'type' => 'select', + 'label' => $this->l('Order Way'), + 'class' => 'form-action', + 'name' => 'order_way', + 'options' => array( + 'query' => array( + array('id' => 'asc', 'name' => $this->l('Asc')), + array('id' => 'desc', 'name' => $this->l('Desc')), + array('id' => 'random', 'name' => $this->l('Random'))), // remove to increase speed + 'id' => 'id', + 'name' => 'name' + ), + 'default' => 'all' + ), + array( + 'type' => 'select', + 'label' => $this->l('Order By'), + 'name' => 'order_by', + 'options' => array( + 'query' => ApPageSetting::getOrderBy(), + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'order_type_sub order_type-asc order_type-desc', + 'default' => 'all' + ), + array( + 'type' => 'select', + 'label' => $this->l('Columns'), + 'name' => 'columns', + 'options' => array('query' => array( + array('id' => '1', 'name' => $this->l('1 Column')), + array('id' => '2', 'name' => $this->l('2 Columns')), + array('id' => '3', 'name' => $this->l('3 Columns')), + array('id' => '4', 'name' => $this->l('4 Columns')), + array('id' => '5', 'name' => $this->l('5 Columns')), + array('id' => '6', 'name' => $this->l('6 Columns')), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => '4', + ), + array( + 'type' => 'text', + 'name' => 'nb_products', + 'label' => $this->l('Limit'), + 'default' => '10', + ), + //boostrap carousel end + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('Step 3: Product Template').'
    ', + ), + array( + 'type' => 'select', + 'label' => $this->l('Product Template'), + 'name' => 'profile', + 'options' => array( + 'query' => $profile_list, + 'id' => 'plist_key', + 'name' => 'name' + ), + 'default' => 'all' + ), + array( + 'type' => 'switch', + 'label' => $this->l('Use Animation For Product Item'), + 'name' => 'use_animation', + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1' + ), + array( + 'type' => 'switch', + 'label' => $this->l('Use Show More button'), + 'name' => 'use_showmore', + 'desc' => $this->l('Show button to load more product or hidden this function'), + 'values' => ApPageSetting::returnYesNo(), + 'default' => '1' + ), + ); + return $input; + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + $form_atts = $assign['formAtts']; + $n = (int)isset($form_atts['nb_products']) ? $form_atts['nb_products'] : '10'; + $p = (int)Tools::getIsset('p') ? Tools::getValue('p') : '1'; + $form_atts['page_number'] = $p; // current page + $form_atts['get_total'] = true; // sql param + $module = APPageBuilder::getInstance(); + $total = $module->getProductsFont($form_atts); + $total = (is_array($total) && count($total) > 0) ? count($total) : 0; + $form_atts['total_page'] = $total_page = ceil(($total / $n)); + $is_more = $p < $total_page ? 'more' : ''; + + $products = array(); + if ($p <= $total_page) { + $form_atts['get_total'] = false; + $products = $module->getProductsFont($form_atts); + $products = $this->loadProductDetail($products, $module); + } + + $assign['scolumn'] = $form_atts['columns']; + $assign['products'] = $products; + $assign['is_more'] = $is_more; + $assign['p'] = $p + 1; + + $assign['productClassWidget'] = $this->getProductClassByPListKey($assign['formAtts']['profile']); + + if (isset($assign['formAtts']['profile']) && $assign['formAtts']['profile'] != 'default' && file_exists(apPageHelper::getConfigDir('theme_profiles').$assign['formAtts']['profile'] . '.tpl')) { + $assign['product_item_path'] = apPageHelper::getConfigDir('theme_profiles') . $assign['formAtts']['profile'].'.tpl'; + } else { + // Default load file in theme + $assign['product_item_path'] = 'catalog/_partials/miniatures/product.tpl'; + } + + # DATA FOR AJAX + $apPConfig = $form_atts; + // FIX : special charactor http://screencast.com/t/cEqFoIL5K + unset($apPConfig['title']); + $apPConfig['product_item_path'] = $assign['product_item_path']; + + $assign['apPConfig'] = call_user_func('base64'.'_encode', Tools::jsonEncode($apPConfig)); + return $assign; + } + + public function ajaxProcessRender($module) + { + $assign = array(); + $params = array(); + $input = Tools::jsonDecode(call_user_func('base64'.'_decode', Tools::getValue('config'))); + $use_animation = Tools::getValue('use_animation'); + $n = (int)isset($input->nb_products) ? $input->nb_products : '10'; + $p = (int)Tools::getIsset('p') ? Tools::getValue('p') : '1'; + $params['value_by_categories'] = isset($input->value_by_categories) ? $input->value_by_categories : '0'; + $params['value_by_product_type'] = isset($input->value_by_product_type) ? $input->value_by_product_type : '0'; + $params['value_by_manufacture'] = isset($input->value_by_manufacture) ? $input->value_by_manufacture : '0'; + $params['value_by_supplier'] = isset($input->value_by_supplier) ? $input->value_by_supplier : '0'; + $params['categorybox'] = isset($input->categorybox) ? $input->categorybox : ''; + $params['category_type'] = isset($input->category_type) ? $input->category_type : ''; + $params['product_type'] = isset($input->product_type) ? $input->product_type : ''; + $params['manufacture'] = isset($input->manufacture) ? $input->manufacture : ''; + $params['supplier'] = isset($input->supplier) ? $input->supplier : ''; + $params['nb_products'] = $n; + $params['page_number'] = $p; + $params['order_by'] = isset($input->order_by) ? $input->order_by : ''; + $params['order_way'] = isset($input->order_way) ? $input->order_way : ''; + $params['get_total'] = true; + $params['override_folder'] = isset($input->override_folder) ? $input->override_folder : ''; + $assign['product_item_path'] = $input->product_item_path; + $total_page = $input->total_page; + + + $is_more = ($p < $total_page) ? 'more' : ''; + $products = array(); + if ($p <= $total_page) { + $params['get_total'] = false; + $products = $module->getProductsFont($params); + $products = $this->loadProductDetail($products, $module); + } + $assign['profile'] = (isset($input->profile) && $input->profile != 'default') ? $input->profile : ''; + $assign['products'] = $products; + $assign['apAjax'] = 1; + $assign['scolumn'] = $input->columns; + $assign['formAtts']['use_animation'] = $use_animation; + + $theme_name = _THEME_NAME_; + $tpl_name = 'ApProductList.tpl'; + if (isset($params['override_folder']) && file_exists(_PS_ALL_THEMES_DIR_.$theme_name.'/modules/appagebuilder/views/templates/hook/'.$params['override_folder'].'/'.$tpl_name)) { + // overide_folder + $tpl_file = _PS_ALL_THEMES_DIR_.$theme_name.'/modules/appagebuilder/views/templates/hook/'.$params['override_folder'].'/'.$tpl_name; +// } elseif (file_exists(_PS_ALL_THEMES_DIR_.$theme_name.'/modules/appagebuilder/views/templates/hook/'.$hook_name.'/'.$tpl_name) || file_exists(dirname(__FILE__).'/views/templates/hook/'.$hook_name.'/'.$tpl_name)) { +// $tpl_file = 'views/templates/hook/'.$hook_name.'/'.$tpl_name; + } elseif (file_exists(_PS_ALL_THEMES_DIR_.$theme_name.'/modules/appagebuilder/views/templates/hook/'.$tpl_name) || file_exists(dirname(__FILE__).'/views/templates/hook/'.$tpl_name)) { + // theme folder + $tpl_file = _PS_ALL_THEMES_DIR_.$theme_name.'/modules/appagebuilder/views/templates/hook/'.$tpl_name; + } else { + // module folder + $tpl_file = _PS_MODULE_DIR_.'appagebuilder/views/templates/hook/'.$tpl_name; + } + + $imageRetriever = new ImageRetriever(Context::getContext()->link); + $urls['no_picture_image'] = $imageRetriever->getNoPictureImage(Context::getContext()->language); + Context::getContext()->smarty->assign('urls', $urls); + + foreach ($assign as $key => $ass) { + Context::getContext()->smarty->assign(array($key => $ass)); + } + $html = Context::getContext()->smarty->fetch($tpl_file); + + return array('html' => $html, 'is_more' => $is_more); + } + + public function loadProductDetail($products, $module) + { + # 1.7 + $assembler = new ProductAssembler(Context::getContext()); + $presenterFactory = new ProductPresenterFactory(Context::getContext()); + $presentationSettings = $presenterFactory->getPresentationSettings(); + $presenter = new ProductListingPresenter( + new ImageRetriever( + Context::getContext()->link + ), + Context::getContext()->link, + new PriceFormatter(), + new ProductColorsRetriever(), + Context::getContext()->getTranslator() + ); + + $products_for_template = array(); + foreach ($products as $rawProduct) + { + $product_temp = $presenter->present( + $presentationSettings, + $assembler->assembleProduct($rawProduct), + Context::getContext()->language + ); + + # FIX 1.7.5.0 + if(is_object($product_temp) && method_exists($product_temp, 'jsonSerialize')) + { + $product_temp = $product_temp->jsonSerialize(); + } + + # ADD SHORTCODE TO PRODUCT DESCRIPTION AND PRODUCT SHORT DESCRIPTION + $product_temp['description'] = $module->buildShortCode($product_temp['description']); + $product_temp['description_short'] = $module->buildShortCode($product_temp['description_short']); + $products_for_template[] = $product_temp; + } + return $products_for_template; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApProductTag.php b/modules/appagebuilder/classes/shortcodes/ApProductTag.php new file mode 100644 index 00000000..e8b30138 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApProductTag.php @@ -0,0 +1,170 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApProductTag extends ApShortCodeBase +{ + public $name = 'ApProductTag'; + public $for_module = 'manage'; + + public function getInfo() + { + return array( + 'label' => $this->l('Product Tags'), + 'position' => 4, + 'desc' => $this->l('Show Product Tags at Frontend'), + 'icon_class' => 'icon icon-tags', + 'tag' => 'content'); + } + + public function getConfigList() + { + $accordion_type = array( + array( + 'value' => 'full', + 'text' => $this->l('Always Full') + ), + array( + 'value' => 'accordion', + 'text' => $this->l('Always Accordion') + ), + array( + 'value' => 'accordion_small_screen', + 'text' => $this->l('Accordion at small screen') + ), + ); + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'lang' => 'true', + 'default' => '', + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'autoload_rte' => false, + 'values' => '', + 'class' => 'sub_title', + 'default' => '', + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => '' + ), + array( + 'type' => 'select', + 'label' => $this->l('Accordion Type'), + 'name' => 'accordion_type', + 'options' => array( + 'query' => $accordion_type, + 'id' => 'value', + 'name' => 'text' + ), + 'default' => 'full', + 'hint' => $this->l('Select a Accordion Type'), + ), + array( + 'type' => 'text', + 'name' => 'displayed_tags', + 'label' => $this->l('Displayed tags'), + 'desc' => $this->l('Set the number of tags you would like to see displayed in this block. (default: 10)'), + 'lang' => 'false', + 'default' => '10' + ), + array( + 'type' => 'text', + 'name' => 'tag_levels', + 'label' => $this->l('Tag levels'), + 'desc' => $this->l('Set the number of different tag levels you would like to use. (default: 3) '), + 'lang' => 'false', + 'default' => '10' + ), + array( + 'type' => 'switch', + 'label' => $this->l('Random display'), + 'name' => 'random_display', + 'class' => 'fixed-width-xs', + 'desc' => $this->l('If enabled, displays tags randomly. By default, random display is disabled and the most used tags are displayed first.'), + 'values' => array( + array( + 'id' => 'active_on', + 'value' => 1, + 'label' => $this->l('Enabled') + ), + array( + 'id' => 'active_off', + 'value' => 0, + 'label' => $this->l('Disabled') + ) + ) + ) + ); + return $inputs; + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + + $id_lang = (int) Context::getContext()->language->id; + $displayed_tags = isset($assign['formAtts']['displayed_tags']) ? (int)$assign['formAtts']['displayed_tags'] : 10; + $tag_levels = isset($assign['formAtts']['tag_levels']) ? (int)$assign['formAtts']['tag_levels'] : 10; + $random_display = isset($assign['formAtts']['random_display']) ? (int)$assign['formAtts']['random_display'] : 0; + + $tags = Tag::getMainTags($id_lang, $displayed_tags); + + $max = -1; + $min = -1; + foreach ($tags as $tag) { + if ($tag['times'] > $max) { + $max = $tag['times']; + } + if ($tag['times'] < $min || $min == -1) { + $min = $tag['times']; + } + } + + if ($min == $max) { + $coef = $max; + } else { + $coef = ($tag_levels - 1) / ($max - $min); + } + + if (!count($tags)) { + return $assign; + } + if ($random_display) { + shuffle($tags); + } + foreach ($tags as &$tag) { + $tag['class'] = 'tag_level'.(int)(($tag['times'] - $min) * $coef + 1); + } + + $assign['formAtts']['tags'] = $tags; + + return $assign; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApQuicklogin.php b/modules/appagebuilder/classes/shortcodes/ApQuicklogin.php new file mode 100644 index 00000000..6230f739 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApQuicklogin.php @@ -0,0 +1,120 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApQuicklogin extends ApShortCodeBase +{ + public $name = 'ApQuicklogin'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Quicklogin Module'), 'position' => 3, 'desc' => $this->l('You set quick login or social login form from leoquicklogin module'), + 'icon_class' => 'icon icon-chevron-right', 'tag' => 'content'); + } + + public function getConfigList() + { + if (Module::isInstalled('leoquicklogin') && Module::isEnabled('leoquicklogin')) { + include_once(_PS_MODULE_DIR_.'leoquicklogin/leoquicklogin.php'); + $module = new Leoquicklogin(); + $select_list_type = array(); + + foreach ($module->list_type as $key => $value) { + $select_list_type[] = array('id' => $key, 'name' => $value); + } + + $select_list_layout = array(); + + foreach ($module->list_layout as $key => $value) { + $select_list_layout[] = array('id' => $key, 'name' => $value); + } + $inputs = array( + array( + 'type' => 'select', + 'label' => $this->l('Select type'), + 'name' => 'quicklogin_type', + 'options' => array( + 'query' => $select_list_type, + 'id' => 'id', + 'name' => 'name' + ), + + ), + array( + 'type' => 'select', + 'label' => $this->l('Select layout'), + 'name' => 'quicklogin_layout', + 'options' => array( + 'query' => $select_list_layout, + 'id' => 'id', + 'name' => 'name' + ), + + ), + array( + 'type' => 'select', + 'label' => $this->l('Show Social Login'), + 'name' => 'quicklogin_sociallogin', + 'options' => array( + 'query' => array( + array( + 'id' => 'enable', + 'name' => $this->l('Yes'), + ), + array( + 'id' => 'disable', + 'name' => $this->l('No'), + )), + 'id' => 'id', + 'name' => 'name' + ), + ), + ); + } else { + $inputs = array( + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '. + $this->l('"Leoquicklogin module" Module must be installed and enabled before using.'). + '

    You can take this module at leo-theme or apollo-theme

    ' + ) + ); + } + return $inputs; + } + + public function prepareFontContent($assign, $module = null) + { + if (Module::isInstalled('leoquicklogin') && Module::isEnabled('leoquicklogin')) { + $assign['formAtts']['isEnabled'] = true; + include_once(_PS_MODULE_DIR_.'leoquicklogin/leoquicklogin.php'); + $module = new Leoquicklogin(); + + $assign['content_quicklogin'] = $module->processHookCallBack($assign['formAtts']['quicklogin_type'], $assign['formAtts']['quicklogin_layout'], $assign['formAtts']['quicklogin_sociallogin']); + } else { + // validate module + $assign['formAtts']['isEnabled'] = false; + $assign['formAtts']['lib_has_error'] = true; + $assign['formAtts']['lib_error'] = 'Can not show Leoquicklogin via Appagebuilder. Please enable Leoquicklogin module.'; + } + return $assign; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApRawHtml.php b/modules/appagebuilder/classes/shortcodes/ApRawHtml.php new file mode 100644 index 00000000..de42d724 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApRawHtml.php @@ -0,0 +1,70 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApRawHtml extends ApShortCodeBase +{ + public $name = 'ApRawHtml'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Raw Html'), 'position' => 3, 'desc' => $this->l('You can put raw html'), + 'icon_class' => 'icon-html5', 'tag' => 'content structure'); + } + + public function getConfigList() + { + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'lang' => 'true', + 'default' => '', + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'content_html', + 'class' => 'ap_html_raw raw-'.time(), + 'rows' => '50', + 'lang' => true, + 'label' => $this->l('Raw html'), + 'values' => '', + 'default' => "
    \n
    " + ), + ); + return $inputs; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApRow.php b/modules/appagebuilder/classes/shortcodes/ApRow.php new file mode 100644 index 00000000..4011f0ea --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApRow.php @@ -0,0 +1,774 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageBuilderHookModel.php'); + +class ApRow extends ApShortCodeBase +{ + public $name = 'ApRow'; + public $for_module = 'manage'; + public $show_upload = '1'; + public $atribute = array('el_class' => ''); + + public function getInfo() + { + return array('label' => $this->l('Row'), 'position' => 1, + 'desc' => $this->l('Each row can have one or more Column'), + 'tag' => 'content structure'); + } + + public function getConfigList() + { + $input = array( + array( + 'type' => 'tabConfig', + 'name' => 'tabConfig', + 'values' => array( + 'aprow_general' => $this->l('General'), + 'aprow_style' => $this->l('Style'), + 'aprow_background' => $this->l('Background'), + // 'aprow_animation' => $this->l('Animation'), + 'aprow_exceptions' => $this->l('Exceptions')) + ), + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'form_group_class' => 'aprow_general', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'form_group_class' => 'aprow_general', + 'default' => '' + ), + array( + 'type' => 'text', + 'name' => 'id', + 'label' => $this->l('ID'), + 'form_group_class' => 'aprow_general', + 'desc' => $this->l('Use for css and javascript'), + 'default' => '' + ), + array( + 'type' => 'text', + 'name' => 'container', + 'label' => $this->l('Class container'), + 'form_group_class' => 'aprow_general', + 'desc' => $this->getDescriptionContainerInput(), + 'default' => '' + ), + array( + 'type' => 'ApRowclass', + 'name' => 'class', + 'leolabel' => 'CSS Class', + 'form_group_class' => 'aprow_general', + 'default' => 'row' + ), + array( + 'type' => 'text', + 'name' => 'min_height', + 'label' => $this->l('Minimum height'), + 'desc' => $this->l('You can use pixels : 10px or percents : 10%.'), + 'default' => '', + 'form_group_class' => 'aprow_style', + ), + array( + 'type' => 'text', + 'label' => $this->l('Margin Top'), + 'name' => 'margin_top', + 'desc' => $this->l('You can use pixels :10px or percents : 10%.'), + 'default' => '', + 'form_group_class' => 'aprow_style', + ), + array( + 'type' => 'text', + 'label' => $this->l('Margin Bottom'), + 'name' => 'margin_bottom', + 'desc' => $this->l('You can use pixels :10px or percents : 10%.'), + 'default' => '', + 'form_group_class' => 'aprow_style', + ), + array( + 'type' => 'text', + 'label' => $this->l('Padding Top'), + 'name' => 'padding_top', + 'desc' => $this->l('You can use pixels :10px or percents : 10%.'), + 'default' => '', + 'form_group_class' => 'aprow_style', + ), + array( + 'type' => 'text', + 'label' => $this->l('Padding Bottom'), + 'name' => 'padding_bottom', + 'desc' => $this->l('You can use pixels : 10px or percents : 10%.'), + 'default' => '', + 'form_group_class' => 'aprow_style', + ), + array( + 'type' => 'select', + 'label' => $this->l('Background Config'), + 'name' => 'bg_config', + 'default' => 'boxed', + 'options' => array( + 'query' => array( + array( + 'id' => 'fullwidth', + 'name' => $this->l('Full width'), + ), + array( + 'id' => 'boxed', + 'name' => $this->l('Boxed'), + ), + array( + 'id' => 'none', + 'name' => $this->l('None'), + ), + ), + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'aprow_background', + ), + array( + 'type' => 'select', + 'label' => $this->l('Background Type'), + 'name' => 'bg_type', + 'class' => 'form-action', + 'options' => array( + 'query' => array( + array( + 'id' => 'normal', + 'name' => $this->l('Normal'), + ), + array( + 'id' => 'fixed', + 'name' => $this->l('Fixed'), + ), + array( + 'id' => 'parallax', + 'name' => $this->l('Parallax'), + ), + array( + 'id' => 'mouseparallax', + 'name' => $this->l('Mouse Parallax'), + ), +// array( +// 'id' => 'video_youtube', +// 'name' => $this->l('Video Youtube'), +// ), +// array( +// 'id' => 'video_vimeo', +// 'name' => $this->l('Vimeo video'), +// ), +// array( +// 'id' => 'video_html5', +// 'name' => $this->l('HTML5'), +// ) + ), + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'aprow_background', + ), + array( + 'type' => 'text', + 'label' => $this->l('Background size'), + 'name' => 'bg_size', + 'desc' => $this->l('Set CSS value for the background size. (Ex: contain, cover, 50% 100%, 100px 200px,..)'), + 'form_group_class' => 'aprow_background bg_type_sub bg_type-normal bg_type-fixed bg_type-parallax', + ), + array( + 'type' => 'color', + 'label' => $this->l('Background color'), + 'name' => 'bg_color', + 'default' => '', + 'form_group_class' => 'aprow_background bg_type_sub bg_type-normal bg_type-fixed bg_type-parallax bg_type-mouseparallax', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '', + ), + array( + 'type' => 'bg_img', + 'label' => $this->l('Background image'), + 'name' => 'bg_img', + 'img_link' => _THEME_IMG_DIR_.'modules/'.$this->module_name.'/images/', + 'default' => '', + 'form_group_class' => 'aprow_background bg_type_sub bg_type-normal bg_type-fixed bg_type-parallax bg_type-mouseparallax', + ), + array( + 'type' => 'text', + 'label' => $this->l('Background position'), + 'name' => 'bg_position', + 'desc' => $this->l('Set CSS value for the background image position. (Ex: center top, right bottom, 50% 50%, 100px 200px,..)'), + 'form_group_class' => 'aprow_background bg_type_sub bg_type-normal bg_type-fixed bg_type-parallax', + ), + array( + 'type' => 'select', + 'label' => $this->l('Background repeat'), + 'name' => 'bg_repeat', + 'options' => array( + 'query' => array( + array( + 'id' => 'no-repeat', + 'name' => $this->l('No repeat'), + ), + array( + 'id' => 'repeat', + 'name' => $this->l('Repeat All'), + ), + array( + 'id' => 'repeat-x', + 'name' => $this->l('repeat horizontally only'), + ), + array( + 'id' => 'repeat-y', + 'name' => $this->l('repeat vertically only'), + ) + ), + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'aprow_background bg_type_sub bg_type-normal bg_type-fixed bg_type-parallax bg_type-mouseparallax', + ), + array( + 'type' => 'text', + 'label' => $this->l('Parallax speed'), + 'name' => 'parallax_speed', + 'default' => '0.1', + 'desc' => $this->l('Set the background speed, this is relative to the natural scroll speed (Ex: 0, 0.5, 1, 2).'), + 'form_group_class' => 'aprow_background bg_type_sub bg_type-parallax', + ), + array( + 'type' => 'select', + 'label' => $this->l('Parallax axis'), + 'desc' => $this->l('Select axis effect for this background.'), + 'name' => 'parallax_axis', + 'desc' => $this->l('Select axis effect for this background.'), + 'options' => array( + 'query' => array( + array( + 'id' => 'both', + 'name' => $this->l('Both'), + ), + array( + 'id' => 'axis-x', + 'name' => $this->l('Axis X (horizontally)'), + ), + array( + 'id' => 'axis-y', + 'name' => $this->l('Axis Y (vertically)'), + ) + ), + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'aprow_background bg_type_sub bg_type-mouseparallax', + ), + array( + 'type' => 'text', + 'label' => $this->l('Parallax strength'), + 'name' => 'parallax_strength', + 'default' => '0.5', + 'desc' => $this->l('Set the background strength, this is relative to the natural mouse speed (Ex: 0, 0.5, 1, 2).'), + 'form_group_class' => 'aprow_background bg_type_sub bg_type-mouseparallax', + ), + array( + 'type' => 'text', + 'label' => $this->l('Parallax rid'), + 'name' => 'parallax_rid', + 'default' => '0.5', + 'form_group_class' => 'aprow_background bg_type_sub bg_type-mouseparallax', + ), + array( + 'type' => 'text', + 'label' => $this->l('Parallax horizontal offsets'), + 'name' => 'parallax_hoffsets', + 'default' => '0.1', + 'desc' => $this->l('Set the global alignment horizontal offset'), + 'form_group_class' => 'aprow_background bg_type_sub bg_type-parallax', + ), + array( + 'type' => 'text', + 'label' => $this->l('Parallax vertical speed'), + 'name' => 'parallax_voffsets', + 'default' => '0.1', + 'desc' => $this->l('Set the global alignment vertical offset'), + 'form_group_class' => 'aprow_background bg_type_sub bg_type-parallax', + ), + array( + 'type' => 'text', + 'label' => $this->l('Video background'), + 'name' => 'video_link', + 'default' => '', + 'desc' => $this->l('Put video youtube link or vimeo'), + 'form_group_class' => 'aprow_background bg_type_sub bg_type-video_html5', + ), + array( + 'type' => 'text', + 'label' => $this->l('Video ID'), + 'name' => 'video_id', + 'default' => '', + 'desc' => $this->l('Put video ID of youtube link or vimeo'), + 'form_group_class' => 'aprow_background bg_type_sub bg_type-video_youtube bg_type-video_vimeo', + ), + array( + 'type' => 'select', + 'label' => $this->l('Specific Controller'), + 'name' => 'specific_type', + 'class' => 'form-action', + 'options' => array( + 'query' => array( + array( + 'id' => 'all', + 'name' => $this->l('Show on all Page Controller'), + ), + array( + 'id' => 'index', + 'name' => $this->l('Show on only Index'), + ), + array( + 'id' => 'category', + 'name' => $this->l('Show on only Category'), + ), + array( + 'id' => 'product', + 'name' => $this->l('Show on only Product'), + ), + array( + 'id' => 'cms', + 'name' => $this->l('Show on only CMS'), + ) + ), + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'aprow_exceptions', + 'default' => 'all' + ), + array( + 'type' => 'reloadControler', + 'label' => $this->l('AJAX Reload Controller'), + 'name' => 'reloadControler', + 'default' => '', + 'form_group_class' => 'aprow_exceptions specific_type_sub specific_type-all', + 'hint' => 'If website have new a Controller, click to generate Controller again.', + ), + array( + 'type' => 'text', + 'label' => $this->l('Controller ID'), + 'name' => 'controller_id', + 'desc' => $this->l('Example: 1,2,3'), + 'default' => '', + 'form_group_class' => 'aprow_exceptions specific_type_sub specific_type-category specific_type-product specific_type-cms', + ), + array( + 'type' => 'apExceptions', + 'name' => 'controller_pages', + 'form_group_class' => 'aprow_exceptions specific_type_sub specific_type-all', + ), + ); + return $input; + } + + public function endRenderForm() + { +// $display_module_exception = ''; +// +// if (Tools::getValue('reloadControllerException')) { +// # ReLoad : write to config +// $display_module_exception = $this->displayModuleExceptionList(); +// +// $ap_cache_controller_exception = apPageHelper::correctEnCodeData($display_module_exception); +// Configuration::updateValue('AP_CACHE_CONTROLLER_EXCEPTION', $ap_cache_controller_exception); +// } else { +// +// $display_module_exception = Configuration::get('AP_CACHE_CONTROLLER_EXCEPTION'); +// if ($display_module_exception === false) +// { +// # First Time : write to config +// $display_module_exception = $this->displayModuleExceptionList(); +// +// $ap_cache_controller_exception = apPageHelper::correctEnCodeData($display_module_exception); +// Configuration::updateValue('AP_CACHE_CONTROLLER_EXCEPTION', $ap_cache_controller_exception); +// } else { +// # Second Time : read from config +// $display_module_exception = apPageHelper::correctDeCodeData($display_module_exception); +// } +// } +// $this->helper->tpl_vars['exception_list'] = $display_module_exception; + $this->helper->module = new $this->module_name(); + $this->helper->tpl_vars['link'] = Context::getContext()->link; + $this->helper->tpl_vars['exception_list'] = $this->displayModuleExceptionList(); + } + + public function displayModuleExceptionList() + { + $controllers = array(); + $controllers_modules = array(); + $controllers_modules['admin'] = array(); + $controllers_modules['front'] = array(); + + if (Tools::getValue('reloadControllerException')) { + $controllers = Dispatcher::getControllers(_PS_FRONT_CONTROLLER_DIR_); + $controllers_modules = array( + 'admin' => Dispatcher::getModuleControllers('admin'), + 'front' => Dispatcher::getModuleControllers('front'), + ); + + Configuration::updateValue('AP_CACHE_FRONT_CONTROLLER_EXCEPTION', apPageHelper::correctEnCodeData(Tools::jsonEncode($controllers))); + Configuration::updateValue('AP_CACHE_FRONT_MODULE_EXCEPTION', apPageHelper::correctEnCodeData(Tools::jsonEncode($controllers_modules['admin']))); + Configuration::updateValue('AP_CACHE_ADMIN_MODULE_EXCEPTION', apPageHelper::correctEnCodeData(Tools::jsonEncode($controllers_modules['front']))); + } else { + if (Configuration::get('AP_CACHE_FRONT_CONTROLLER_EXCEPTION') === false) { + # First Time : write to config + $controllers = Dispatcher::getControllers(_PS_FRONT_CONTROLLER_DIR_); + Configuration::updateValue('AP_CACHE_FRONT_CONTROLLER_EXCEPTION', apPageHelper::correctEnCodeData(Tools::jsonEncode($controllers))); + } else { + # Second Time : read from config + $controllers = Tools::jsonDecode(apPageHelper::correctDeCodeData(Configuration::get('AP_CACHE_FRONT_CONTROLLER_EXCEPTION')), true); + } + + if (Configuration::get('AP_CACHE_FRONT_MODULE_EXCEPTION') === false) { + # First Time : write to config + $controllers_modules['admin'] = Dispatcher::getModuleControllers('admin'); + Configuration::updateValue('AP_CACHE_FRONT_MODULE_EXCEPTION', apPageHelper::correctEnCodeData(Tools::jsonEncode($controllers_modules['admin']))); + } else { + # Second Time : read from config + $controllers_modules['admin'] = Tools::jsonDecode(apPageHelper::correctDeCodeData(Configuration::get('AP_CACHE_FRONT_MODULE_EXCEPTION')), true); + } + + if (Configuration::get('AP_CACHE_ADMIN_MODULE_EXCEPTION') === false) { + # First Time : write to config + $controllers_modules['front'] = Dispatcher::getModuleControllers('front'); + Configuration::updateValue('AP_CACHE_ADMIN_MODULE_EXCEPTION', apPageHelper::correctEnCodeData(Tools::jsonEncode($controllers_modules['front']))); + } else { + # Second Time : read from config + $controllers_modules['front'] = Tools::jsonDecode(apPageHelper::correctDeCodeData(Configuration::get('AP_CACHE_ADMIN_MODULE_EXCEPTION')), true); + } + } + + $controller = Tools::getValue('controller_pages'); + $arr_controllers = explode(',', $controller); + $arr_controllers = array_map('trim', $arr_controllers); + + $modules_controllers_type = array('front' => $this->l('Front modules controller'), 'admin' => $this->l('Admin modules controller')); + Context::getContext()->smarty->assign(array( + '_core_' => $this->l('________________________________________ CORE ________________________________________'), + 'controller' => $controller, + 'arr_controllers' => $arr_controllers, + 'controllers' => $controllers, + 'modules_controllers_type' => $modules_controllers_type, + 'controllers_modules' => $controllers_modules, + )); + $content = Context::getContext()->smarty->fetch(apPageHelper::getShortcodeTemplatePath('ApRow.tpl')); + return $content; + } + + public function prepareFontContent($assign, $module = null) + { + // validate module + unset($module); + $form_atts = $assign['formAtts']; + + //process back-ground + $form_atts['bg_class'] = ''; + $form_atts['bg_data'] = ''; + $form_atts['parallax'] = ''; + $form_atts['bg_video'] = ''; + + //1. set class + if (isset($form_atts['bg_config']) && $form_atts['bg_config'] != 'none') { + $form_atts['bg_class'] = 'has-bg'; + //video + if (isset($form_atts['bg_type']) && ($form_atts['bg_type'] == 'video_youtube' || $form_atts['bg_type'] == 'video_youtube' || $form_atts['bg_type'] == 'video_youtube')) { + // validate module + $form_atts['bg_video'] = $this->getBgStyleVideo($form_atts); + } else { + if ($form_atts['bg_config'] == 'boxed') { + // validate module + $form_atts['bg_class'] .= ' bg-boxed'; + } else { + if (isset($form_atts['container']) && $form_atts['container']) { + // validate module + $form_atts['bg_class'] .= ' bg-fullwidth-container'; + } else { + $form_atts['id'] = (isset($form_atts['id']) && $form_atts['id'] != '') ? $form_atts['id'] : $form_atts['form_id']; + $form_atts['bg_class'] .= ' bg-fullwidth'; + } + } + if (isset($form_atts['bg_color']) && $form_atts['bg_color']) { + // validate module + $form_atts['bg_data'] .= ' '.$form_atts['bg_color']; + } + if (isset($form_atts['bg_img']) && $form_atts['bg_img']) { + if (strpos($form_atts['bg_img'], '/') == false) { + // validate module + $form_atts['bg_img'] = _THEME_IMG_DIR_.'modules/'.$this->module_name.'/images/'.$form_atts['bg_img']; + } + $form_atts['bg_data'] .= ' url('.$form_atts['bg_img'].')'; + } + if (isset($form_atts['bg_type']) && $form_atts['bg_type'] == 'fixed') { + // validate module + $form_atts['bg_data'] .= ' fixed'; + } + if ($form_atts['bg_repeat']) { + // validate module + $form_atts['bg_data'] .= ' '.$form_atts['bg_repeat']; + } + if (isset($form_atts['bg_position']) && $form_atts['bg_position']) { + // validate module + $form_atts['bg_data'] .= ' '.$form_atts['bg_position']; + } + if (isset($form_atts['bg_size']) && $form_atts['bg_size']) { + if (!empty($form_atts['bg_data'])) { + $form_atts['bg_data'] .= '; '; + } + + $form_atts['bg_data'] .= 'background-size: '.$form_atts['bg_size']; + } + //config for background style - stela - stela + if (isset($form_atts['bg_type']) && $form_atts['bg_type'] == 'parallax') { + $form_atts['bg_class'] .= ' bg-parallax'; + $hoffset = (isset($form_atts['parallax_hoffsets']) && $form_atts['parallax_hoffsets']) ? $form_atts['parallax_hoffsets'] : '40'; + $voffset = (isset($form_atts['parallax_voffsets']) && $form_atts['parallax_voffsets']) ? $form_atts['parallax_voffsets'] : '150'; + $bratio = (isset($form_atts['parallax_speed']) && $form_atts['parallax_speed']) ? $form_atts['parallax_speed'] : '0.5'; + + $form_atts['id'] = (isset($form_atts['id']) && $form_atts['id'] != '') ? $form_atts['id'] : $form_atts['form_id']; + + $form_atts['parallax'] = 'data-stellar-horizontal-offset="' + .$hoffset.'" data-stellar-vertical-offset="'.$voffset.'" data-stellar-background-ratio="'.$bratio.'"'; + } + + if (isset($form_atts['bg_type']) && $form_atts['bg_type'] == 'mouseparallax') { + $strength = (isset($form_atts['parallax_strength']) && $form_atts['parallax_strength']) ? $form_atts['parallax_strength'] : '40'; + $axis = (isset($form_atts['parallax_axis']) && $form_atts['parallax_axis']) ? $form_atts['parallax_axis'] : 'both'; + $rid = (isset($form_atts['parallax_rid']) && $form_atts['parallax_rid']) ? $form_atts['parallax_rid'] : '0.5'; + + $form_atts['id'] = $form_atts['form_id']; + + $form_atts['parallax'] = 'data-mouse-parallax-strength="'.$strength.'" data-mouse-parallax-axis="'.$axis.'" data-mouse-parallax-rid="'.$rid.'"'; + } + } + } + + if (isset($form_atts['bg_img']) && isset($form_atts['img_link'])) { + if ($form_atts['bg_img'] == '' && $form_atts['img_link'] != '') { + // validate module + $form_atts['bg_img'] = $form_atts['img_link']; + } + } + + if (!isset($form_atts['animation']) || $form_atts['animation'] == 'none') { + $form_atts['animation'] = 'none'; + $form_atts['animation_delay'] = ''; + } elseif ($form_atts['animation'] != 'none') { + // validate module + //DONGND:: add more config for animation + if ((int)$form_atts['animation_delay'] >= 0) { + $form_atts['animation_delay'] .= 's'; + } else { + $form_atts['animation_delay'] = '1s'; + } + + if (isset($form_atts['animation_duration']) && (int)$form_atts['animation_duration'] >= 0) { + $form_atts['animation_duration'] .= 's'; + } else { + $form_atts['animation_duration'] = '1s'; + } + + if (isset($form_atts['animation_iteration_count']) && (int)$form_atts['animation_iteration_count'] > 0) { + $form_atts['animation_iteration_count'] = (int)$form_atts['animation_iteration_count']; + } else { + $form_atts['animation_iteration_count'] = 1; + } + }; + + # set style + $assign['formAtts'] = $form_atts; + $form_atts['css_style'] = $this->showCSSStyle($assign); + $assign['formAtts']['css_style'] = $this->showCSSStyle($assign); + $this->checkFullwidth($assign); + + return $assign; + } + + public function checkFullwidth(&$assign) + { + $page_name = apPageHelper::getPageName(); + $hook_name = ApShortCodesBuilder::$hook_name; + + $hook_model = new ApPageBuilderHookModel(); + $hook_model->create(); + if ($page_name == 'index') { + $hooks = $hook_model->fullwidth_index_hook; + } else { + $hooks = $hook_model->fullwidth_other_hook; + } + + if (isset($hooks[$hook_name]) && $hooks[$hook_name] == ApPageSetting::HOOK_FULWIDTH_INDEXPAGE) { + // validate module + $assign['formAtts']['container_remove'] = '0'; + } else { + # remove container class - BEGIN + if (isset($assign['formAtts']['container'])) { + $str_search = array('/\bcontainer\b/'); + $str_replace = array(''); + $str_subject = $assign['formAtts']['container']; + + $assign['formAtts']['container'] = preg_replace($str_search, $str_replace, $str_subject); + $assign['formAtts']['container_remove'] = '1'; + } + # remove container class - END + } + } + + public function getHookLayout() + { + $hook_name = Tools::getValue('hook_name'); + + $hook_model = new ApPageBuilderHookModel(); + $hook_model->create(); + + return $hook_model->fullwidthHook($hook_name, 'index'); + } + + /** + * Live + * not follow in database + */ + public function getRowLayOut($hook_layout) + { + $row_layout = ApPageSetting::ROW_BOXED; + if ($hook_layout == ApPageSetting::HOOK_FULWIDTH_INDEXPAGE) { + $row_container = Tools::getValue('container'); + if (!preg_match('/\bcontainer\b/', $row_container)) { + // validate module + $row_layout = ApPageSetting::ROW_FULWIDTH_INDEXPAGE; + } + } + + return $row_layout; + } + + public function getDescriptionContainerInput() + { + $hook_layout = $this->getHookLayout(); + $row_layout = $this->getRowLayOut($hook_layout); + + $id_profile = Tools::getValue('id_appagebuilder_profiles'); + $url_profile_edit = Context::getContext()->link->getAdminLink('AdminApPageBuilderProfiles'). + '&id_appagebuilder_profiles='.$id_profile.'&updateappagebuilder_profiles'; + $link = 'edit profile'; + + $hook_name = Tools::getValue('hook_name'); + + $row_layout_text = 'Boxed'; + if ($row_layout) { + // validate module + $row_layout_text = 'Fullwidth'; + } + + $row_contain_class = 0; + $row_container = Tools::getValue('container'); + if (preg_match('/\bcontainer\b/', $row_container)) { + // validate module + $row_contain_class = 1; + } + if ($row_layout) { + # fullwidth + $desc = 'Now Layout of Row is '.$row_layout_text.', to change to Boxed :'; + $desc .= '
    '; + $desc .= '- Typing "container" to above textbox.'; + } else { + # boxed + $desc = 'Now Layout of Row is '.$row_layout_text.', to change to Fullwidth :'; + if ($row_contain_class) { + $desc .= '
    '; + $desc .= '- Removing "container" above textbox.'; + } + if ($hook_layout == ApPageSetting::HOOK_BOXED) { + $desc .= '
    '; + $desc .= '- Going to '.$link.' check option "'.$hook_name.'" hook of "Fullwidth Homepage"'; + } + } + return $desc; + } + + public function showCSSStyle($assign) + { + $form_atts = $assign['formAtts']; + $style = 'style="'; + if (isset($form_atts['bg_config']) && $form_atts['bg_config'] == 'boxed' && isset($form_atts['bg_data']) && $form_atts['bg_data']) { + $style .= 'background:'.$form_atts['bg_data'].';'; + } + if (isset($form_atts['min_height']) && $form_atts['min_height']) { + $style .= 'min-height: '.$form_atts['min_height'].';'; + } + if (isset($form_atts['margin_top']) && $form_atts['margin_top']) { + $style .= 'margin-top: '.$form_atts['margin_top'].';'; + } + if (isset($form_atts['margin_bottom']) && $form_atts['margin_bottom']) { + $style .= 'margin-bottom: '.$form_atts['margin_bottom'].';'; + } + if (isset($form_atts['padding_top']) && $form_atts['padding_top']) { + $style .= 'padding-top: '.$form_atts['padding_top'].';'; + } + if (isset($form_atts['padding_bottom']) && $form_atts['padding_bottom']) { + $style .= 'padding-bottom: '.$form_atts['padding_bottom'].';'; + } + $style .= '"'; + return $style; + } + + public function getPageName() + { + // Are we in a payment module + $module_name = ''; + if (Validate::isModuleName(Tools::getValue('module'))) { + $module_name = Tools::getValue('module'); + } + + if (!empty($this->page_name)) { + $page_name = $this->page_name; + } elseif (!empty($this->php_self)) { + $page_name = $this->php_self; + } elseif (Tools::getValue('fc') == 'module' && $module_name != '' && (Module::getInstanceByName($module_name) instanceof PaymentModule)) { + $page_name = 'module-payment-submit'; + } elseif (preg_match('#^'.preg_quote(Context::getContext()->shop->physical_uri, '#').'modules/([a-zA-Z0-9_-]+?)/(.*)$#', $_SERVER['REQUEST_URI'], $m)) { + // @retrocompatibility Are we in a module ? + $page_name = 'module-'.$m[1].'-'.str_replace(array('.php', '/'), array('', '-'), $m[2]); + } else { + $page_name = Dispatcher::getInstance()->getController(); + $page_name = (preg_match('/^[0-9]/', $page_name) ? 'page_'.$page_name : $page_name); + } + + return $page_name; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApSlideShow.php b/modules/appagebuilder/classes/shortcodes/ApSlideShow.php new file mode 100644 index 00000000..fbc0b496 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApSlideShow.php @@ -0,0 +1,141 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApSlideShow extends ApShortCodeBase +{ + public $name = 'ApSlideShow'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Slide show Module'), 'position' => 3, 'desc' => $this->l('You can get group from leoslideshow module'), + 'icon_class' => 'icon icon-chevron-right', 'tag' => 'content slider'); + } + + public function getConfigList() + { + if (Module::isInstalled('leoslideshow') && Module::isEnabled('leoslideshow')) { + include_once(_PS_MODULE_DIR_.'leoslideshow/leoslideshow.php'); + $module = new LeoSlideshow(); + $list = $module->getAllSlides(); + $controller = 'AdminModules'; + $id_lang = Context::getContext()->language->id; + $params = array('token' => Tools::getAdminTokenLite($controller), + 'configure' => 'leoslideshow', + 'tab_module' => 'front_office_features', + 'module_name' => 'leoslideshow'); + $url = dirname($_SERVER['PHP_SELF']).'/'.Dispatcher::getInstance()->createUrl($controller, $id_lang, $params, false); + if ($list && count($list) > 0) { + $inputs = array( + array( + 'type' => 'select', + 'label' => $this->l('Select a group for slideshow'), + 'name' => 'slideshow_group', + 'options' => array( + 'query' => $this->getListGroup($list), + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'value_by_categories', + 'default' => 'all' + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '' + ) + ); + } else { + // Go to page setting of the module LeoSlideShow + $inputs = array( + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '. + $this->l('There is no group slide in LeoSlideshow Module.'). + '

    ' + ) + ); + } + } else { + $inputs = array( + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '. + $this->l('"LeoSlideshow" Module must be installed and enabled before using.'). + '

    You can take this module at leo-theme or apollo-theme

    ' + ) + ); + } + return $inputs; + } + + public function getListGroup($list) + { + $result = array(); + foreach ($list as $item) { + $status = ' ('.($item['active'] ? $this->l('Active') : $this->l('Deactive')).')'; + $result[] = array('id' => $item['randkey'], 'name' => $item['title'].$status); + } + return $result; + } + + public function prepareFontContent($assign, $module = null) + { + if (Module::isInstalled('leoslideshow') && Module::isEnabled('leoslideshow')) { + $id_shop = (int)Context::getContext()->shop->id; + $assign['formAtts']['isEnabled'] = true; + include_once(_PS_MODULE_DIR_.'leoslideshow/leoslideshow.php'); + $module = new LeoSlideshow(); + $link_array = explode(',', $assign['formAtts']['slideshow_group']); + if ($link_array && !is_numeric($link_array['0'])) { + $randkey_group = ''; + foreach ($link_array as $val) { + // validate module + $randkey_group .= ($randkey_group == '') ? "'".pSQL($val)."'" : ",'".pSQL($val)."'"; + } + $where = ' WHERE randkey IN ('.$randkey_group.') AND id_shop = ' . (int)$id_shop; + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('SELECT id_leoslideshow_groups FROM `'._DB_PREFIX_.'leoslideshow_groups` '.$where); + $where = ''; + + if (is_array($result) && !empty($result)) { + foreach ($result as $slide) { + // validate module + $where .= ($where == '') ? $slide['id_leoslideshow_groups'] : ','.$slide['id_leoslideshow_groups']; + } + $assign['formAtts']['slideshow_group'] = $where; + $assign['content_slider'] = $module->processHookCallBack($assign['formAtts']['slideshow_group']); + } else { + $assign['formAtts']['isEnabled'] = false; + $assign['formAtts']['lib_has_error'] = true; + $assign['formAtts']['lib_error'] = 'Can not show LeoSlideShow via Appagebuilder. Please check that The Group of LeoSlideShow is exist.'; + } + } + } else { + $assign['formAtts']['isEnabled'] = false; + $assign['formAtts']['lib_has_error'] = true; + $assign['formAtts']['lib_error'] = 'Can not show LeoSlideShow via Appagebuilder. Please enable LeoSlideShow module.'; + } + return $assign; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApSliderLayer.php b/modules/appagebuilder/classes/shortcodes/ApSliderLayer.php new file mode 100644 index 00000000..a4f1ebf7 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApSliderLayer.php @@ -0,0 +1,138 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApSliderLayer extends ApShortCodeBase +{ + public $name = 'ApSliderLayer'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Slider Layer Module'), 'position' => 3, 'desc' => $this->l('You can group from leosliderlayer module to display'), + 'icon_class' => 'icon icon-chevron-right', 'tag' => 'content slider'); + } + + public function getConfigList() + { + if (Module::isInstalled('leosliderlayer') && Module::isEnabled('leosliderlayer')) { + include_once(_PS_MODULE_DIR_.'leosliderlayer/leosliderlayer.php'); + $module = new LeoSliderLayer(); + $list = $module->getAllSlides(); + $controller = 'AdminModules'; + $id_lang = Context::getContext()->language->id; + $params = array('token' => Tools::getAdminTokenLite($controller), + 'configure' => 'leosliderlayer', + 'tab_module' => 'front_office_features', + 'module_name' => 'leosliderlayer'); + $url = dirname($_SERVER['PHP_SELF']).'/'.Dispatcher::getInstance()->createUrl($controller, $id_lang, $params, false); + if ($list && count($list) > 0) { + $inputs = array( + array( + 'type' => 'select', + 'label' => $this->l('Select a group for slider layer'), + 'name' => 'slideshow_group', + 'options' => array( + 'query' => $this->getListGroup($list), + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'value_by_categories', + 'default' => 'all' + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '' + ) + ); + } else { + // Go to page setting of the module LeoSlideShow + $inputs = array( + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '. + $this->l('There is no group slide in Leosliderlayer Module.'). + '

    ' + ) + ); + } + } else { + $inputs = array( + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '. + $this->l('"Leosliderlayer" Module must be installed and enabled before using.'). + '

    You can take this module at leo-theme or apollo-theme

    ' + ) + ); + } + return $inputs; + } + + public function getListGroup($list) + { + $result = array(); + foreach ($list as $item) { + $status = ' ('.($item['active'] ? $this->l('Active') : $this->l('Deactive')).')'; + $result[] = array('id' => $item['id_leosliderlayer_groups'], 'name' => $item['title'].$status); + } + return $result; + } + + public function prepareFontContent($assign, $module = null) + { + if (Module::isInstalled('leosliderlayer') && Module::isEnabled('leosliderlayer')) { + $id_shop = Context::getContext()->shop->id; + $assign['formAtts']['isEnabled'] = true; + include_once(_PS_MODULE_DIR_.'leosliderlayer/leosliderlayer.php'); + $module = new LeoSliderLayer(); + //print_r($assign['slideshow_group']['slideshow_group']); + $link_array = explode(',', $assign['formAtts']['slideshow_group']); + if ($link_array && !is_numeric($link_array['0'])) { + $randkey_title = ''; + foreach ($link_array as $val) { + // validate module + $randkey_title .= ($randkey_title == '') ? "'".pSQL($val)."'" : ",'".pSQL($val)."'"; + } + + $where = ' WHERE title IN ('.$randkey_title.') AND id_shop = ' . (int)$id_shop; + $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('SELECT id_leoslideshow_groups FROM `'._DB_PREFIX_.'leoslideshow_groups` '.pSQL($where)); + $where = ''; + foreach ($result as $blog) { + // validate module + $where .= ($where == '') ? $blog['id_leoslideshow_groups'] : ','.$blog['id_leoslideshow_groups']; + } + $assign['formAtts']['slideshow_group'] = $where; + } + $assign['content_slider'] = $module->processHookCallBack($assign['formAtts']['slideshow_group']); + //$module->processHookCallBack(); + } else { + // validate module + $assign['formAtts']['isEnabled'] = false; + $assign['formAtts']['lib_has_error'] = true; + $assign['formAtts']['lib_error'] = 'Can not show LeoSliderLayer via Appagebuilder. Please enable LeoSliderLayer module.'; + } + return $assign; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApTabs.php b/modules/appagebuilder/classes/shortcodes/ApTabs.php new file mode 100644 index 00000000..667e1f6a --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApTabs.php @@ -0,0 +1,389 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApTabs extends ApShortCodeBase +{ + public $name = 'ApTabs'; + + public function getInfo() + { + return array('label' => $this->l('Tabs'), 'position' => 4, + 'desc' => $this->l('You can put widget in tab'), + 'icon_class' => 'icon-html5', 'tag' => 'content'); + } + + public function getConfigList($sub_tab = 0) + { + Context::getContext()->smarty->assign('path_image', apPageHelper::getImgThemeUrl()); + $href = Context::getContext()->link->getAdminLink('AdminApPageBuilderImages').'&ajax=1&action=manageimage&imgDir=images'; + if (Tools::getIsset('subTab') || $sub_tab) { + $input = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'lang' => 'true', + 'values' => '', + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '' + ), + array( + 'type' => 'text', + 'name' => 'id', + 'label' => $this->l('ID Tab'), + 'values' => '', + ), + array( + 'type' => 'text', + 'name' => 'css_class', + 'label' => $this->l('CSS Class'), + 'values' => '', + ), + array( + 'label' => $this->l('Image'), + 'type' => 'selectImg', + 'href' => $href, + 'name' => 'image', + 'lang' => false, + 'show_image' => true, + ), + ); + $this->name = 'ap_sub_tabs'; + } else { + $input = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'lang' => 'true', + 'default' => '', + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '' + ), + array( + 'type' => 'text', + 'name' => 'class', + 'label' => $this->l('CSS Class'), + 'default' => '', + ), + array( + 'type' => 'select', + 'label' => $this->l('Select Type'), + 'name' => 'tab_type', + 'options' => array( + 'query' => array( + array( + 'id' => 'tabs-top', + 'name' => $this->l('Tabs Top'), + ), + array( + 'id' => 'tabs-below', + 'name' => $this->l('Tabs below'), + ), + array( + 'id' => 'tabs-left', + 'name' => $this->l('Tabs Left'), + ), + array( + 'id' => 'tabs-right', + 'name' => $this->l('Tabs Right'), + ) + ), + 'id' => 'id', + 'name' => 'name' + ), + ), + array( + 'type' => 'text', + 'name' => 'active_tab', + 'label' => $this->l('Active Tab'), + 'default' => '1', + 'desc' => $this->l('Input position(number) to show tab. If Blank, all tab default is inactive.'), + ), + array( + 'type' => 'switch', + 'label' => $this->l('Use Fade effect'), + 'name' => 'fade_effect', + 'is_bool' => true, + 'desc' => $this->l('To make tabs fade in.'), + 'values' => ApPageSetting::returnYesNo(), + ) + ); + } + return $input; + } + + public function endRenderForm() + { + $this->helper->module = new $this->module_name(); + } + + /** + * Overide in tabs module + * @param type $atts + * @param type $content + * @param type $tag_name + * @param type $is_gen_html + * @return type + */ + public function adminContent($atts, $content = null, $tag_name = null, $is_gen_html = null) + { + $this->preparaAdminContent($atts, $tag_name); + if ($is_gen_html) { + $assign = array(); + $assign['formAtts'] = $atts; + $w_info = $this->getInfo(); + $w_info['name'] = $this->name; + $assign['apInfo'] = $w_info; + if ($tag_name == 'ApTab') { + $assign['tabID'] = $atts['id']; + $assign['isSubTab'] = 1; + $w_info['name'] = 'ApTab'; + } else { + preg_match_all('/ApTab form_id="([^\"]+)" id\=\"([^\"]+)\" css_class\=\"([^\"]+){0,1}\" title\=\"([^\"]+)\"{0,1}/i', $content, $matches, PREG_OFFSET_CAPTURE); + $sub_tab_content = array(); + $len = count($matches[0]); + for ($i = 0; $i < $len; $i++) { + $title = $matches[4][$i][0]; + $title = str_replace($this->str_search, $this->str_relace_html, $title); + $form_id = $matches[1][$i][0]; + $sub_tab_content[$form_id] = array( + 'form_id' => $form_id, + 'id' => $matches[2][$i][0], + 'css_class' => $matches[3][$i][0], + 'title' => $title, + ); + } + // validate module + $pattern = '/ApTab form_id="([^\"]+)" id\=\"([^\"]+)\" css_class\=\"([^\"]+){0,1}\" '; + $pattern .= 'override_folder\=\"([^\"]+){0,1}\" title\=\"([^\"]+)\"{0,1}/i'; + preg_match_all($pattern, $content, $matches2, PREG_OFFSET_CAPTURE); + $sub_tab_content2 = array(); + $len2 = count($matches2[0]); + for ($i = 0; $i < $len2; $i++) { + $title2 = $matches2[5][$i][0]; + $title2 = str_replace($this->str_search, $this->str_relace_html, $title2); + $form_id2 = $matches2[1][$i][0]; + $sub_tab_content2[$form_id2] = array( + 'form_id' => $form_id2, + 'id' => $matches2[2][$i][0], + 'css_class' => $matches2[3][$i][0], + 'title' => $title2, + ); + } + + $pattern = '/ApTab form_id="([^\"]+)" id\=\"([^\"]+)\" css_class\=\"([^\"]+){0,1}\" image\=\"([^\"]+){0,1}\" override_folder\=\"([^\"]+){0,1}\" title\=\"([^\"]+){0,1}\" sub_title\=\"([^\"]+){0,1}/i'; + preg_match_all($pattern, $content, $matches3, PREG_OFFSET_CAPTURE); + $sub_tab_content3 = array(); + $len3 = count($matches3[0]); + for ($i = 0; $i < $len3; $i++) { + $title3 = $matches3[6][$i][0]; + $title3 = str_replace($this->str_search, $this->str_relace_html, $title3); + $sub_title = isset($matches3[7][$i][0]) ? $matches3[7][$i][0] : ''; + $sub_title = str_replace($this->str_search, $this->str_relace_html, $sub_title); + + $form_id3 = $matches3[1][$i][0]; + $sub_tab_content3[$form_id3] = array( + 'form_id' => $form_id3, + 'id' => $matches3[2][$i][0], + 'css_class' => $matches3[3][$i][0], + 'title' => $title3, + 'sub_title' => $sub_title, + ); + } + $assign['subTabContent'] = array_merge($sub_tab_content, $sub_tab_content2, $sub_tab_content3); + } + $assign['apContent'] = ApShortCodesBuilder::doShortcode($content); + $controller = new AdminApPageBuilderShortcodesController(); + return $controller->adminContent($assign, $this->name.'.tpl'); + } else { + ApShortCodesBuilder::doShortcode($content); + } + //preg_match_all( '/ap_tab id="([^\"]+)"(\id\=\"([^\"]+)\"){0,1}/i', $content, $matches, PREG_OFFSET_CAPTURE ); + } + + /** + * Overide in tabs module + * @param type $atts + * @param type $content + * @param type $tag_name + * @param type $is_gen_html + * @return type + */ + public function fontContent($atts, $content = null, $tag_name = null, $is_gen_html = null) + { + $is_active = $this->isWidgetActive(array('formAtts' => $atts)); + if (!$is_active) { + return ''; + } + + foreach ($atts as $key => $val) { + if (strpos($key, 'content') !== false || strpos($key, 'link') !== false || strpos($key, 'url') !== false || strpos($key, 'alt') !== false || strpos($key, 'tit') !== false || strpos($key, 'name') !== false || strpos($key, 'desc') !== false || strpos($key, 'itemscustom') !== false) { + $atts[$key] = str_replace($this->str_search, $this->str_relace_html, $val); + if (strpos($atts[$key], '_AP_IMG_DIR') !== false) { + // validate module + $atts[$key] = str_replace('_AP_IMG_DIR/', $this->theme_img_module, $atts[$key]); + } + } + } + // validate module + unset($is_gen_html); + $assign = array(); + + if ($tag_name == 'ApTabs') { + // ApTabs + $assign['tab_name'] = 'ApTabs'; + preg_match_all('/ApTab form_id="([^\"]+)" id\=\"([^\"]+)\" css_class\=\"([^\"]+){0,1}\" image\=\"([^\"]+)\" title\=\"([^\"]+)\"{0,1}/i', $content, $matches, PREG_OFFSET_CAPTURE); + $sub_tab_content = array(); + $len = count($matches[0]); + for ($i = 0; $i < $len; $i++) { + $title = $matches[4][$i][0]; + $title = str_replace($this->str_search, $this->str_relace_html, $title); + $sub_tab_content[] = array( + 'form_id' => $matches[1][$i][0], + 'id' => $matches[2][$i][0], + 'css_class' => $matches[3][$i][0], + 'title' => $title, + ); + } + $pattern = '/ApTab form_id="([^\"]+)" id\=\"([^\"]+)\" css_class\=\"([^\"]+){0,1}\" override_folder\=\"([^\"]+){0,1}\" title\=\"([^\"]+)\"{0,1}/i'; + preg_match_all($pattern, $content, $matches2, PREG_OFFSET_CAPTURE); + $sub_tab_content2 = array(); + $len2 = count($matches2[0]); + for ($i = 0; $i < $len2; $i++) { + $title2 = $matches2[5][$i][0]; + $title2 = str_replace($this->str_search, $this->str_relace_html, $title2); + $form_id2 = $matches2[1][$i][0]; + $sub_tab_content2[$form_id2] = array( + 'form_id' => $form_id2, + 'id' => $matches2[2][$i][0], + 'css_class' => $matches2[3][$i][0], + 'title' => $title2, + ); + } + + $pattern = '/ApTab form_id="([^\"]+)" id\=\"([^\"]+)\" css_class\=\"([^\"]+){0,1}\" image\=\"([^\"]+){0,1}\" override_folder\=\"([^\"]+){0,1}\" title\=\"([^\"]+){0,1}\" sub_title\=\"([^\"]+){0,1}/i'; + preg_match_all($pattern, $content, $matches3, PREG_OFFSET_CAPTURE); + $sub_tab_content3 = array(); + $len3 = count($matches3[0]); + for ($i = 0; $i < $len3; $i++) { + $title3 = $matches3[6][$i][0]; + $title3 = str_replace($this->str_search, $this->str_relace_html, $title3); + $sub_title = isset($matches3[7][$i][0]) ? $matches3[7][$i][0] : ''; + $sub_title = str_replace($this->str_search, $this->str_relace_html, $sub_title); + + $form_id3 = $matches3[1][$i][0]; + $sub_tab_content3[$form_id3] = array( + 'form_id' => $form_id3, + 'id' => $matches3[2][$i][0], + 'css_class' => $matches3[3][$i][0], + 'title' => $title3, + 'image' => $matches3[4][$i][0], + 'sub_title' => $sub_title, + ); + } + if (isset($atts['active_tab']) && $atts['active_tab'] != '') { + $tab_count = substr_count($content, '[ApTab'); + $tab_active = (int)$atts['active_tab']; + + if (($tab_active <= $tab_count) && ($tab_active >= 1)) { + # ACTIVE TAB + $atts['active_tab'] = $tab_active - 1; + } elseif ($tab_active > $tab_count) { + # ACTIVE LAST TAB + $atts['active_tab'] = $tab_count - 1; + } else { + # ACTIVE FIRST TAB + $atts['active_tab'] = 0; + } + } else { + # BLANK + $atts['active_tab'] = -1; + } + $assign['subTabContent'] = array_merge($sub_tab_content, $sub_tab_content2, $sub_tab_content3); + $atts['id'] = 'tab_'.ApPageSetting::getRandomNumber(); + $atts['class'] = ((isset($atts['class']) && $atts['class']) ? $atts['class'].' ' : '').(isset($atts['tab_type']) ? $atts['tab_type'] : ''); + + $assign['formAtts'] = $atts; + $module = APPageBuilder::getInstance(); + $assign['path'] = apPageHelper::getImgThemeUrl(); + $assign['apContent'] = ApShortCodesBuilder::doShortcode($content); + return $module->fontContent($assign, $this->name.'.tpl'); + } else { + // ApTab + $assign['tabID'] = $atts['id']; + $assign['tab_name'] = 'ApTab'; + $assign['isSubTab'] = 1; + + $assign['formAtts'] = $atts; + $module = APPageBuilder::getInstance(); + $assign['path'] = apPageHelper::getImgThemeUrl(); + $assign['apContent'] = ApShortCodesBuilder::doShortcode($content); + return $module->fontContent($assign, $this->name.'.tpl'); + } + } + + /** + * @Override + * Fixed css_class is empty -> cant set to $apHomeBuilder.process (json) in javascript + */ + public function preparaAdminContent($atts, $tag_name = null) + { + if ($tag_name == null) { + $tag_name = $this->name; + } + if (is_array($atts)) { + if (!isset(ApShortCodesBuilder::$shortcode_lang[$tag_name])) { + $inputs = $this->getConfigList(); + $lang_field = array(); + foreach ($inputs as $input) { + if (isset($input['lang']) && $input['lang']) { + $lang_field[] = $input['name']; + } + } + ApShortCodesBuilder::$shortcode_lang[$tag_name] = $lang_field; + } else { + $lang_field = ApShortCodesBuilder::$shortcode_lang[$tag_name]; + } + foreach ($atts as $key => $val) { + if ($lang_field && in_array($key, $lang_field)) { + $key .= '_'.ApShortCodesBuilder::$lang_id; + } + if (!isset(ApShortCodesBuilder::$data_form[$atts['form_id']][$key])) { + ApShortCodesBuilder::$data_form[$atts['form_id']][$key] = $val; + } + } + } + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApTwitter.php b/modules/appagebuilder/classes/shortcodes/ApTwitter.php new file mode 100644 index 00000000..98c44f8b --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApTwitter.php @@ -0,0 +1,194 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApTwitter extends ApShortCodeBase +{ + public $name = 'ApTwitter'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Twitter'), + 'position' => 6, + 'desc' => $this->l('You can config for display Twitter box'), + 'icon_class' => 'icon-twitter-sign', + 'tag' => 'social'); + } + + public function getConfigList() + { + $accordion_type = array( + array( + 'value' => 'full', + 'text' => $this->l('Always Full') + ), + array( + 'value' => 'accordion', + 'text' => $this->l('Always Accordion') + ), + array( + 'value' => 'accordion_small_screen', + 'text' => $this->l('Accordion at small screen') + ), + ); + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'form_group_class' => 'aprow_general', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'select', + 'label' => $this->l('Accordion Type'), + 'name' => 'accordion_type', + 'options' => array( + 'query' => $accordion_type, + 'id' => 'value', + 'name' => 'text' ), + 'default' => 'full', + 'hint' => $this->l('Select a Accordion Type'), + ), + array( + 'type' => 'text', + 'label' => $this->l('Twitter'), + 'name' => 'twidget_id', + 'default' => '578806287158251521', + 'desc' => $this->l('Please go to the page https://twitter.com/settings/widgets/new, then create a widget, and get data-widget-id to input in this param.'), + ), + array( + 'type' => 'text', + 'label' => $this->l('Count'), + 'name' => 'count', + 'default' => 2, + 'desc' => $this->l('If the param is empty or equal 0, the widget will show scrollbar when more items. Or you can input number from 1-20. Default NULL.'), + ), + array( + 'type' => 'text', + 'label' => $this->l('User'), + 'name' => 'username', + 'default' => 'prestashop', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '', + ), + array( + 'type' => 'color', + 'label' => $this->l('Border Color'), + 'name' => 'border_color', + 'default' => '#000', + ), + array( + 'type' => 'color', + 'label' => $this->l('Link Color'), + 'name' => 'link_color', + 'default' => '#000', + ), + array( + 'type' => 'color', + 'label' => $this->l('Text Color'), + 'name' => 'text_color', + 'default' => '#000', + ), + array( + 'type' => 'color', + 'label' => $this->l('Name Color'), + 'name' => 'name_color', + 'default' => '#000', + ), + array( + 'type' => 'color', + 'label' => $this->l('Nick name Color'), + 'name' => 'mail_color', + 'default' => '#000', + ), + array( + 'type' => 'text', + 'label' => $this->l('Width'), + 'name' => 'width', + 'default' => 180, + ), + array( + 'type' => 'text', + 'label' => $this->l('Height'), + 'name' => 'height', + 'default' => 200, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show background'), + 'name' => 'transparent', + 'values' => ApPageSetting::returnYesNo(), + 'default' => 0, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show Replies'), + 'name' => 'show_replies', + 'values' => ApPageSetting::returnYesNo(), + 'default' => 0, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show Header'), + 'name' => 'show_header', + 'values' => ApPageSetting::returnYesNo(), + 'default' => 0, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show Footer'), + 'name' => 'show_footer', + 'values' => ApPageSetting::returnYesNo(), + 'default' => 0, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show Border'), + 'name' => 'show_border', + 'values' => ApPageSetting::returnYesNo(), + 'default' => 0, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Show Scrollbar'), + 'name' => 'show_scrollbar', + 'values' => ApPageSetting::returnYesNo(), + 'desc' => $this->l('If the param is empty or equal 0, the widget will show scrollbar when more items. Or you can input number from 1-20. Default NULL.'), + 'hint' => $this->l('Twitter not Show Scrollbar if you set a number of Tweets is specified. Please not set value for input Count.'), + ) + ); + return $inputs; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/ApVideo.php b/modules/appagebuilder/classes/shortcodes/ApVideo.php new file mode 100644 index 00000000..3297c911 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/ApVideo.php @@ -0,0 +1,84 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class ApVideo extends ApShortCodeBase +{ + public $name = 'ApVideo'; + public $for_module = 'manage'; + + public function getInfo() + { + return array('label' => $this->l('Video'), + 'position' => 5, + 'desc' => $this->l('Embed video box'), + 'icon_class' => 'icon-facetime-video', + 'tag' => 'social'); + } + + public function getConfigList() + { + $inputs = array( + array( + 'type' => 'text', + 'name' => 'title', + 'label' => $this->l('Title'), + 'desc' => $this->l('Auto hide if leave it blank'), + 'lang' => 'true', + 'form_group_class' => 'aprow_general', + 'default' => '' + ), + array( + 'type' => 'textarea', + 'name' => 'sub_title', + 'label' => $this->l('Sub Title'), + 'lang' => true, + 'values' => '', + 'autoload_rte' => false, + 'default' => '', + ), + array( + 'type' => 'textarea', + 'label' => $this->l('Code'), + 'name' => 'content_html', + 'cols' => 40, + 'rows' => 10, + 'value' => true, + 'default' => '', + 'desc' => $this->l('Example embed video: "<div class="embed-responsive"><iframe src="https://www.youtube.com/embed/iZoR21juRzs" frameborder="0" allowfullscreen></iframe></div>"'), + 'autoload_rte' => false, + ), + array( + 'type' => 'select', + 'label' => $this->l('Align'), + 'name' => 'align', + 'options' => array('query' => array( + array('id' => 'left', 'name' => $this->l('Left')), + array('id' => 'center', 'name' => $this->l('Center')), + array('id' => 'right', 'name' => $this->l('Right')) + ), + 'id' => 'id', + 'name' => 'name' + ), + 'default' => 'center', + ) + ); + return $inputs; + } +} diff --git a/modules/appagebuilder/classes/shortcodes/index.php b/modules/appagebuilder/classes/shortcodes/index.php new file mode 100644 index 00000000..6bf70e95 --- /dev/null +++ b/modules/appagebuilder/classes/shortcodes/index.php @@ -0,0 +1,36 @@ + +* @copyright 2007-2012 PrestaShop SA +* @version Release: $Revision: 13573 $ +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/modules/appagebuilder/config.xml b/modules/appagebuilder/config.xml new file mode 100644 index 00000000..523ebd86 --- /dev/null +++ b/modules/appagebuilder/config.xml @@ -0,0 +1,12 @@ + + + appagebuilder + + + + + + 1 + 0 + + \ No newline at end of file diff --git a/modules/appagebuilder/config_pl.xml b/modules/appagebuilder/config_pl.xml new file mode 100644 index 00000000..523ebd86 --- /dev/null +++ b/modules/appagebuilder/config_pl.xml @@ -0,0 +1,12 @@ + + + appagebuilder + + + + + + 1 + 0 + + \ No newline at end of file diff --git a/modules/appagebuilder/controllers/admin/AdminApPageBuilder.php b/modules/appagebuilder/controllers/admin/AdminApPageBuilder.php new file mode 100644 index 00000000..f0bd8636 --- /dev/null +++ b/modules/appagebuilder/controllers/admin/AdminApPageBuilder.php @@ -0,0 +1,40 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class AdminApPageBuilderController extends ModuleAdminControllerCore +{ + public static $shortcode_lang; + public static $lang_id; + public static $language; + public $error_text = ''; + public $theme_name; + + public function __construct() + { + $url = 'index.php?controller=adminmodules&configure=appagebuilder&token='.Tools::getAdminTokenLite('AdminModules') + .'&tab_module=Home&module_name=appagebuilder'; + Tools::redirectAdmin($url); + $this->bootstrap = true; + $this->className = 'Configuration'; + $this->table = 'configuration'; + $this->theme_name = _THEME_NAME_; + parent::__construct(); + } +} diff --git a/modules/appagebuilder/controllers/admin/AdminApPageBuilderDetails.php b/modules/appagebuilder/controllers/admin/AdminApPageBuilderDetails.php new file mode 100644 index 00000000..175ef949 --- /dev/null +++ b/modules/appagebuilder/controllers/admin/AdminApPageBuilderDetails.php @@ -0,0 +1,601 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageBuilderDetailsModel.php'); + +class AdminApPageBuilderDetailsController extends ModuleAdminControllerCore +{ + private $theme_name = ''; + public $module_name = 'appagebuilder'; + public $tpl_save = ''; + public $file_content = array(); + public $explicit_select; + public $order_by; + public $order_way; + public $profile_css_folder; + public $module_path; +// public $module_path_resource; + public $str_search = array(); + public $str_relace = array(); + public $theme_dir; + + public function __construct() + { + $this->bootstrap = true; + $this->table = 'appagebuilder_details'; + $this->className = 'ApPageBuilderDetailsModel'; + $this->lang = false; + $this->explicit_select = true; + $this->allow_export = true; + $this->context = Context::getContext(); + $this->_join = ' + INNER JOIN `'._DB_PREFIX_.'appagebuilder_details_shop` ps ON (ps.`id_appagebuilder_details` = a.`id_appagebuilder_details`)'; + $this->_select .= ' ps.active as active, '; + + $this->order_by = 'id_appagebuilder_details'; + $this->order_way = 'DESC'; + parent::__construct(); + $this->fields_list = array( + 'id_appagebuilder_details' => array( + 'title' => $this->l('ID'), + 'align' => 'center', + 'width' => 50, + 'class' => 'fixed-width-xs' + ), + 'name' => array( + 'title' => $this->l('Name'), + 'width' => 140, + 'type' => 'text', + 'filter_key' => 'a!name' + ), + 'plist_key' => array( + 'title' => $this->l('Product List Key'), + 'filter_key' => 'a!plist_key', + 'type' => 'text', + 'width' => 140, + ), + 'class_detail' => array( + 'title' => $this->l('Class'), + 'width' => 140, + 'type' => 'text', + 'filter_key' => 'a!class_detail', + 'orderby' => false + ), + 'active' => array( + 'title' => $this->l('Is Default'), + 'active' => 'status', + 'filter_key' => 'ps!active', + 'align' => 'text-center', + 'type' => 'bool', + 'class' => 'fixed-width-sm', + 'orderby' => false + ), + ); + $this->bulk_actions = array( + 'delete' => array( + 'text' => $this->l('Delete selected'), + 'confirm' => $this->l('Delete selected items?'), + 'icon' => 'icon-trash' + ) + ); + $this->theme_dir = _PS_THEME_DIR_; + + $this->_where = ' AND ps.id_shop='.(int)$this->context->shop->id; + $this->theme_name = _THEME_NAME_; + $this->profile_css_folder = $this->theme_dir.'modules/'.$this->module_name.'/'; + $this->module_path = __PS_BASE_URI__.'modules/'.$this->module_name.'/'; +// $this->module_path_resource = $this->module_path.'views/'; + $this->str_search = array('_APAMP_', '_APQUOT_', '_APAPOST_', '_APTAB_', '_APNEWLINE_', '_APENTER_', '_APOBRACKET_', '_APCBRACKET_', '_APOCBRACKET_', '_APCCBRACKET_',); + $this->str_relace = array('&', '\"', '\'', '\t', '\r', '\n', '[', ']', '{', '}'); + } + + public function renderView() + { + $object = $this->loadObject(); + if ($object->page == 'product_detail') { + $this->redirect_after = Context::getContext()->link->getAdminLink('AdminApPageBuilderProductDetail'); + } else { + $this->redirect_after = Context::getContext()->link->getAdminLink('AdminApPageBuilderHome'); + } + $this->redirect_after .= '&id_appagebuilder_details='.$object->id; + $this->redirect(); + } + + public function postProcess() + { + parent::postProcess(); + if (count($this->errors) > 0) { + return; + } + + if (Tools::getIsset('duplicateappagebuilder_details')) { + $id = Tools::getValue('id_appagebuilder_details'); + $model = new ApPageBuilderDetailsModel($id); + $duplicate_object = $model->duplicateObject(); + $duplicate_object->name = $this->l('Duplicate of').' '.$duplicate_object->name; + $old_key = $duplicate_object->plist_key; + $duplicate_object->plist_key = 'detail'.ApPageSetting::getRandomNumber(); + if ($duplicate_object->add()) { + //duplicate shortCode + $filecontent = Tools::file_get_contents(apPageHelper::getConfigDir('theme_details').$old_key.'.tpl'); + ApPageSetting::writeFile(apPageHelper::getConfigDir('theme_details'), $duplicate_object->plist_key.'.tpl', $filecontent); + $this->redirect_after = self::$currentIndex.'&token='.$this->token; + $this->redirect(); + } else { + Tools::displayError('Can not duplicate Profiles'); + } + } + if (Tools::isSubmit('saveELement')) { + $filecontent = Tools::getValue('filecontent'); + $fileName = Tools::getValue('fileName'); + apPageHelper::createDir(apPageHelper::getConfigDir('theme_details')); + ApPageSetting::writeFile(apPageHelper::getConfigDir('theme_details'), $fileName.'.tpl', $filecontent); + } + } + + public function convertObjectToTpl($object_form) + { + $tpl = ''; + + foreach ($object_form as $object) { + if ($object['name'] == 'functional_buttons') { + //DONGND:: fix can save group column when change class + if (isset($object['form']['class']) && $object['form']['class'] != '') { + $tpl .= '
    '; + } else { + $tpl .= '
    '; + } + foreach ($object['columns'] as $objectC) { + $tpl .= '
    '; + $tpl .= $this->convertObjectToTpl($objectC['sub']); + $tpl .= ' +
    '; + } + + $tpl .= '
    '; + } else if ($object['name'] == 'code') { + $tpl .= $object['code']; + } else { + if (!isset($this->file_content[$object['name']])) { + $this->returnFileContent($object['name']); + //DONGND:: add config to type gallery + if ($object['name'] == "product_image_with_thumb" || $object['name'] == "product_image_show_all") { + $strdata = ''; + foreach ($object['form'] as $key => $value) { + $strdata .= ' data-'.$key.'="'.$value.'"'; + } + $this->file_content[$object['name']] = str_replace('id="content">', 'id="content"'.$strdata.'>', $this->file_content[$object['name']]); + } + } + //add class + $tpl .= $this->file_content[$object['name']]; + } + } + return $tpl; + } + + public function convertToColumnClass($form) + { + $class = ''; + foreach ($form as $key => $val) { + //DONGND:: check class name of column + if ($key == 'class') { + if ($val != '') { + $class .= ($class=='')?$val:' '.$val; + } + } else { + $class .= ($class=='')?'col-'.$key.'-'.$val:' col-'.$key.'-'.$val; + } + } + return $class; + } + + public function returnFileContent($pelement) + { + $tpl_dir = apPageHelper::getConfigDir('theme_details').$pelement.'.tpl'; + if (!file_exists($tpl_dir)) { + $tpl_dir = apPageHelper::getConfigDir('module_details').$pelement.'.tpl'; + } + $this->file_content[$pelement] = Tools::file_get_contents($tpl_dir); + return $this->file_content[$pelement]; + } + + public function renderList() + { + if (Tools::getIsset('pelement')) { + $helper = new HelperForm(); + $helper->submit_action = 'saveELement'; + $inputs = array( + array( + 'type' => 'textarea', + 'name' => 'filecontent', + 'label' => $this->l('File Content'), + 'desc' => $this->l('Please carefully when edit tpl file'), + ), + array( + 'type' => 'hidden', + 'name' => 'fileName', + ) + ); + $fields_form = array( + 'form' => array( + 'legend' => array( + 'title' => sprintf($this->l('You are Editing file: %s'), Tools::getValue('pelement').'.tpl'), + 'icon' => 'icon-cogs' + ), + 'action' => Context::getContext()->link->getAdminLink('AdminApPageBuilderShortcodes'), + 'input' => $inputs, + 'name' => 'importData', + 'submit' => array( + 'title' => $this->l('Save'), + 'class' => 'button btn btn-default pull-right' + ), + 'tinymce' => false, + ), + ); + $helper->tpl_vars = array( + 'fields_value' => $this->getFileContent() + ); + return $helper->generateForm(array($fields_form)); + } + $this->initToolbar(); + $this->addRowAction('edit'); + $this->addRowAction('duplicate'); + $this->addRowAction('delete'); + return parent::renderList(); + } + + public function getFileContent() + { + $pelement = Tools::getValue('pelement'); + $tpl_dir = apPageHelper::getConfigDir('theme_details').$pelement.'.tpl'; + if (!file_exists($tpl_dir)) { + $tpl_dir = apPageHelper::getConfigDir('module_details').$pelement.'.tpl'; + } + return array('fileName' => $pelement, 'filecontent' => Tools::file_get_contents($tpl_dir)); + } + + public function setHelperDisplay(Helper $helper) + { + parent::setHelperDisplay($helper); + $this->helper->module = APPageBuilder::getInstance(); + } + + public function processDelete() + { + $object = $this->loadObject(); + Tools::deleteFile(apPageHelper::getConfigDir('theme_details').$object->plist_key.'.tpl'); + parent::processDelete(); + } + + public function renderForm() + { + $this->initToolbar(); + $this->context->controller->addJqueryUI('ui.sortable'); + $this->context->controller->addJqueryUI('ui.draggable'); + //$this->context->controller->addJs(apPageHelper::getJsAdminDir().'admin/form.js'); + $this->context->controller->addJs(apPageHelper::getJsAdminDir().'admin/detail.js'); + $this->context->controller->addCss(apPageHelper::getCssAdminDir().'admin/form.css'); + $source_file = Tools::scandir(apPageHelper::getConfigDir('theme_details'), 'tpl'); + + if (is_dir(apPageHelper::getConfigDir('theme_details'))) { + $source_template_file = Tools::scandir(apPageHelper::getConfigDir('theme_details'), 'tpl'); + $source_file = array_merge($source_file, $source_template_file); + } + + $params = array('gridLeft' => array(), 'gridRight' => array()); + + $this->object->params = str_replace($this->str_search, $this->str_relace, $this->object->params); + + $config_dir = apPageHelper::getConfigDir('theme_details') . 'config.json'; + if (!file_exists($config_dir)) { + $config_dir = apPageHelper::getConfigDir('module_details') . 'config.json'; + } + + $config_file = Tools::jsonDecode(Tools::file_get_contents($config_dir), true); + $element_by_name = array(); + foreach ($config_file as $k1 => $groups) { + foreach ($groups['group'] as $k2 => $group) { + $config_file[$k1]['group'][$k2]['dataForm'] = (!isset($group['data-form']))?'':Tools::jsonEncode($group['data-form']); + if (isset($group['file'])) { + $element_by_name[$group['file']] = $group; + } + } + } + + if (isset($this->object->params)) { + //add sample data + if (Tools::getIsset('sampledetail')) { + switch (Tools::getValue('sampledetail')) { + case 'product_image_thumbs_bottom': + $this->object->url_img_preview = 'https://i.pinimg.com/originals/8c/16/f9/8c16f9f024af16977adc1f618872eb8b.jpg'; + $this->object->params = '{"gridLeft":{"0":{"name":"functional_buttons","form":"","columns":{"0":{"form":{"form_id":"form_9367402777406408","md":6,"lg":6,"xl":6,"sm":12,"xs":12,"sp":12},"element":"column","sub":{"0":{"name":"product_image_with_thumb","form":{"templateview":"bottom","numberimage":"5","numberimage1200":"5","numberimage992":"4","numberimage768":"3","numberimage576":"3","numberimage480":"2","numberimage360":"2","templatemodal":"1","templatezoomtype":"out","zoomposition":"right","zoomwindowwidth":"400","zoomwindowheight":"400"}}}},"1":{"form":{"form_id":"form_15874367062488778","md":6,"lg":6,"xl":6,"sm":12,"xs":12,"sp":12},"element":"column","sub":{"0":{"name":"product_detail_name","form":""},"1":{"name":"hook_display_product_additional_info","form":""},"2":{"name":"hook_display_leo_product_review_extra","form":""},"3":{"name":"product_price","form":""},"4":{"name":"product_description_short","form":""},"5":{"name":"product_customization","form":""},"6":{"name":"product_actions_form","form":""},"7":{"name":"hook_display_reassurance","form":""}}},"2":{"form":{"form_id":"form_4666379129988496","md":12,"lg":12,"xl":12,"sm":12,"xs":12,"sp":12},"element":"column","sub":{"0":{"name":"product_more_info_tab","form":""},"1":{"name":"product_accessories","form":""},"2":{"name":"hook_display_footer_product","form":""}}}}}},"class":"product-image-thumbs product-thumbs-bottom"}'; + break; + case 'product_image_thumbs_left': + $this->object->url_img_preview = 'https://i.pinimg.com/originals/98/b4/b0/98b4b05fef8913b2a37cbb592b921e7b.jpg'; + $this->object->params = '{"gridLeft":{"0":{"name":"functional_buttons","form":"","columns":{"0":{"form":{"md":6,"lg":6,"xl":6,"sm":12,"xs":12,"sp":12},"element":"column","sub":{"0":{"name":"product_image_with_thumb","form":{"templateview":"left","numberimage":"5","numberimage1200":"4","numberimage992":"4","numberimage768":"3","numberimage576":"3","numberimage480":"2","numberimage360":"2","templatemodal":"1","templatezoomtype":"in","zoomposition":"right","zoomwindowwidth":"400","zoomwindowheight":"400"}}}},"1":{"form":{"md":6,"lg":6,"xl":6,"sm":12,"xs":12,"sp":12},"element":"column","sub":{"0":{"name":"product_detail_name","form":""},"1":{"name":"hook_display_product_additional_info","form":""},"2":{"name":"hook_display_leo_product_review_extra","form":""},"3":{"name":"product_price","form":""},"4":{"name":"product_description_short","form":""},"5":{"name":"product_customization","form":""},"6":{"name":"product_actions_form","form":""},"7":{"name":"hook_display_reassurance","form":""}}},"2":{"form":{"md":12,"lg":12,"xl":12,"sm":12,"xs":12,"sp":12},"element":"column","sub":{"0":{"name":"product_more_info_accordions","form":""},"1":{"name":"product_accessories","form":""},"2":{"name":"hook_display_footer_product","form":""}}}}}},"class":"product-image-thumbs product-thumbs-left"}'; + break; + case 'product_image_thumbs_right': + $this->object->url_img_preview = 'https://i.pinimg.com/originals/81/c4/41/81c441c1b2f6c3e56b3da56b65324423.jpg'; + $this->object->params = '{"gridLeft":{"0":{"name":"functional_buttons","form":"","columns":{"0":{"form":{"md":6,"lg":6,"xl":6,"sm":12,"xs":12,"sp":12},"element":"column","sub":{"0":{"name":"product_image_with_thumb","form":{"templateview":"right","numberimage":"5","numberimage1200":"4","numberimage992":"4","numberimage768":"3","numberimage576":"3","numberimage480":"2","numberimage360":"2","templatemodal":"1","templatezoomtype":"in","zoomposition":"right","zoomwindowwidth":"400","zoomwindowheight":"400"}}}},"1":{"form":{"md":6,"lg":6,"xl":6,"sm":12,"xs":12,"sp":12},"element":"column","sub":{"0":{"name":"product_detail_name","form":""},"1":{"name":"hook_display_product_additional_info","form":""},"2":{"name":"hook_display_leo_product_review_extra","form":""},"3":{"name":"product_price","form":""},"4":{"name":"product_description_short","form":""},"5":{"name":"product_customization","form":""},"6":{"name":"product_actions_form","form":""},"7":{"name":"hook_display_reassurance","form":""}}},"2":{"form":{"md":12,"lg":12,"xl":12,"sm":12,"xs":12,"sp":12},"element":"column","sub":{"0":{"name":"product_more_info_default","form":""},"1":{"name":"product_accessories","form":""},"2":{"name":"hook_display_footer_product","form":""}}}}}},"class":"product-image-thumbs product-thumbs-right"}'; + break; + case 'product_image_no_thumbs': + $this->object->url_img_preview = 'https://i.pinimg.com/originals/60/ca/57/60ca570f6a8254c3741d8c9db78eb3d5.jpg'; + $this->object->params = '{"gridLeft":{"0":{"name":"functional_buttons","form":"","columns":{"0":{"form":{"md":6,"lg":6,"xl":6,"sm":12,"xs":12,"sp":12},"element":"column","sub":{"0":{"name":"product_image_with_thumb","form":{"templateview":"none","numberimage":"5","numberimage1200":"5","numberimage992":"4","numberimage768":"3","numberimage576":"3","numberimage480":"2","numberimage360":"2","templatemodal":"1","templatezoomtype":"in","zoomposition":"right","zoomwindowwidth":"400","zoomwindowheight":"400"}}}},"1":{"form":{"md":6,"lg":6,"xl":6,"sm":12,"xs":12,"sp":12},"element":"column","sub":{"0":{"name":"product_detail_name","form":""},"1":{"name":"hook_display_product_additional_info","form":""},"2":{"name":"hook_display_leo_product_review_extra","form":""},"3":{"name":"product_price","form":""},"4":{"name":"product_description_short","form":""},"5":{"name":"product_customization","form":""},"6":{"name":"product_actions_form","form":""},"7":{"name":"hook_display_reassurance","form":""}}},"2":{"form":{"md":12,"lg":12,"xl":12,"sm":12,"xs":12,"sp":12},"element":"column","sub":{"0":{"name":"product_more_info_tab","form":""},"1":{"name":"product_accessories","form":""},"2":{"name":"hook_display_footer_product","form":""}}}}}},"class":"product-image-thumbs no-thumbs"}'; + break; + case 'product_image_no_thumbs_fullwidth': + $this->object->url_img_preview = 'https://i.pinimg.com/originals/c5/d9/02/c5d9025b68250832a31eac3b6d344955.jpg'; + $this->object->params = '{"gridLeft":{"0":{"name":"functional_buttons","form":"","columns":{"0":{"form":{"class":"","xl":"12","lg":"12","md":"12","sm":"12","xs":"12","sp":"12"},"element":"column","sub":{"0":{"name":"product_image_with_thumb","form":{"templateview":"none","numberimage":"5","numberimage1200":"5","numberimage992":"4","numberimage768":"3","numberimage576":"3","numberimage480":"2","numberimage360":"2","templatemodal":"1","templatezoomtype":"in","zoomposition":"right","zoomwindowwidth":"400","zoomwindowheight":"400"}}}},"1":{"form":{"class":"offset-lg-2 offset-xl-2","xl":"8","lg":"8","md":"12","sm":"12","xs":"12","sp":"12"},"element":"column","sub":{"0":{"name":"product_detail_name","form":""},"1":{"name":"hook_display_product_additional_info","form":""},"2":{"name":"hook_display_leo_product_review_extra","form":""},"3":{"name":"product_price","form":""},"4":{"name":"product_description_short","form":""},"5":{"name":"product_customization","form":""},"6":{"name":"product_actions_form","form":""},"7":{"name":"hook_display_reassurance","form":""},"8":{"name":"product_more_info_tab","form":""}}},"2":{"form":{"class":"","xl":"12","lg":"12","md":"12","sm":"12","xs":"12","sp":"12"},"element":"column","sub":{"0":{"name":"product_accessories","form":""},"1":{"name":"hook_display_footer_product","form":""}}}}}},"class":"product-image-thumbs no-thumbs"}'; + break; + case 'product_image_gallery': + $this->object->url_img_preview = 'https://i.pinimg.com/originals/b1/a8/b9/b1a8b9381d8d3e3c4d13dfe24231581f.jpg'; + $this->object->params = '{"gridLeft":{"0":{"name":"functional_buttons","form":"","columns":{"0":{"form":{"md":6,"lg":6,"xl":6,"sm":12,"xs":12,"sp":12},"element":"column","sub":{"0":{"name":"product_image_show_all","form":{"templatezoomtype":"in","zoomposition":"right","zoomwindowwidth":"400","zoomwindowheight":"400"}}}},"1":{"form":{"md":6,"lg":6,"xl":6,"sm":12,"xs":12,"sp":12},"element":"column","sub":{"0":{"name":"product_detail_name","form":""},"1":{"name":"hook_display_product_additional_info","form":""},"2":{"name":"hook_display_leo_product_review_extra","form":""},"3":{"name":"product_price","form":""},"4":{"name":"product_description_short","form":""},"5":{"name":"product_customization","form":""},"6":{"name":"product_actions_form","form":""},"7":{"name":"hook_display_reassurance","form":""}}},"2":{"form":{"md":12,"lg":12,"xl":12,"sm":12,"xs":12,"sp":12},"element":"column","sub":{"0":{"name":"product_more_info_tab","form":""},"1":{"name":"product_accessories","form":""},"2":{"name":"hook_display_footer_product","form":""}}}}}},"class":"product-image-gallery"}'; + break; + case 'product_image_no_thumbs_center': + $this->object->url_img_preview = 'https://i.pinimg.com/originals/38/99/1a/38991a8c1582669d29abe889bc0d5f52.jpg'; + $this->object->params = '{"gridLeft":{"0":{"name":"functional_buttons","form":"","columns":{"0":{"form":{"class":"","xl":"4","lg":"4","md":"12","sm":"12","xs":"12","sp":"12"},"element":"column","sub":{"0":{"name":"product_detail_name","form":""},"1":{"name":"hook_display_product_additional_info","form":""},"2":{"name":"hook_display_leo_product_review_extra","form":""},"3":{"name":"product_price","form":""},"4":{"name":"product_description_short","form":""},"5":{"name":"hook_display_reassurance","form":""}}},"1":{"form":{"class":"","xl":"5","lg":"5","md":"12","sm":"12","xs":"12","sp":"12"},"element":"column","sub":{"0":{"name":"product_image_with_thumb","form":{"templateview":"none","numberimage":"5","numberimage1200":"5","numberimage992":"4","numberimage768":"3","numberimage576":"3","numberimage480":"2","numberimage360":"2","templatemodal":"1","templatezoomtype":"in","zoomposition":"right","zoomwindowwidth":"400","zoomwindowheight":"400"}}}},"2":{"form":{"class":"","xl":"3","lg":"3","md":"12","sm":"12","xs":"12","sp":"12"},"element":"column","sub":{"0":{"name":"product_customization","form":""},"1":{"name":"product_actions_form","form":""}}},"3":{"form":{"md":12,"lg":12,"xl":12,"sm":12,"xs":12,"sp":12},"element":"column","sub":{"0":{"name":"product_more_info_tab","form":""},"1":{"name":"product_accessories","form":""},"2":{"name":"hook_display_footer_product","form":""}}}}}},"class":"product-image-thumbs no-thumbs"}'; + break; + default: + break; + } + } + + $params = Tools::jsonDecode($this->object->params, true); + if ($params['gridLeft']) { + foreach ($params['gridLeft'] as $key => $value) { + $params['gridLeft'][$key]['dataForm'] = (!isset($value['form']))?'':Tools::jsonEncode($value['form']); + + if (isset($element_by_name[$value['name']])) { + $params['gridLeft'][$key]['config'] = $element_by_name[$value['name']]; + } + if ($value['name'] == "functional_buttons") { + foreach ($value['columns'] as $k => $v) { + $params['gridLeft'][$key]['columns'][$k]['dataForm'] = (!isset($v['form']))?'':Tools::jsonEncode($v['form']); + foreach ($v['sub'] as $ke => $ve) { + $params['gridLeft'][$key]['columns'][$k]['sub'][$ke]['dataForm'] = (!isset($ve['form']))?'':Tools::jsonEncode($ve['form']); + if (isset($element_by_name[$ve['name']])) { + $params['gridLeft'][$key]['columns'][$k]['sub'][$ke]['config'] = $element_by_name[$ve['name']]; + } + } + } + } + } + } + } + // echo '
    ';print_r($params);die;
    +        
    +        $block_list = array(
    +            'gridLeft' => array('title' => 'Product-Layout', 'class' => 'left-block'),
    +        );
    +        
    +        $this->fields_form = array(
    +            'legend' => array(
    +                'title' => $this->l('Ap Profile Manage'),
    +                'icon' => 'icon-folder-close'
    +            ),
    +            'input' => array(
    +                array(
    +                    'type' => 'text',
    +                    'label' => $this->l('Name'),
    +                    'name' => 'name',
    +                    'required' => true,
    +                    'hint' => $this->l('Invalid characters:').' <>;=#{}'
    +                ),
    +                array(
    +                    'type' => 'text',
    +                    'label' => $this->l('Product List Key'),
    +                    'name' => 'plist_key',
    +                    'readonly' => 'readonly',
    +                    'desc' => $this->l('Tpl File name'),
    +                ),
    +                array(
    +                    'label' => $this->l('Class'),
    +                    'type' => 'text',
    +                    'name' => 'class_detail',
    +                    'width' => 140
    +                ),
    +                array(
    +                    'label' => $this->l('Url Image Preview'),
    +                    'type' => 'text',
    +                    'name' => 'url_img_preview',
    +                    'desc' => $this->l('Only for developers'),
    +                    'width' => 140
    +                ),
    +                array(
    +                    'type' => 'ap_proGrid',
    +                    'name' => 'ap_proGrid',
    +                    'params' => $params,
    +                    'blockList' => $block_list,
    +                    'elements' => $config_file,
    +                    'demodetaillink' => 'index.php?controller=AdminApPageBuilderDetails'.'&token='.Tools::getAdminTokenLite('AdminApPageBuilderDetails').'&addappagebuilder_details',
    +                    'element_by_name' => $element_by_name,
    +                    'widthList' => ApPageSetting::returnWidthList(),
    +                    'columnGrids' => ApPageSetting::getColumnGrid(),
    +                ),
    +                array(
    +                    'type' => 'hidden',
    +                    'name' => 'params'
    +                ),
    +                array(
    +                    'type' => 'hidden',
    +                    'name' => 'submitAddappagebuilder_detailsAndStay',
    +                )
    +            ),
    +            'buttons' => array(
    +                'save-and-stay' => array(
    +                    'title' => $this->l('Save and Stay'),
    +                    'id' => 'saveAndStay',
    +                    'type' => 'button',
    +                    'class' => 'btn btn-default pull-right ',
    +                    'icon' => 'process-icon-save')
    +            )
    +        );
    +        return parent::renderForm();
    +    }
    +
    +    public function replaceSpecialStringToHtml($arr)
    +    {
    +        foreach ($arr as &$v) {
    +            if ($v['name'] == 'code') {
    +                // validate module
    +                $v['code'] = str_replace($this->str_search, $this->str_relace, $v['code']);
    +            } else {
    +                if ($v['name'] == 'functional_buttons') {
    +                    foreach ($v as &$f) {
    +                        if ($f['name'] == 'code') {
    +                            // validate module
    +                            $f['code'] = str_replace($this->str_search, $this->str_relace, $f['code']);
    +                        }
    +                    }
    +                }
    +            }
    +        }
    +        return $arr;
    +    }
    +
    +    public function getFieldsValue($obj)
    +    {
    +        $file_value = parent::getFieldsValue($obj);
    +        if (!$obj->id) {
    +            $num = ApPageSetting::getRandomNumber();
    +            $file_value['plist_key'] = 'detail'.$num;
    +            $file_value['name'] = $file_value['plist_key'];
    +            $file_value['class_detail'] = 'detail-'.$num;
    +        }
    +        return $file_value;
    +    }
    +
    +    public function processAdd()
    +    {
    +        if ($obj = parent::processAdd()) {
    +            $this->saveTplFile($obj->plist_key, $obj->params);
    +        }
    +    }
    +
    +    public function processUpdate()
    +    {
    +        if ($obj = parent::processUpdate()) {
    +            $this->saveTplFile($obj->plist_key, $obj->params);
    +        }
    +    }
    +
    +    //save file
    +    public function saveTplFile($plist_key, $params)
    +    {
    +        // validate module
    +        unset($params);
    +        //if (Tools::get)
    +        $data_form = str_replace($this->str_search, $this->str_relace, Tools::getValue('params', ''));
    +        $data_form = Tools::jsonDecode($data_form, true);
    +
    +        $grid_left = $data_form['gridLeft'];
    +        //get header
    +        
    +        $tpl_grid = $this->returnFileContent('header_product');
    +        //change class
    +        // echo '
    ';print_r($grid_left);die;
    +        $tpl_grid = str_replace('class="product-detail', 'class="product-detail '.Tools::getValue('class_detail', '').' '.Tools::getValue('main_class', ''), $tpl_grid);
    +       //die($tpl_grid);
    +        $tpl_grid .= $this->convertObjectToTpl($grid_left);
    +        $tpl_grid .= $this->returnFileContent('footer_product');
    +        
    +        $tpl_grid = preg_replace('/\{\*[\s\S]*?\*\}/', '', $tpl_grid);
    +
    +        $folder = apPageHelper::getConfigDir('theme_details');
    +        if (!is_dir($folder)) {
    +            mkdir($folder, 0755, true);
    +        }
    +        $file = $plist_key.'.tpl';
    +        //$tpl_grid = preg_replace('/\{\*[\s\S]*?\*\}/', '', $tpl_grid);
    +        //$tpl_grid = str_replace(" mod='appagebuilder'", '', $tpl_grid);
    +
    +        //die($tpl_grid."--");
    +        ApPageSetting::writeFile($folder, $file, $tpl_grid);
    +    }
    +
    +    public function processStatus()
    +    {
    +        if (Validate::isLoadedObject($object = $this->loadObject())) {
    +            if ($object->toggleStatus()) {
    +                $matches = array();
    +                if (preg_match('/[\?|&]controller=([^&]*)/', (string)$_SERVER['HTTP_REFERER'], $matches) !== false && Tools::strtolower($matches[1]) != Tools::strtolower(preg_replace('/controller/i', '', get_class($this)))) {
    +                    $this->redirect_after = preg_replace('/[\?|&]conf=([^&]*)/i', '', (string)$_SERVER['HTTP_REFERER']);
    +                } else {
    +                    $this->redirect_after = self::$currentIndex.'&token='.$this->token;
    +                }
    +            }
    +        } else {
    +            $this->errors[] = Tools::displayError('An error occurred while updating the status for an object.')
    +                    .''.$this->table.' '.Tools::displayError('(cannot load object)');
    +        }
    +        return $object;
    +    }
    +    
    +    public function displayDuplicateLink($token = null, $id = null, $name = null)
    +    {
    +        $controller = 'AdminApPageBuilderDetails';
    +        $token = Tools::getAdminTokenLite($controller);
    +        $html = '
    +             Duplicate
    +        ';
    +        
    +        // validate module
    +        unset($name);
    +        
    +        return $html;
    +    }
    +    
    +    /**
    +     * PERMISSION ACCOUNT demo@demo.com
    +     * OVERRIDE CORE
    +     */
    +    public function access($action, $disable = false)
    +    {
    +        if (Tools::getIsset('update'.$this->table) && Tools::getIsset($this->identifier)) {
    +            // Allow person see "EDIT" form
    +            $action = 'view';
    +        }
    +        return parent::access($action, $disable);
    +    }
    +    
    +    /**
    +     * PERMISSION ACCOUNT demo@demo.com
    +     * OVERRIDE CORE
    +     */
    +    public function initProcess()
    +    {
    +        parent::initProcess();
    +        if (count($this->errors) <= 0) {
    +            if( Tools::isSubmit('duplicate'.$this->table) ) {
    +                if ($this->id_object) {
    +                    if (!$this->access('add'))
    +                    {
    +                        $this->errors[] = $this->trans('You do not have permission to duplicate this.', array(), 'Admin.Notifications.Error');
    +                    }
    +                }
    +            }elseif(Tools::getIsset('saveELement') && Tools::getValue('saveELement')){
    +                if (!$this->access('edit'))
    +                {
    +                    $this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
    +                }
    +            }
    +        }
    +    }
    +}
    diff --git a/modules/appagebuilder/controllers/admin/AdminApPageBuilderHome.php b/modules/appagebuilder/controllers/admin/AdminApPageBuilderHome.php
    new file mode 100644
    index 00000000..5b53086c
    --- /dev/null
    +++ b/modules/appagebuilder/controllers/admin/AdminApPageBuilderHome.php
    @@ -0,0 +1,1223 @@
    +
    + *  @copyright 2007-2015 Apollotheme
    + *  @license   http://apollotheme.com - prestashop template provider
    + */
    +
    +if (!defined('_PS_VERSION_')) {
    +    # module validation
    +    exit;
    +}
    +
    +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageSetting.php');
    +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageBuilderModel.php');
    +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageBuilderProfilesModel.php');
    +require_once(_PS_MODULE_DIR_.'appagebuilder/controllers/admin/AdminApPageBuilderPositions.php');
    +
    +class AdminApPageBuilderHomeController extends ModuleAdminControllerCore
    +{
    +    public static $shortcode_lang;
    +    public static $lang_id;
    +    public static $language;
    +    public $error_text = '';
    +    public $module_name;
    +    public $module_path;
    +//    public $module_path_resource;
    +    public $tpl_path;
    +    public $theme_dir;
    +    public $file_content = '';
    +
    +    public function __construct()
    +    {
    +        $this->bootstrap = true;
    +        $this->show_toolbar = true;
    +        $this->table = 'appagebuilder';
    +        $this->className = 'ApPageBuilderHome';
    +        $this->context = Context::getContext();
    +        $this->module_name = 'appagebuilder';
    +        $this->module_path = __PS_BASE_URI__.'modules/'.$this->module_name.'/';
    +//        $this->module_path_resource = $this->module_path.'views/';
    +        $this->tpl_path = _PS_ROOT_DIR_.'/modules/'.$this->module_name.'/views/templates/admin';
    +        parent::__construct();
    +        $this->multishop_context = false;
    +        $this->theme_dir = _PS_THEME_DIR_;
    +        apPageHelper::loadShortCode(_PS_THEME_DIR_);
    +    }
    +
    +    public function initPageHeaderToolbar()
    +    {
    +        $this->page_header_toolbar_btn['save'] = array(
    +            //'short' => $this->l('Save', null, null, false),
    +            'short' => 'SaveAndStay',
    +            'href' => 'javascript:;',
    +            //'desc' => $this->l('Save', null, null, false),
    +            'desc' => $this->l('Save and stay'),
    +            'confirm' => 1,
    +            'js' => 'submitform()'
    +        );
    +        $current_id = Tools::getValue('id_appagebuilder_profiles');
    +        if (!$current_id) {
    +            $profile = ApPageBuilderProfilesModel::getActiveProfile('index');
    +            $current_id = $profile['id_appagebuilder_profiles'];
    +        }
    +        $lang = '';
    +        if (Configuration::get('PS_REWRITING_SETTINGS') && count(Language::getLanguages(true)) > 1) {
    +            $lang = Language::getIsoById($this->context->employee->id_lang).'/';
    +        }
    +        $url_preview = $this->context->shop->getBaseUrl().(Configuration::get('PS_REWRITING_SETTINGS') ? '' : 'index.php')
    +                .$lang.'?id_appagebuilder_profiles='.$current_id;
    +        $this->page_header_toolbar_btn['preview'] = array(
    +            //'short' => $this->l('Save', null, null, false),
    +            'short' => 'Preview',
    +            'href' => $url_preview,
    +            'target' => '_blank',
    +            //'desc' => $this->l('Save', null, null, false),
    +            'desc' => $this->l('Preview'),
    +            'confirm' => 0
    +        );
    +        parent::initPageHeaderToolbar();
    +    }
    +
    +    public function postProcess()
    +    {
    +        if (count($this->errors) > 0) {
    +            if ($this->ajax) {
    +                $array = array('hasError' => true, 'errors' => $this->errors[0]);
    +                die(Tools::jsonEncode($array));
    +            }
    +            return;
    +        }
    +        
    +        $action = Tools::getValue('action');
    +//        $type = Tools::getValue('type');
    +        
    +        if ($action == 'processPosition') {
    +            $this->processPosition();
    +        }
    +        
    +        if ($action == 'selectPosition') {
    +            $this->selectPosition();
    +        }
    +        
    +        if (Tools::isSubmit('submitImportData')) {
    +            $this->importData(Language::getLanguages(false), (int)$this->context->language->id);
    +        }
    +        
    +        if ($action == 'export') {
    +            $this->exportData();
    +        }
    +        
    +        //DONGND:: submit save
    +        if (Tools::isSubmit('submitSaveAndStay')) {
    +            if (Tools::getValue('data_profile') && Tools::getValue('data_profile') != '') {
    +                $data_form = Tools::jsonDecode(Tools::getValue('data_profile'), 1);
    +                $id_profile = Tools::getValue('data_id_profile');
    +                self::$language = Language::getLanguages(false);
    +//                $data = array();
    +                $arr_id = array('header' => 0, 'content' => 0, 'footer' => 0, 'product' => 0);
    +                foreach ($data_form as $hook) {
    +                    $position_id = (int)isset($hook['position_id']) ? $hook['position_id'] : '0';
    +                    $hook['position'] = (isset($hook['position']) && $hook['position']) ? $hook['position'] : '';
    +                    $hook['name'] = (isset($hook['name']) && $hook['name']) ? $hook['name'] : 0;
    +                    $position = Tools::strtolower($hook['position']);
    +                    $arr_id[$position] = (isset($arr_id[$position]) && $arr_id[$position]) ? $arr_id[$position] : '';
    +                    // Create new position with name is auto random, and save id of new for other positions reuse
    +                    // position for other hook in this position to variable $header, $content...
    +                    if ($position_id == 0 && $arr_id[$position] == 0) {
    +                        $key = ApPageSetting::getRandomNumber();
    +                        $position_controller = new AdminApPageBuilderPositionsController();
    +                        $position_data = array('name' => $position.$key,
    +                            'position' => $position,
    +                            'position_key' => 'position'.$key);
    +                        $position_id = $position_controller->autoCreatePosition($position_data);
    +                        $arr_id[$position] = $position_id;
    +                    } else if ($position_id != 0 && $arr_id[$position] == 0) {
    +                        $arr_id[$position] = $position_id;
    +                    }
    +
    +                    $obj_model = new ApPageBuilderModel();
    +                    $obj_model->id = $obj_model->getIdbyHookName($hook['name'], $arr_id[$position]);
    +                    $obj_model->hook_name = $hook['name'];
    +                    $obj_model->page = 'index';
    +                    $obj_model->id_appagebuilder_positions = $arr_id[$position];
    +                    if (isset($hook['groups'])) {
    +                        foreach (self::$language as $lang) {
    +                            $params = '';
    +                            if (self::$shortcode_lang) {
    +                                foreach (self::$shortcode_lang as &$s_type) {
    +                                    foreach ($s_type as $key => $value) {
    +                                        $s_type[$key] = $key.'_'.$lang['id_lang'];
    +                                        // validate module
    +                                        unset($value);
    +                                    }
    +                                }
    +                            }
    +                            $obj_model->params[$lang['id_lang']] = '';
    +                            ApShortCodesBuilder::$lang_id = $lang['id_lang'];
    +                            foreach ($hook['groups'] as $groups) {
    +                                $params = $this->getParamByHook($groups, $params, $hook['name']);
    +                            }
    +
    +                            $obj_model->params[$lang['id_lang']] = $params;
    +                        }
    +                    }
    +
    +                    if ($obj_model->id) {
    +                        $this->clearModuleCache();
    +                        $obj_model->save();
    +                    } else {
    +                        $this->clearModuleCache();
    +                        $obj_model->add();
    +                    }
    +                    $path = _PS_ROOT_DIR_.'/cache/smarty/cache/'.$this->module_name;
    +                    
    +                    $this->deleteDirectory($path);
    +                };
    +
    +                $profile = new ApPageBuilderProfilesModel($id_profile);
    +
    +                # Fix : must keep other data in param. ( exception + other data )
    +
    +                $params = Tools::jsonDecode($profile->params);
    +
    +                isset($params->fullwidth_index_hook) ? $this->config_module['fullwidth_index_hook'] = $params->fullwidth_index_hook : false;
    +                isset($params->fullwidth_other_hook) ? $this->config_module['fullwidth_other_hook'] = $params->fullwidth_other_hook : false;
    +                isset($params->disable_cache_hook) ? $this->config_module['disable_cache_hook'] = $params->disable_cache_hook : false;
    +
    +                $profile->params = Tools::jsonEncode($this->config_module);
    +                $profile->header = $arr_id['header'];
    +                $profile->content = $arr_id['content'];
    +                $profile->footer = $arr_id['footer'];
    +                $profile->product = $arr_id['product'];
    +                $profile->save();
    +                $this->confirmations[] = $this->trans('Save successful', array(), 'Admin.Notifications.Success');
    +            }
    +            $this->error[] = $this->trans('Not exist data_profile', array(), 'Admin.Notifications.Success');
    +        }
    +        
    +        parent::postProcess();
    +    }
    +    
    +    public function ajaxProcessShowImportForm()
    +    {
    +        $id_profile = Tools::getValue('idProfile');
    +        $helper = new HelperForm();
    +        $helper->submit_action = 'submitImportData';
    +        $hook = array();
    +        $hook[] = array('id' => 'all', 'name' => $this->l('Profile'));
    +        $hook[] = array('id' => 'header', 'name' => $this->l('Position Header'));
    +        foreach (ApPageSetting::getHook('header') as $val) {
    +            $hook[] = array('id' => $val, 'name' => '----'.$val);
    +        }
    +        $hook[] = array('id' => 'content', 'name' => $this->l('Position Content'));
    +        foreach (ApPageSetting::getHook('content') as $val) {
    +            $hook[] = array('id' => $val, 'name' => '----'.$val);
    +        }
    +        $hook[] = array('id' => 'footer', 'name' => $this->l('Position Footer'));
    +        foreach (ApPageSetting::getHook('footer') as $val) {
    +            $hook[] = array('id' => $val, 'name' => '----'.$val);
    +        }
    +        $hook[] = array('id' => 'product', 'name' => $this->l('Position Product'));
    +        foreach (ApPageSetting::getHook('product') as $val) {
    +            $hook[] = array('id' => $val, 'name' => '----'.$val);
    +        }
    +        $inputs = array(
    +            array(
    +                'type' => 'file',
    +                'name' => 'importFile',
    +                'label' => $this->l('File'),
    +                'desc' => $this->l('Only accept xml file'),
    +            ),
    +            array(
    +                'type' => 'select',
    +                'label' => $this->l('Import For'),
    +                'name' => 'import_for',
    +                'options' => array(
    +                    'query' => $hook,
    +                    'id' => 'id',
    +                    'name' => 'name'
    +                ),
    +                'desc' => $this->l('Select hook you want to import. Override all is only avail for import appagebuilderhome.xml file'),
    +            ),
    +            array(
    +                'type' => 'switch',
    +                'label' => $this->l('Override'),
    +                'name' => 'override',
    +                'is_bool' => true,
    +                'desc' => $this->l('Override current data or not.'),
    +                'values' => ApPageSetting::returnYesNo()
    +            ),
    +            array(
    +                'type' => 'html',
    +                'name' => 'default_html',
    +                'html_content' => ''
    +            )
    +        );
    +        $fields_form = array(
    +            'form' => array(
    +                'action' => Context::getContext()->link->getAdminLink('AdminApPageBuilderHome'),
    +                'input' => $inputs,
    +//                'name' => 'importData',
    +                //'buttons' => array(array('title' => $this->l('Save'), 'class' => 'button btn')),
    +                'submit' => array('title' => $this->l('Save'), 'class' => 'button btn btn-success'),
    +                'tinymce' => false,
    +            ),
    +        );
    +        $helper->fields_value = isset($this->fields_value) ? $this->fields_value : array();
    +        $array = array('hasError' => false, 'result' => $helper->generateForm(array($fields_form)));
    +        die(Tools::jsonEncode($array));
    +    }
    +    
    +    /**
    +     * Show panel : widgets and modules
    +     * .group-add
    +     * .btn-new-widget
    +     */
    +    public function ajaxProcessRenderList()
    +    {
    +        $tpl = $this->createTemplate('shortcodelist.tpl');
    +        // get list module installed by hook position
    +        $list_modules = array();
    +
    +
    +        if (Tools::getValue('reloadModule')) {
    +            # ReLoad : write to config
    +            $list_modules = apPageHelper::getModules();
    +
    +            $ap_cache_module = apPageHelper::correctEnCodeData(Tools::jsonEncode($list_modules));
    +            Configuration::updateValue('AP_CACHE_MODULE', $ap_cache_module);
    +        } else {
    +            $ap_cache_module = Configuration::get('AP_CACHE_MODULE');
    +            if ($ap_cache_module === false) {
    +                # First Time : write to config
    +                $list_modules = apPageHelper::getModules();
    +
    +                $ap_cache_module = apPageHelper::correctEnCodeData(Tools::jsonEncode($list_modules));
    +                Configuration::updateValue('AP_CACHE_MODULE', $ap_cache_module);
    +            } else {
    +                # Second Time : read from config
    +                $list_modules = Tools::jsonDecode(apPageHelper::correctDeCodeData($ap_cache_module), true);
    +            }
    +        }
    +
    +        // Get list author
    +        $author = array();
    +        foreach ($list_modules as $mi) {
    +            $str = Tools::ucwords(Tools::strtolower($mi['author'] ? $mi['author'] : ' '));
    +            if (!in_array($str, $author)) {
    +                array_push($author, $str);
    +            }
    +        }
    +        //Get list of image or shortcodeFile
    +        $tpl->assign(array(
    +            'author' => $author,
    +            'listModule' => $list_modules,
    +            'shortCodeList' => ApShortCodeBase::getShortCodeInfos()
    +        ));
    +        $array = array('hasError' => false, 'result' => $tpl->fetch());
    +        die(Tools::jsonEncode($array));
    +    }
    +    
    +    public function ajaxProcessSaveData()
    +    {
    +        $type = Tools::getValue('type');
    +        $this->saveData('save', $type);
    +    }
    +    
    +    public function saveData($action, $type)
    +    {
    +        $data_form = Tools::getValue('dataForm');
    +        $data_form = Tools::jsonDecode($data_form, 1);
    +        self::$language = Language::getLanguages(false);
    +        $data = array();
    +        $arr_id = array('header' => 0, 'content' => 0, 'footer' => 0, 'product' => 0);
    +        foreach ($data_form as $hook) {
    +            $position_id = (int)isset($hook['position_id']) ? $hook['position_id'] : '0';
    +            $hook['position'] = (isset($hook['position']) && $hook['position']) ? $hook['position'] : '';
    +            $hook['name'] = (isset($hook['name']) && $hook['name']) ? $hook['name'] : 0;
    +            $position = Tools::strtolower($hook['position']);
    +            $arr_id[$position] = (isset($arr_id[$position]) && $arr_id[$position]) ? $arr_id[$position] : '';
    +            // Create new position with name is auto random, and save id of new for other positions reuse
    +            // position for other hook in this position to variable $header, $content...
    +            if ($position_id == 0 && $arr_id[$position] == 0) {
    +                //DONGND: enable save multithreading
    +                if (Configuration::get('APPAGEBUILDER_SAVE_MULTITHREARING')) {
    +                    if ((Configuration::get('APPAGEBUILDER_GLOBAL_HEADER_ID') == 0 && $position == 'header')
    +                        || (Configuration::get('APPAGEBUILDER_GLOBAL_CONTENT_ID') == 0 && $position == 'content')
    +                        || (Configuration::get('APPAGEBUILDER_GLOBAL_FOOTER_ID') == 0 && $position == 'footer')
    +                        || (Configuration::get('APPAGEBUILDER_GLOBAL_PRODUCT_ID') == 0 && $position == 'product')) {
    +                        $key = ApPageSetting::getRandomNumber();
    +                        $position_controller = new AdminApPageBuilderPositionsController();
    +                        $position_data = array('name' => $position.$key,
    +                            'position' => $position,
    +                            'position_key' => 'position'.$key);
    +                        $position_id = $position_controller->autoCreatePosition($position_data);
    +                        $arr_id[$position] = $position_id;
    +                        switch ($position) {
    +                            case 'header':
    +                                Configuration::updateValue('APPAGEBUILDER_GLOBAL_HEADER_ID', $position_id);
    +                                break;
    +                            case 'content':
    +                                Configuration::updateValue('APPAGEBUILDER_GLOBAL_CONTENT_ID', $position_id);
    +                                break;
    +                            case 'footer':
    +                                Configuration::updateValue('APPAGEBUILDER_GLOBAL_FOOTER_ID', $position_id);
    +                                break;
    +                            case 'product':
    +                                Configuration::updateValue('APPAGEBUILDER_GLOBAL_PRODUCT_ID', $position_id);
    +                                break;
    +                        }
    +                    } else {
    +                        switch ($position) {
    +                            case 'header':
    +                                $arr_id[$position] = Configuration::get('APPAGEBUILDER_GLOBAL_HEADER_ID');
    +                                break;
    +                            case 'content':
    +                                $arr_id[$position] = Configuration::get('APPAGEBUILDER_GLOBAL_CONTENT_ID');
    +                                break;
    +                            case 'footer':
    +                                $arr_id[$position] = Configuration::get('APPAGEBUILDER_GLOBAL_FOOTER_ID');
    +                                break;
    +                            case 'product':
    +                                $arr_id[$position] = Configuration::get('APPAGEBUILDER_GLOBAL_PRODUCT_ID');
    +                                break;
    +                        }
    +                    }
    +                } else {
    +                    $key = ApPageSetting::getRandomNumber();
    +                    $position_controller = new AdminApPageBuilderPositionsController();
    +                    $position_data = array('name' => $position.$key,
    +                            'position' => $position,
    +                            'position_key' => 'position'.$key);
    +                    $position_id = $position_controller->autoCreatePosition($position_data);
    +                    $arr_id[$position] = $position_id;
    +                }
    +            } else if ($position_id != 0 && $arr_id[$position] == 0) {
    +                //DONGND: enable save multithreading
    +                if (Configuration::get('APPAGEBUILDER_SAVE_MULTITHREARING')) {
    +                    switch ($position) {
    +                        case 'header':
    +                            Configuration::updateValue('APPAGEBUILDER_GLOBAL_HEADER_ID', $position_id);
    +                            break;
    +                        case 'content':
    +                            Configuration::updateValue('APPAGEBUILDER_GLOBAL_CONTENT_ID', $position_id);
    +                            break;
    +                        case 'footer':
    +                            Configuration::updateValue('APPAGEBUILDER_GLOBAL_FOOTER_ID', $position_id);
    +                            break;
    +                        case 'product':
    +                            Configuration::updateValue('APPAGEBUILDER_GLOBAL_PRODUCT_ID', $position_id);
    +                            break;
    +                    }
    +                };
    +                $arr_id[$position] = $position_id;
    +            }
    +
    +            $obj_model = new ApPageBuilderModel();
    +            $obj_model->id = $obj_model->getIdbyHookName($hook['name'], $arr_id[$position]);
    +            $obj_model->hook_name = $hook['name'];
    +            $obj_model->page = 'index';
    +            $obj_model->id_appagebuilder_positions = $arr_id[$position];
    +            if (isset($hook['groups'])) {
    +                foreach (self::$language as $lang) {
    +                    $params = '';
    +                    if (self::$shortcode_lang) {
    +                        foreach (self::$shortcode_lang as &$s_type) {
    +                            foreach ($s_type as $key => $value) {
    +                                $s_type[$key] = $key.'_'.$lang['id_lang'];
    +                                // validate module
    +                                unset($value);
    +                            }
    +                        }
    +                    }
    +                    $obj_model->params[$lang['id_lang']] = '';
    +                    ApShortCodesBuilder::$lang_id = $lang['id_lang'];
    +                    foreach ($hook['groups'] as $groups) {
    +                        $params = $this->getParamByHook($groups, $params, $hook['name'], $action);
    +                    }
    +                    $obj_model->params[$lang['id_lang']] = $params;
    +                    if ($action == 'export') {
    +                        $data[$lang['iso_code']] = (isset($data[$lang['iso_code']]) && $data[$lang['iso_code']]) ? $data[$lang['iso_code']] : '';
    +                        $data[$hook['name']][$lang['iso_code']] = (isset($data[$hook['name']][$lang['iso_code']]) && $data[$hook['name']][$lang['iso_code']]) ? $data[$hook['name']][$lang['iso_code']] : '';
    +
    +                        if ($type == 'all' || (strpos($type, 'position') !== false)) {
    +                            $data[$hook['name']][$lang['iso_code']] .= $params;
    +                        } else {
    +                            $data[$lang['iso_code']] .= $params;
    +                        }
    +                    }
    +                }
    +            }
    +            if ($action == 'save') {
    +                if ($obj_model->id) {
    +                    $this->clearModuleCache();
    +                    $obj_model->save();
    +                } else {
    +                    $this->clearModuleCache();
    +                    $obj_model->add();
    +                }
    +                $path = _PS_ROOT_DIR_.'/cache/smarty/cache/'.$this->module_name;
    +                $this->deleteDirectory($path);
    +            }
    +        };
    +
    +        if ($action == 'save') {
    +            if (Configuration::get('APPAGEBUILDER_SAVE_MULTITHREARING')) {
    +                if (Tools::getValue('dataFirst')) {
    +                    $profile = new ApPageBuilderProfilesModel(Tools::getValue('id_profile'));
    +
    +                    # Fix : must keep other data in param. ( exception + other data )
    +                    //print_r($this->config_module);
    +                    $params = Tools::jsonDecode($profile->params, true);
    +                    isset($params['fullwidth_index_hook']) ? $this->config_module['fullwidth_index_hook'] = $params['fullwidth_index_hook'] : false;
    +                    isset($params['fullwidth_other_hook']) ? $this->config_module['fullwidth_other_hook'] = $params['fullwidth_other_hook'] : false;
    +                    isset($params['disable_cache_hook']) ? $this->config_module['disable_cache_hook'] = $params['disable_cache_hook'] : false;
    +                    Configuration::updateValue('APPAGEBUILDER_GLOBAL_PROFILE_PARAM', Tools::jsonEncode($this->config_module));
    +                } else {
    +                    if (count($this->config_module) > 0) {
    +                        $array_global_profile_param = Tools::jsonDecode(Configuration::get('APPAGEBUILDER_GLOBAL_PROFILE_PARAM'), true);
    +                        $array_global_profile_param = array_merge($this->config_module, $array_global_profile_param);
    +                        Configuration::updateValue('APPAGEBUILDER_GLOBAL_PROFILE_PARAM', Tools::jsonEncode($array_global_profile_param));
    +                    }
    +                };
    +                if (Tools::getValue('dataLast')) {
    +                    $profile = new ApPageBuilderProfilesModel(Tools::getValue('id_profile'));
    +                    $params = Tools::jsonDecode($profile->params, true);
    +                    $profile->params = Configuration::get('APPAGEBUILDER_GLOBAL_PROFILE_PARAM');
    +                    $profile->header = Configuration::get('APPAGEBUILDER_GLOBAL_HEADER_ID');
    +                    $profile->content = Configuration::get('APPAGEBUILDER_GLOBAL_CONTENT_ID');
    +                    $profile->footer = Configuration::get('APPAGEBUILDER_GLOBAL_FOOTER_ID');
    +                    $profile->product = Configuration::get('APPAGEBUILDER_GLOBAL_PRODUCT_ID');
    +                    $profile->save();
    +
    +                    Configuration::updateValue('APPAGEBUILDER_GLOBAL_HEADER_ID', 0);
    +                    Configuration::updateValue('APPAGEBUILDER_GLOBAL_CONTENT_ID', 0);
    +                    Configuration::updateValue('APPAGEBUILDER_GLOBAL_FOOTER_ID', 0);
    +                    Configuration::updateValue('APPAGEBUILDER_GLOBAL_PRODUCT_ID', 0);
    +                    Configuration::updateValue('APPAGEBUILDER_GLOBAL_PROFILE_PARAM', '');
    +                }
    +            } else {
    +                $profile = new ApPageBuilderProfilesModel(Tools::getValue('id_profile'));
    +
    +                # Fix : must keep other data in param. ( exception + other data )
    +                //print_r($this->config_module);
    +                $params = Tools::jsonDecode($profile->params);
    +                isset($params->fullwidth_index_hook) ? $this->config_module['fullwidth_index_hook'] = $params->fullwidth_index_hook : false;
    +                isset($params->fullwidth_other_hook) ? $this->config_module['fullwidth_other_hook'] = $params->fullwidth_other_hook : false;
    +                isset($params->disable_cache_hook) ? $this->config_module['disable_cache_hook'] = $params->disable_cache_hook : false;
    +
    +                $profile->params = Tools::jsonEncode($this->config_module);
    +                $profile->header = $arr_id['header'];
    +                $profile->content = $arr_id['content'];
    +                $profile->footer = $arr_id['footer'];
    +                $profile->product = $arr_id['product'];
    +                $profile->save();
    +            };
    +        };
    +        return $data;
    +    }
    +
    +    public function renderList()
    +    {
    +        $this->context->controller->addJqueryUI('ui.sortable');
    +        $this->context->controller->addJqueryUI('ui.draggable');
    +        $this->context->controller->addCss(apPageHelper::getCssAdminDir().'admin/form.css');
    +        $this->context->controller->addCss(apPageHelper::getCssAdminDir().'animate.css');
    +        $this->context->controller->addJs(apPageHelper::getJsAdminDir().'admin/form.js');
    +        $this->context->controller->addJs(apPageHelper::getJsAdminDir().'admin/home.js');
    +        $this->context->controller->addJs(apPageHelper::getJsAdminDir().'admin/isotope.pkgd.min.js');
    +        $this->context->controller->addJS(_PS_JS_DIR_.'tiny_mce/tiny_mce.js');
    +
    +        $this->context->controller->addJs(apPageHelper::getJsAdminDir().'admin/jquery-validation-1.9.0/jquery.validate.js');
    +        $this->context->controller->addCss(apPageHelper::getJsAdminDir().'admin/jquery-validation-1.9.0/screen.css');
    +
    +//        $version = Configuration::get('PS_INSTALL_VERSION');
    +//        $tiny_path = ($version >= '1.6.0.13') ? 'admin/' : '';
    +//        $tiny_path .= 'tinymce.inc.js';
    +
    +        // Pham_Khanh_Dong fix loading TINY_MCE library for all Prestashop_Versions
    +        $tiny_path = 'tinymce.inc.js';
    +        if (version_compare(_PS_VERSION_, '1.6.0.13', '>')) {
    +            $tiny_path = 'admin/tinymce.inc.js';
    +        }
    +
    +        $this->context->controller->addJS(_PS_JS_DIR_.$tiny_path);
    +        $bo_theme = ((Validate::isLoadedObject($this->context->employee) && $this->context->employee->bo_theme) ? $this->context->employee->bo_theme : 'default');
    +        if (!file_exists(_PS_BO_ALL_THEMES_DIR_.$bo_theme.DIRECTORY_SEPARATOR.'template')) {
    +            $bo_theme = 'default';
    +        }
    +        $this->addJs(__PS_BASE_URI__.$this->admin_webpath.'/themes/'.$bo_theme.'/js/jquery.fileupload.js');
    +        $this->addJs(__PS_BASE_URI__.$this->admin_webpath.'/themes/'.$bo_theme.'/js/jquery.fileupload-process.js');
    +        $this->addJs(__PS_BASE_URI__.$this->admin_webpath.'/themes/'.$bo_theme.'/js/jquery.fileupload-validate.js');
    +        $this->context->controller->addJs(__PS_BASE_URI__.'js/vendor/spin.js');
    +        $this->context->controller->addJs(__PS_BASE_URI__.'js/vendor/ladda.js');
    +        //load javascript for menu tree, Product Carousel widget
    +        $tree = new HelperTreeCategories('123', null);
    +        $tree->render();
    +        
    +        $model = new ApPageBuilderModel();
    +        $id_profile = Tools::getValue('id_appagebuilder_profiles');
    +        if (!$id_profile) {
    +            $result_profile = ApPageBuilderProfilesModel::getActiveProfile('index');
    +            //if empty default profile redirect to other
    +            if (!$result_profile) {
    +                $this->redirect_after = Context::getContext()->link->getAdminLink('AdminApPageBuilderProfiles');
    +                $this->redirect();
    +            }
    +            $id_profile = $result_profile['id_appagebuilder_profiles'];
    +        } else {
    +            $profile_obj = new ApPageBuilderProfilesModel($id_profile);
    +            if ($profile_obj->id) {
    +                $result_profile['id_appagebuilder_profiles'] = $profile_obj->id;
    +                $result_profile['name'] = $profile_obj->name;
    +                $result_profile['header'] = $profile_obj->header;
    +                $result_profile['content'] = $profile_obj->content;
    +                $result_profile['footer'] = $profile_obj->footer;
    +                $result_profile['product'] = $profile_obj->product;
    +                $result_profile['page'] = $profile_obj->page;
    +            }
    +        }
    +        if (isset($result_profile) && $result_profile) {
    +            $positions_dum = array();
    +            // Get default config - data of current position
    +            $positions_dum['header'] = $result_profile['header'] ? $model->getAllItemsByPosition('header', $result_profile['header'], $id_profile) : array('content' => $this->extractHookDefault(Configuration::get('APPAGEBUILDER_HEADER_HOOK')), 'dataForm' => array());
    +            $positions_dum['content'] = $result_profile['content'] ? $model->getAllItemsByPosition('content', $result_profile['content'], $id_profile) : array('content' => $this->extractHookDefault(Configuration::get('APPAGEBUILDER_CONTENT_HOOK')), 'dataForm' => array());
    +            $positions_dum['footer'] = $result_profile['footer'] ? $model->getAllItemsByPosition('footer', $result_profile['footer'], $id_profile) : array('content' => $this->extractHookDefault(Configuration::get('APPAGEBUILDER_FOOTER_HOOK')), 'dataForm' => array());
    +            $positions_dum['product'] = $result_profile['product'] ? $model->getAllItemsByPosition('product', $result_profile['product'], $id_profile) : array('content' => $this->extractHookDefault(Configuration::get('APPAGEBUILDER_PRODUCT_HOOK')), 'dataForm' => array());
    +            // Extract for display
    +            $positions = array();
    +            $position_data_form = array();
    +            foreach ($positions_dum as $key => $val) {
    +                $temp = $val['content'];
    +                $position_data_form[$key] = Tools::jsonEncode($val['dataForm']);
    +                foreach ($temp as $key_hook => &$row) {
    +                    if (!is_array($row)) {
    +                        $row = array('hook_name' => $key_hook, 'content' => '');
    +                    }
    +                    if ($key_hook == 'displayLeftColumn' || $key_hook == 'displayRightColumn') {
    +                        $row['class'] = 'col-md-3';
    +                    } else {
    +                        $row['class'] = 'col-md-12';
    +                    }
    +                }
    +                $positions[$key] = $temp;
    +            }
    +            
    +            // Get list position for dropdowns
    +            $list_positions = array();
    +            $list_positions['header'] = $model->getListPositisionByType('header', $this->context->shop->id);
    +            $list_positions['content'] = $model->getListPositisionByType('content', $this->context->shop->id);
    +            $list_positions['footer'] = $model->getListPositisionByType('footer', $this->context->shop->id);
    +            $list_positions['product'] = $model->getListPositisionByType('product', $this->context->shop->id);
    +            // Get current position name
    +
    +            $current_position = array();
    +            $current_position['header'] = $this->getCurrentPosition($list_positions['header'], $result_profile['header']);
    +            $current_position['content'] = $this->getCurrentPosition($list_positions['content'], $result_profile['content']);
    +            $current_position['footer'] = $this->getCurrentPosition($list_positions['footer'], $result_profile['footer']);
    +            $current_position['product'] = $this->getCurrentPosition($list_positions['product'], $result_profile['product']);
    +            $data_by_hook = array();
    +            $data_form = '{}';
    +            $data = $model->getAllItems($result_profile);
    +
    +            if ($data) {
    +                $data_by_hook = $data['content'];
    +                $data_form = Tools::jsonEncode($data['dataForm']);
    +
    +                foreach ($data_by_hook as $key_hook => &$row) {
    +                    if (!is_array($row)) {
    +                        $row = array('hook_name' => $key_hook, 'content' => '');
    +                    }
    +                    if ($key_hook == 'displayLeftColumn' || $key_hook == 'displayRightColumn') {
    +                        $row['class'] = 'col-md-3';
    +                    } else {
    +                        $row['class'] = 'col-md-12';
    +                    }
    +                }
    +            }
    +
    +            // Get list item for dropdown export
    +            $export_items = array();
    +            $export_items['Header'] = ApPageSetting::getHook('header');
    +            $export_items['Content'] = ApPageSetting::getHook('content');
    +            $export_items['Footer'] = ApPageSetting::getHook('footer');
    +            $export_items['Product'] = ApPageSetting::getHook('product');
    +            // get shortcode information
    +            $shortcode_infos = ApShortCodeBase::getShortCodeInfos();
    +            //include all short code default
    +            $shortcodes = Tools::scandir($this->tpl_path.'/ap_page_builder_shortcodes', 'tpl');
    +            $shortcode_form = array();
    +            foreach ($shortcodes as $s_from) {
    +                if ($s_from == 'shortcodelist.tpl') {
    +                    continue;
    +                }
    +                $shortcode_form[] = $this->tpl_path.'/ap_page_builder_shortcodes/'.$s_from;
    +            }
    +            
    +            // ROOT//modules/appagebuilder/views/templates/admin/ap_page_builder_home/home.tpl
    +            $tpl = $this->createTemplate('home.tpl');
    +            
    +            $languages = array();
    +            foreach (Language::getLanguages(false) as $lang) {
    +                $languages[$lang['iso_code']] = $lang['id_lang'];
    +            }
    +            //DONGND: check enable save multithreading
    +            if (Configuration::get('APPAGEBUILDER_SAVE_MULTITHREARING')) {
    +                $check_save_multithreading = 1;
    +            } else {
    +                $check_save_multithreading = 0;
    +            };
    +            
    +            //DONGND: check enable save submit
    +            if (Configuration::get('APPAGEBUILDER_SAVE_SUBMIT')) {
    +                $check_save_submit = 1;
    +            } else {
    +                $check_save_submit = 0;
    +            };
    +            
    +            //DONGND: error when submit
    +            $errorSubmit = '';
    +            if (Tools::isSubmit('errorSubmit')) {
    +                $errorSubmit = $this->l('There was an error during save. Please try again and check the value of server config: max_input_vars, make sure it is greater than 30000');
    +            }
    +            
    +            $tpl->assign(array(
    +                'positions' => $positions,
    +                'listPositions' => $list_positions,
    +                //'positionDataForm' => $position_data_form,
    +                'dataByHook' => $data_by_hook,
    +                'exportItems' => $export_items,
    +                'currentProfile' => $result_profile,
    +                'currentPosition' => $current_position,
    +                'profilesList' => $this->getAllProfiles($result_profile['id_appagebuilder_profiles']),
    +                'tplPath' => $this->tpl_path,
    +                'ajaxShortCodeUrl' => Context::getContext()->link->getAdminLink('AdminApPageBuilderShortcodes'),
    +                'ajaxHomeUrl' => Context::getContext()->link->getAdminLink('AdminApPageBuilderHome'),
    +                'shortcodeForm' => $shortcode_form,
    +                'moduleDir' => _MODULE_DIR_,
    +                // Not run with multi_shop (ex block carousel cant get image in backend multi_shop)
    +//                'imgModuleLink' => _THEME_IMG_DIR_.'modules/'.$this->module_name.'/images/',
    +                'imgModuleLink' => apPageHelper::getImgThemeUrl(),
    +                'shortcodeInfos' => Tools::jsonEncode($shortcode_infos),
    +                'languages' => Tools::jsonEncode($languages),
    +                'dataForm' => $data_form,
    +                'errorText' => $this->error_text,
    +                'imgController' => Context::getContext()->link->getAdminLink('AdminApPageBuilderImages'),
    +                'widthList' => ApPageSetting::returnWidthList(),
    +                'lang_id' => (int)$this->context->language->id,
    +                'idProfile' => $id_profile,
    +                'checkSaveMultithreading' => $check_save_multithreading,
    +                'checkSaveSubmit' => $check_save_submit,
    +                'errorSubmit' => $errorSubmit,
    +                'listAnimation' => ApPageSetting::getAnimationsColumnGroup(),
    +                
    +            ));
    +            $path_guide = $this->getTemplatePath().'guide.tpl';
    +            $guide_box = ApPageSetting::buildGuide($this->context, $path_guide, 3);
    +            return $guide_box.$tpl->fetch();
    +        } else {
    +            $this->errors[] = $this->l('Your Profile ID is not exist!');
    +        }
    +    }
    +    
    +    private function exportData()
    +    {
    +        $action = Tools::getValue('action');
    +        $type = Tools::getValue('type');
    +        
    +        $data = $this->saveData($action, $type);
    +        if ($data) {
    +            if ($type == 'all') {
    +                $this->file_content = '';
    +                foreach ($data as $key => $hook) {
    +                    $this->file_content .= '<'.$key.'>';
    +                    if (is_string($hook)) {
    +                        $hook = array();
    +                    }
    +                    foreach ($hook as $lang => $group) {
    +                        $this->file_content .= '<'.$lang.'>';
    +                        $this->file_content .= '';
    +                        $this->file_content .= '';
    +                    }
    +                    $this->file_content .= '';
    +                }
    +                $this->file_content .= '';
    +            } else if (strpos($type, 'position') !== false) {
    +                // Export position
    +                $this->file_content = '<'.'position'.'>';
    +                foreach ($data as $key => $hook) {
    +                    $this->file_content .= '<'.$key.'>';
    +                    if (is_string($hook)) {
    +                        $hook = array();
    +                    }
    +                    foreach ($hook as $lang => $group) {
    +                        $this->file_content .= '<'.$lang.'>';
    +                        $this->file_content .= '';
    +                        $this->file_content .= '';
    +                    }
    +                    $this->file_content .= '';
    +                }
    +                $this->file_content .= '';
    +            } else if ($type == 'group') {
    +                //export group
    +                foreach ($data as $lang => $group) {
    +                    if (is_string($group)) {
    +                        $this->file_content .= '<'.$lang.'>';
    +                        $this->file_content .= '';
    +                        $this->file_content .= '';
    +                    }
    +                }
    +            } else {
    +                //export all group in hook
    +                foreach ($data as $lang => $group) {
    +                    if (is_string($group)) {
    +                        $this->file_content .= '<'.$lang.'>';
    +                        $this->file_content .= '';
    +                        $this->file_content .= '';
    +                    }
    +                }
    +            }
    +            $href = $this->createXmlFile($type);
    +            $array = array('hasError' => false, 'result' => $href);
    +            die(Tools::jsonEncode($array));
    +        }
    +    }
    +            
    +    private function importData($language, $lang_id)
    +    {
    +        $upload_file = new Uploader('importFile');
    +        $upload_file->setAcceptTypes(array('xml'));
    +        $file = $upload_file->process();
    +        $file = $file[0];
    +        $files_content = simplexml_load_file($file['save_path']);
    +        $hook_list = array();
    +        $hook_list = array_merge($hook_list, explode(',', Configuration::get('APPAGEBUILDER_HEADER_HOOK')));
    +        $hook_list = array_merge($hook_list, explode(',', Configuration::get('APPAGEBUILDER_CONTENT_HOOK')));
    +        $hook_list = array_merge($hook_list, explode(',', Configuration::get('APPAGEBUILDER_FOOTER_HOOK')));
    +        $hook_list = array_merge($hook_list, explode(',', Configuration::get('APPAGEBUILDER_PRODUCT_HOOK')));
    +        $import_for = Tools::getValue('import_for');
    +        $override = Tools::getValue('override');
    +        self::$language = Language::getLanguages(false);
    +        $id_profile = Tools::getValue('id_profile');
    +        $profile = new ApPageBuilderProfilesModel($id_profile);
    +        if (!$profile->id || !$profile->header || !$profile->content || !$profile->footer || !$profile->product) {
    +            // validate module
    +            die('Pease click save Profile before run import function. click back to try again!');
    +        }
    +
    +        $lang_iso = 'en';
    +        $lang_list = array();
    +        foreach ($language as $lang) {
    +            $lang_list[$lang['iso_code']] = $lang['id_lang'];
    +            if ($lang['id_lang'] == $lang_id) {
    +                $lang_iso = $lang['iso_code'];
    +            }
    +        }
    +        // Import all mdoule
    +        if (isset($files_content->module)) {
    +            if ($import_for != 'all') {
    +                $this->errors[] = $this->trans('That is not the file for module, please select other file.', array(), 'Admin.Notifications.Error');
    +                return 'ERORR_ALL';
    +            }
    +            $module = $files_content->module;
    +            foreach ($hook_list as $hook) {
    +                $import_hook = $module->{$hook};
    +                $model = new ApPageBuilderModel();
    +                foreach ($language as $lang) {
    +                    $obj = $model->getIdbyHookNameAndProfile($hook, $profile, $lang_list[$lang['iso_code']]);
    +                    if ($override) {
    +                        $params = apPageHelper::replaceFormId($import_hook->{$lang['iso_code']});
    +                    } else {
    +                        $params = $obj['params'];
    +                        $params .= apPageHelper::replaceFormId($import_hook->{$lang['iso_code']});
    +                    }
    +                    $model->updateAppagebuilderLang($obj['id_appagebuilder'], $lang_list[$lang['iso_code']], $params);
    +                }
    +            }
    +        } else if (isset($files_content->position)) {
    +            // Import a position
    +            $arr_positions = array('header', 'content', 'footer', 'product');
    +            if (!in_array($import_for, $arr_positions)) {
    +                $this->errors[] = $this->trans('That is not file for position, please select import for positon: header or content or footer or product', array(), 'Admin.Notifications.Error');
    +                return 'ERORR_POSITION';
    +            }
    +            $position = $files_content->position;
    +            $hook_name = '';
    +            if ($import_for == 'header') {
    +                $hook_name = 'APPAGEBUILDER_HEADER_HOOK';
    +            } else if ($import_for == 'content') {
    +                $hook_name = 'APPAGEBUILDER_CONTENT_HOOK';
    +            } else if ($import_for == 'footer') {
    +                $hook_name = 'APPAGEBUILDER_FOOTER_HOOK';
    +            } else if ($import_for == 'product') {
    +                $hook_name = 'APPAGEBUILDER_PRODUCT_HOOK';
    +            }
    +            $hook_list = explode(',', Configuration::get($hook_name));
    +            foreach ($hook_list as $hook) {
    +                $import_hook = $position->{$hook};
    +                $model = new ApPageBuilderModel();
    +                foreach ($language as $lang) {
    +                    $obj = $model->getIdbyHookNameAndProfile($hook, $profile, $lang_list[$lang['iso_code']]);
    +                    if ($override) {
    +                        $params = apPageHelper::replaceFormId($import_hook->{$lang['iso_code']});
    +                    } else {
    +                        $params = $obj['params'];
    +                        $params .= apPageHelper::replaceFormId($import_hook->{$lang['iso_code']});
    +                    }
    +                    $model->updateAppagebuilderLang($obj['id_appagebuilder'], $lang_list[$lang['iso_code']], $params);
    +                }
    +            }
    +        } else {
    +            // Import only for a group - a hook
    +            $arr_positions = array('header', 'content', 'footer', 'product');
    +            if ($import_for == 'all' || in_array($import_for, $arr_positions)) {
    +                $this->errors[] = $this->trans('That is not file for module, please select other file.', array(), 'Admin.Notifications.Error');
    +                return 'ERORR_NOT_ALL';
    +            }
    +            $import_hook = $import_for;
    +            $hook = $import_for;
    +            foreach ($language as $lang) {
    +                $model = new ApPageBuilderModel();
    +                $obj = $model->getIdbyHookNameAndProfile($hook, $profile, $lang_list[$lang['iso_code']]);
    +                if ($override) {
    +                    $params = apPageHelper::replaceFormId($files_content->{$lang['iso_code']});
    +                } else {
    +                    $params = $obj['params'];
    +                    $params .= apPageHelper::replaceFormId($files_content->{$lang['iso_code']});
    +                }
    +                $model->updateAppagebuilderLang($obj['id_appagebuilder'], $lang_list[$lang['iso_code']], $params);
    +            }
    +        }
    +        // validate module
    +        unset($lang_iso);
    +        $this->confirmations[] = $this->trans('Import Success', array(), 'Admin.Notifications.Success');
    +        return 'ok';
    +    }
    +
    +    public function extractHookDefault($str_hook = '')
    +    {
    +        $result = array();
    +        if ($str_hook) {
    +            $arr = explode(',', $str_hook);
    +            $len = count($arr);
    +            for ($i = 0; $i < $len; $i++) {
    +                $result[$arr[$i]] = $i;
    +            }
    +        }
    +        return $result;
    +    }
    +
    +    public function getAllProfiles($id)
    +    {
    +        $current_id = Tools::getValue('id_appagebuilder_profiles');
    +        $profile_obj = new ApPageBuilderProfilesModel($current_id);
    +        return $profile_obj->getProfilesInPage($id);
    +    }
    +
    +    /**
    +     * Get template a position
    +     */
    +    public function selectPosition($id = '')
    +    {
    +        $position = Tools::getValue('position');
    +        $id_position = $id ? $id : (int)Tools::getValue('id');
    +        $id_duplicate = (int)Tools::getValue('is_duplicate');
    +        $content = '';
    +        $tpl_name = 'position.tpl';
    +        $path = '';
    +
    +        if (file_exists($this->theme_dir.'modules/'.$this->module->name.'/views/templates/admin/'.$tpl_name)) {
    +            $path = $this->theme_dir.'modules/'.$this->module->name.'/views/templates/admin/'.$tpl_name;
    +        } elseif (file_exists($this->getTemplatePath().$this->override_folder.$tpl_name)) {
    +            $path = $this->getTemplatePath().$this->override_folder.$tpl_name;
    +        }
    +        $model = new ApPageBuilderModel();
    +        $positions_dum = $id_position ?
    +                $model->getAllItemsByPosition($position, $id_position) :
    +                array('content' => $this->extractHookDefault(Configuration::get('APPAGEBUILDER_' . Tools::strtoupper($position).'_HOOK')), 'dataForm' => array());
    +        $list_positions = $model->getListPositisionByType(Tools::strtolower($position), $this->context->shop->id);
    +        $current_position = $this->getCurrentPosition($list_positions, $id_position);
    +
    +        foreach ($positions_dum['content'] as $key_hook => &$row) {
    +            if (!is_array($row)) {
    +                $row = array('hook_name' => $key_hook, 'content' => '');
    +            }
    +            if ($key_hook == 'displayLeftColumn' || $key_hook == 'displayRightColumn') {
    +                $row['class'] = 'col-md-3';
    +            } else {
    +                $row['class'] = 'col-md-12';
    +            }
    +        }
    +        $positions = $positions_dum['content'];
    +        $data_form = Tools::jsonEncode($positions_dum['dataForm']);
    +        $id_position = $id_duplicate ? 0 : $id_position;
    +        $this->context->smarty->assign(array(
    +            'default' => $current_position,
    +            'position' => $position,
    +            'listPositions' => $list_positions,
    +            'config' => $positions,
    +        ));
    +        $content = $this->context->smarty->fetch($path);
    +        $result = array('status' => 'SUCCESS', 'message' => '', 'html' => $content,
    +            'position' => $position, 'id' => $id_position, 'data' => $data_form);
    +
    +        die(Tools::jsonEncode($result));
    +        // Check this position is using by other profile
    +    }
    +
    +    /**
    +     * Process: add, update, duplicate a position
    +     */
    +    public function processPosition()
    +    {
    +        $name = Tools::getValue('name');
    +        $position = Tools::getValue('position');
    +        $id_position = (int)Tools::getValue('id');
    +        $mode = Tools::getValue('mode');
    +        if ($mode == 'duplicate') {
    +            $adapter = new AdminApPageBuilderPositionsController();
    +            $id_position = $adapter->duplicatePosition($id_position, 'ajax', $name);
    +        } else if ($mode == 'new') {
    +            $key = ApPageSetting::getRandomNumber();
    +            $name = $name ? $name : $position.$key;
    +            $position_controller = new AdminApPageBuilderPositionsController();
    +
    +            $position_data = array(
    +                'name' => $name,
    +                'position' => $position,
    +                'position_key' => 'position'.$key,
    +            );
    +            $id_position = $position_controller->autoCreatePosition($position_data);
    +        } else if ($mode == 'edit') {
    +            // Edit only name
    +            $position_controller = new AdminApPageBuilderPositionsController();
    +            $position_controller->updateName($id_position, $name);
    +        }
    +        // Reload position
    +        if ($mode == 'new' || $mode == 'duplicate') {
    +            $this->selectPosition($id_position);
    +        } else {
    +            die(Tools::jsonEncode(array('status' => 'SUCCESS')));
    +        }
    +    }
    +
    +    private function getCurrentPosition($list, $id)
    +    {
    +        if ($list) {
    +            foreach ($list as $item) {
    +                if (isset($item['id_appagebuilder_positions']) && $item['id_appagebuilder_positions'] == $id) {
    +                    return array('id' => $id, 'name' => $item['name']);
    +                }
    +            }
    +        }
    +        return array('id' => '0', 'name' => '');
    +    }
    +    
    +    private function getParamByHook($groups, $params, $hook, $action = 'save')
    +    {
    +        $groups['params']['specific_type'] = (isset($groups['params']['specific_type']) && $groups['params']['specific_type']) ? $groups['params']['specific_type'] : '';
    +        $groups['params']['controller_pages'] = (isset($groups['params']['controller_pages']) && $groups['params']['controller_pages']) ? $groups['params']['controller_pages'] : '';
    +        $groups['params']['controller_id'] = (isset($groups['params']['controller_id']) && $groups['params']['controller_id']) ? $groups['params']['controller_id'] : '';
    +        $params .= '[ApRow'.ApShortCodesBuilder::converParamToAttr($groups['params'], 'ApRow', $this->theme_dir).']';
    +        //check exception page
    +        $this->saveExceptionConfig($hook, $groups['params']['specific_type'], $groups['params']['controller_pages'], $groups['params']['controller_id']);
    +        foreach ($groups['columns'] as $columns) {
    +            $columns['params']['specific_type'] = (isset($columns['params']['specific_type']) && $columns['params']['specific_type']) ? $columns['params']['specific_type'] : '';
    +            $columns['params']['controller_pages'] = (isset($columns['params']['controller_pages']) && $columns['params']['controller_pages']) ? $columns['params']['controller_pages'] : '';
    +            $columns['params']['controller_id'] = (isset($columns['params']['controller_id']) && $columns['params']['controller_id']) ? $columns['params']['controller_id'] : '';
    +            $this->saveExceptionConfig($hook, $columns['params']['specific_type'], $columns['params']['controller_pages'], $columns['params']['controller_id']);
    +            $params .= '[ApColumn'.ApShortCodesBuilder::converParamToAttr($columns['params'], 'ApColumn', $this->theme_dir).']';
    +            foreach ($columns['widgets'] as $widgets) {
    +                if ($widgets['type'] == 'ApTabs' || $widgets['type'] == 'ApAccordions') {
    +                    $params .= '['.$widgets['type'].ApShortCodesBuilder::converParamToAttr($widgets['params'], $widgets['type'], $this->theme_dir).']';
    +                    foreach ($widgets['widgets'] as $sub_widgets) {
    +                        $type_sub = Tools::substr($widgets['type'], 0, -1);
    +                        $params .= '['.$type_sub.ApShortCodesBuilder::converParamToAttr($sub_widgets['params'], str_replace('_', '_sub_', $widgets['type']), $this->theme_dir).']';
    +                        foreach ($sub_widgets['widgets'] as $sub_widget) {
    +                            $params .= '['.$sub_widget['type']
    +                                    .ApShortCodesBuilder::converParamToAttr($sub_widget['params'], $sub_widget['type'], $this->theme_dir).'][/'
    +                                    .$sub_widget['type'].']';
    +                        }
    +                        $params .= '[/'.$type_sub.']';
    +                    }
    +                    $params .= '[/'.$widgets['type'].']';
    +                } else {
    +                    $params .= '['.$widgets['type'].ApShortCodesBuilder::converParamToAttr($widgets['params'], $widgets['type'], $this->theme_dir).'][/'.$widgets['type'].']';
    +                    if ($widgets['type'] == 'ApModule' && $action == 'save') {
    +                        $is_delete = (int)$widgets['params']['is_display'];
    +                        if ($is_delete) {
    +                            if (!isset($widgets['params']['hook'])) {
    +                                // FIX : Module not choose hook -> error
    +                                $widgets['params']['hook'] = '';
    +                            }
    +                            $this->deleteModuleFromHook($widgets['params']['hook'], $widgets['params']['name_module']);
    +                        }
    +                    } else if ($widgets['type'] == 'ApProductCarousel') {
    +                        if ($widgets['params']['order_way'] == 'random') {
    +                            $this->config_module[$hook]['productCarousel']['order_way'] = 'random';
    +                        }
    +                    }
    +                }
    +            }
    +            $params .= '[/ApColumn]';
    +        }
    +        $params .= '[/ApRow]';
    +        return $params;
    +    }
    +    
    +    public function clearModuleCache()
    +    {
    +        $module = APPageBuilder::getInstance();
    +        $module->clearHookCache();
    +    }
    +    
    +    private function deleteDirectory($dir)
    +    {
    +        if (!file_exists($dir)) {
    +            return true;
    +        }
    +        if (!is_dir($dir) || is_link($dir)) {
    +            return unlink($dir);
    +        }
    +        foreach (scandir($dir) as $item) {
    +            if ($item == '.' || $item == '..') {
    +                continue;
    +            }
    +            if (!$this->deleteDirectory($dir.'/'.$item)) {
    +                chmod($dir.'/'.$item, 0777);
    +                if (!$this->deleteDirectory($dir.'/'.$item)) {
    +                    return false;
    +                }
    +            }
    +        }
    +        return rmdir($dir);
    +    }
    +    
    +    private function deleteModuleFromHook($hook_name, $module_name)
    +    {
    +        $res = true;
    +        $sql = 'DELETE FROM `'._DB_PREFIX_.'hook_module`
    +                WHERE `id_hook` IN( 
    +                    SELECT `id_hook` FROM `'._DB_PREFIX_.'hook`
    +                    WHERE name ="'.pSQL($hook_name).'") AND `id_module` IN( SELECT `id_module` FROM `'._DB_PREFIX_.'module` WHERE name ="'.pSQL($module_name).'")';
    +        $res &= Db::getInstance()->execute($sql);
    +        return $res;
    +    }
    +    
    +    private function saveExceptionConfig($hook, $type, $page, $ids)
    +    {
    +        if (!$type) {
    +            return;
    +        }
    +
    +        if ($type == 'all') {
    +            if ($type != '') {
    +                $list = explode(',', $page);
    +                foreach ($list as $val) {
    +                    $val = trim($val);
    +                    if ($val && (!is_array($this->config_module) || !isset($this->config_module[$hook]) || !isset($this->config_module[$hook]['exception']) || !isset($val, $this->config_module[$hook]['exception']))) {
    +                        $this->config_module[$hook]['exception'][] = $val;
    +                    }
    +                }
    +            }
    +        } else {
    +            $this->config_module[$hook][$type] = array();
    +            if ($type != 'index') {
    +                $ids = explode(',', $ids);
    +                foreach ($ids as $val) {
    +                    $val = trim($val);
    +                    if (!in_array($val, $this->config_module[$hook][$type])) {
    +                        $this->config_module[$hook][$type][] = $val;
    +                    }
    +                }
    +            }
    +        }
    +    }
    +    
    +    public function createXmlFile($title)
    +    {
    +        $file_content = '';
    +        $file_content .= '';
    +        $file_content .= $this->file_content;
    +        $file_content .= '';
    +        //save file content to sample data
    +
    +        $folder = $this->theme_dir.'export/';
    +        if (!is_dir($folder)) {
    +            mkdir($folder, 0755, true);
    +        }
    +        if ($title == 'all') {
    +            $title = 'appagebuilder';
    +        }
    +
    +        ApPageSetting::writeFile($folder, $title.'.xml', $file_content);
    +
    +        return _THEMES_DIR_._THEME_NAME_.'/'.'export/'.$title.'.xml';
    +    }
    +    
    +    /**
    +     * PERMISSION ACCOUNT demo@demo.com
    +     * OVERRIDE CORE
    +     * classes\controller\AdminController.php
    +     */
    +    public function getTabSlug()
    +    {
    +        if (empty($this->tabSlug)) {
    +            
    +            // GET RULE FOLLOW AdminApPageBuilderProfiles
    +            $result = Db::getInstance()->getRow('
    +                SELECT `id_tab`
    +                FROM `'._DB_PREFIX_.'tab`
    +                WHERE UCASE(`class_name`) = "'.'AdminApPageBuilderProfiles'.'"
    +            ');
    +            $profile_id = $result['id_tab'];
    +            $this->tabSlug = Access::findSlugByIdTab($profile_id);
    +        }
    +
    +        return $this->tabSlug;
    +    }
    +    
    +    /**
    +     * PERMISSION ACCOUNT demo@demo.com
    +     * OVERRIDE CORE
    +     */
    +    public function initProcess()
    +    {
    +        parent::initProcess();
    +        if (count($this->errors) <= 0) {
    +            
    +            if (!$this->access('edit')){
    +                if (Tools::isSubmit('submitSaveAndStay')) {
    +                    $this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
    +                }elseif (Tools::isSubmit('submitImportData')) {
    +                    $this->errors[] = $this->trans('You do not have permission to import.', array(), 'Admin.Notifications.Error');
    +                }elseif( Tools::getIsset('action') && Tools::getValue('action') == 'export'){
    +                    $this->errors[] = $this->trans('You do not have permission to export this.', array(), 'Admin.Notifications.Error');
    +                }
    +                
    +            }
    +                    
    +            if (!$this->access('edit') && $this->ajax){
    +                if(Tools::getValue('action') == 'showImportForm')
    +                {
    +                    $this->errors[] = $this->trans('You do not have permission to import.', array(), 'Admin.Notifications.Error');
    +                } elseif(Tools::getValue('action') == 'renderList')
    +                {
    +                    // Allow
    +                }else{
    +                    # DEFAULT
    +                    $this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
    +                }
    +            }
    +        }
    +    }
    +}
    diff --git a/modules/appagebuilder/controllers/admin/AdminApPageBuilderHook.php b/modules/appagebuilder/controllers/admin/AdminApPageBuilderHook.php
    new file mode 100644
    index 00000000..9706dc07
    --- /dev/null
    +++ b/modules/appagebuilder/controllers/admin/AdminApPageBuilderHook.php
    @@ -0,0 +1,414 @@
    +
    + *  @copyright 2007-2015 Apollotheme
    + *  @license   http://apollotheme.com - prestashop template provider
    + */
    +
    +require_once(_PS_MODULE_DIR_.'appagebuilder/libs/Helper.php');
    +
    +if (!defined('_PS_VERSION_')) {
    +    # module validation
    +    exit;
    +}
    +
    +class AdminApPageBuilderHookController extends ModuleAdminControllerCore
    +{
    +    /**
    +     * @var Boolean $display_key
    +     *
    +     * @access protected
    +     */
    +    public $display_key = 0;
    +    /**
    +     * @var Array $hookspos
    +     *
    +     * @access protected
    +     */
    +    public $hookspos = array();
    +    /**
    +     * @var Array $ownPositions
    +     *
    +     * @access protected
    +     */
    +//    public $ownPositions = array();
    +    /**
    +     * @var String $theme_name
    +     *
    +     * @access protected
    +     */
    +    public $theme_name;
    +    /**
    +     * @var String $theme_name
    +     *
    +     * @access protected
    +     */
    +    public $themeKey;
    +
    +    /**
    +     * Constructor
    +     */
    +    public function __construct()
    +    {
    +        $this->bootstrap = true;
    +        $this->table = 'leohook';
    +        $this->className = 'AdminApPageBuilderHook';
    +        $this->lang = true;
    +        $this->context = Context::getContext();
    +        parent::__construct();
    +        $this->display_key = (int)Tools::getValue('show_modules');
    +
    +//        $this->ownPositions = array(
    +//            'displayHeaderRight',
    +//            'displaySlideshow',
    +//            'topNavigation',
    +//            'displayPromoteTop',
    +//            'displayBottom',
    +//            'displayMassBottom'
    +//        );
    +        $this->hookspos = ApPageSetting::getHook();
    +        $this->theme_name = _THEME_NAME_;
    +    }
    +    
    +    /**
    +     * Build List linked Icons Toolbar
    +     */
    +    public function initPageHeaderToolbar()
    +    {
    +        if (empty($this->display)) {
    +            $this->page_header_toolbar_btn['save'] = array(
    +                'href' => 'index.php?tab=AdminApPageBuilderHook&token='.Tools::getAdminTokenLite('AdminApPageBuilderHook').'&action=savepos',
    +                'id' => 'savepos',
    +                'desc' => $this->l('Save Positions')
    +            );
    +        }
    +        parent::initPageHeaderToolbar();
    +    }
    +
    +    /**
    +     * get live Edit URL
    +     */
    +    public function getLiveEditUrl($live_edit_params)
    +    {
    +        $url = $this->context->shop->getBaseURL().Dispatcher::getInstance()->createUrl('index', (int)$this->context->language->id, $live_edit_params);
    +        if (Configuration::get('PS_REWRITING_SETTINGS')) {
    +            $url = str_replace('index.php', '', $url);
    +        }
    +        return $url;
    +    }
    +
    +    /**
    +     * add toolbar icons
    +     */
    +    public function initToolbar()
    +    {
    +        $this->context->smarty->assign('toolbar_scroll', 1);
    +        $this->context->smarty->assign('show_toolbar', 1);
    +        $this->context->smarty->assign('toolbar_btn', $this->toolbar_btn);
    +        $this->context->smarty->assign('title', $this->toolbar_title);
    +    }
    +
    +    /**
    +     * render list of modules following positions in the layout editor.
    +     */
    +    public function renderList()
    +    {
    +        $filePath = _PS_ALL_THEMES_DIR_.$this->theme_name.'';
    +        $showed = true;
    +        $xml = simplexml_load_file($filePath.'/config.xml');
    +
    +        if (isset($xml->theme_key)) {
    +            $this->themeKey = trim((string)$xml->theme_key);
    +        }
    +        $this->themeKey = '1111';
    +        if ($this->themeKey) {
    +            $this->initToolbarTitle();
    +            $this->initToolbar();
    +            $hookspos = $this->hookspos;
    +
    +            foreach ($hookspos as $hook) {
    +                if (Hook::getIdByName($hook)) {
    +                    // validate module
    +                } else {
    +                    $new_hook = new Hook();
    +                    $new_hook->name = pSQL($hook);
    +                    $new_hook->title = pSQL($hook);
    +                    $new_hook->add();
    +//                    $id_hook = $new_hook->id;
    +                }
    +            }
    +
    +//            $sql = 'UPDATE `'._DB_PREFIX_.'hook` SET position=1, live_edit=1
    +//                        WHERE name in ("'.implode('","', $hookspos).'")  ';
    +//            Db::getInstance(_PS_USE_SQL_SLAVE_)->execute($sql);
    +
    +            $modules = Module::getModulesInstalled(0);
    +            $assoc_modules_id = array();
    +
    +            $assoc_modules_id = $module_instances = array();
    +            foreach ($modules as $module) {
    +                if ($tmp_instance = Module::getInstanceById((int)$module['id_module'])) {
    +                    // We want to be able to sort modules by display name
    +                    $module_instances[$tmp_instance->displayName] = $tmp_instance;
    +                    // But we also want to associate hooks to modules using the modules IDs
    +                    $assoc_modules_id[(int)$module['id_module']] = $tmp_instance->displayName;
    +                }
    +            }
    +            $hooks = Hook::getHooks(!(int)Tools::getValue('hook_position'));
    +
    +            $hookModules = array();
    +
    +            $hookedModules = array();
    +            foreach ($hooks as $key => $hook) {
    +                // validate module
    +                unset($key);
    +                
    +                $k = $hook['name'];
    +                $k = (Tools::strtolower(Tools::substr($k, 0, 1)).Tools::substr($k, 1));
    +                if (in_array($k, $hookspos)) {
    +                    // Get all modules for this hook or only the filtered module
    +                    $hookModules[$k]['modules'] = Hook::getModulesFromHook($hook['id_hook'], $this->display_key);
    +                    $hookModules[$k]['module_count'] = count($hookModules[$k]['modules']);
    +
    +                    if (is_array($hookModules[$k]['modules']) && !empty($hookModules[$k]['modules'])) {
    +                        foreach ($hookModules[$k]['modules'] as $module_key => $module) {
    +                            if (isset($assoc_modules_id[$module['id_module']])) {
    +                                $hookedModules[] = $module['id_module'];
    +                                $hookModules[$k]['modules'][$module_key]['instance'] = $module_instances[$assoc_modules_id[$module['id_module']]];
    +                            }
    +                        }
    +                    }
    +                }
    +            }
    +
    +            $instances = array();
    +            foreach ($modules as $module) {
    +                if ($tmp_instance = Module::getInstanceById($module['id_module'])) {
    +                    foreach ($hookspos as $hk) {
    +                        $retro_hook_name = Hook::getRetroHookName($hk);
    +                        $hook_callable = is_callable(array($tmp_instance, 'hook'.$hk));
    +                        $hook_retro_callable = is_callable(array($tmp_instance, 'hook'.$retro_hook_name));
    +                        if ($hook_retro_callable || $hook_callable) {
    +                            $instances[$tmp_instance->displayName] = $tmp_instance;
    +                            break;
    +                        }
    +                    }
    +                }
    +            }
    +            ksort($instances);
    +
    +            $tpl = $this->createTemplate('panel.tpl');
    +
    +//            $this->context->controller->addJqueryUI('ui.sortable');
    +//            $this->context->controller->addJqueryUI('ui.draggable');
    +            $this->context->controller->addCss(__PS_BASE_URI__.str_replace('//', '/', 'modules/appagebuilder').'/css/admin/style_hook_cpanel.css', 'all');
    +            $this->context->controller->addJs(__PS_BASE_URI__.str_replace('//', '/', 'modules/appagebuilder').'/js/jquery-ui-1.10.3.custom.min.js', 'all');
    +            $tpl->assign(array(
    +                'showed' => $showed,
    +                'toolbar' => $this->context->smarty->fetch('toolbar.tpl'),
    +                'modules' => $instances,
    +                'hookspos' => $hookspos,
    +                'URI' => __PS_BASE_URI__.'modules/',
    +                'hookModules' => $hookModules,
    +                'noModuleConfig' => $this->l('No Configuration For This Module'),
    +                'currentURL' => 'index.php?tab=AdminApPageBuilderHook&token='.Tools::getAdminTokenLite('AdminApPageBuilderHook').'',
    +//                'moduleEditURL' => 'index.php?tab=AdminApPageBuilderHook&token='.Tools::getAdminTokenLite('AdminApPageBuilderHook').'',
    +                  'moduleEditURL' => 'index.php?controller=adminmodules&token='.Tools::getAdminTokenLite('AdminModules').'&tab_module=Home',
    +            ));
    +
    +            return $tpl->fetch();
    +        } else {
    +            $tpl = $this->createTemplate('error.tpl');
    +            $tpl->assign(array(
    +                'showed' => false,
    +                'themeURL' => 'index.php?controller=AdminThemes&token='.Tools::getAdminTokenLite('AdminThemes')
    +            ));
    +            return $tpl->fetch();
    +        }
    +    }
    +
    +    /**
    +     * Process posting data
    +     */
    +    public function postProcess()
    +    {
    +        if (count($this->errors) > 0) {
    +            if ($this->ajax) {
    +                $array = array('hasError' => true, 'errors' => $this->errors[0]);
    +                die(Tools::jsonEncode($array));
    +            }
    +            return;
    +        }
    +        
    +        if (Tools::getValue('action') && Tools::getValue('action') == 'modulehook') {
    +            // AJAX EDIT HOOK - READ
    +            $id = (int)Tools::getValue('id');
    +
    +            $tmp_instance = Module::getInstanceById($id);
    +            $hooks = array();
    +
    +            foreach ($this->hookspos as $hk) {
    +                $retro_hook_name = Hook::getRetroHookName($hk);
    +                $hook_callable = is_callable(array($tmp_instance, 'hook'.$hk));
    +                $hook_retro_callable = is_callable(array($tmp_instance, 'hook'.$retro_hook_name));
    +
    +                if ($hook_retro_callable || $hook_callable) {
    +                    $hooks[] = $hk;
    +                }
    +            }
    +            $hooks = implode('|', $hooks);
    +            $sql = 'SELECT * FROM `'._DB_PREFIX_.'leohook` WHERE id_module='.(int)$id.' AND theme="'.pSQL($this->theme_name).'" AND id_shop='.(int)($this->context->shop->id);
    +
    +            if ($row = Db::getInstance()->getRow($sql)) {
    +                die('{"hasError" : false, "hook" : "'.$row['name_hook'].'","hooks":"'.$hooks.'"}');
    +            } else {
    +                die('{"hasError" : true, "errors" : "Can not update module position","hooks":"'.$hooks.'"}');
    +            }
    +        }
    +        if (Tools::getValue('action') && Tools::getValue('action') == 'overridehook') {
    +            // AJAX EDIT HOOK - SAVE
    +            $id_module = (int)Tools::getValue('hdidmodule');
    +            $name_hook = Tools::getValue('name_hook');
    +            if (is_numeric($name_hook)) {
    +                $sql = 'DELETE  FROM`'._DB_PREFIX_.'leohook` WHERE id_module='.(int)$id_module.' AND theme="'.pSQL($this->theme_name).'" AND id_shop='.(int)($this->context->shop->id);
    +
    +                Db::getInstance(_PS_USE_SQL_SLAVE_)->execute($sql);
    +                die('{"hasError" : false, "errors" : "done!delete module position"}');
    +            } elseif ($name_hook) {
    +                $desHook = Tools::getValue('deshook');
    +                $desHookId = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('SELECT id_hook FROM `'._DB_PREFIX_."hook` WHERE name='".pSQL($desHook)."'");
    +                $sql = 'SELECT *
    +                    FROM `'._DB_PREFIX_.'leohook` WHERE id_hook= '.(int)$desHookId.' AND id_module='.(int)$id_module.' AND theme="'.pSQL($this->theme_name).'" AND id_shop='.(int)($this->context->shop->id);
    +
    +                if ($row = Db::getInstance()->getRow($sql)) {
    +                    $sql = ' UPDATE `'._DB_PREFIX_.'leohook`  SET `id_hook`='.(int)$desHookId.', name_hook="'.pSQL($name_hook).'"
    +                         WHERE id_module='.(int)$id_module.' AND theme="'.pSQL($this->theme_name).'" AND id_shop='.(int)($this->context->shop->id);
    +                    Db::getInstance(_PS_USE_SQL_SLAVE_)->execute($sql);
    +                } else {
    +                    $sql = ' INSERT INTO `'._DB_PREFIX_.'leohook` (id_hook, id_module, id_shop, theme, name_hook)
    +                        VALUES('.(int)$desHookId.','.(int)$id_module.','.(int)($this->context->shop->id).',"'.pSQL($this->theme_name).'","'.pSQL($name_hook).'")';
    +                    Db::getInstance(_PS_USE_SQL_SLAVE_)->execute($sql);
    +                }
    +                die('{"hasError" : false, "errors" : "done!update module position"}');
    +            }
    +            die('{"hasError" : true, "errors" : "Can not update module position"}');
    +        }
    +        if (Tools::getValue('action') && Tools::getValue('action') == 'savepos') {
    +            // SUBMIT - SAVE HOOK
    +            $positions = Tools::getValue('position');
    +            $way = (int)(Tools::getValue('way'));
    +            $unhook = Tools::getValue('unhook');
    +            $id_shop = Context::getContext()->shop->id;
    +
    +            if (is_array($unhook)) {
    +                foreach ($unhook as $id_module => $str_hookId) {
    +                    $hookIds = explode(',', $str_hookId);
    +                    foreach ($hookIds as $hookId) {
    +                        $module = Module::getInstanceById($id_module);
    +                        if (Validate::isLoadedObject($module)) {
    +                            !$module->unregisterHook((int)$hookId, array($id_shop));
    +                        }
    +                    }
    +                }
    +            }
    +
    +            if (is_array($positions) && !empty($positions)) {
    +                foreach ($positions as $pos) {
    +                    $tmp = explode('|', $pos);
    +                    if (count($tmp) == 2 && $tmp[0] && $tmp[1]) {
    +                        $position = $tmp[0];
    +                        $hookId = Hook::getIdByName($position);
    +                        $oldhooks = explode(',', Tools::getValue($position));
    +
    +                        $ids = explode(',', $tmp[1]);
    +                        if ($hookId && count($oldhooks)) {
    +                            foreach ($ids as $index => $id_module) {
    +                                $module = Module::getInstanceById($id_module);
    +
    +                                if (Validate::isLoadedObject($module) && isset($oldhooks[$index]) && is_numeric($oldhooks[$index]) && $oldhooks[$index] != $hookId) {
    +                                    // MOVE MODULE TO OTHER HOOK
    +                                    $sql = 'UPDATE `'._DB_PREFIX_.'hook_module` SET id_hook='.(int)$hookId.'
    +                                            WHERE id_module='.(int)$id_module.' AND id_hook='.(int)$oldhooks[$index].' AND id_shop='.(int)($id_shop);
    +                                    try {
    +                                        // FIX: Drag a module to one hook in 2 times. Save 500 error
    +                                        Db::getInstance(_PS_USE_SQL_SLAVE_)->execute($sql);
    +                                    } catch (Exception $ex) {
    +                                    }
    +                                } elseif (Validate::isLoadedObject($module) && (!isset($oldhooks[$index]) || !(int)$oldhooks[$index])) {
    +                                    $this->registerHook($id_module, $hookId, array($id_shop));
    +                                    echo 'new:'.$id_module;
    +                                }
    +                                $module->updatePosition($hookId, $way, $index + 1);
    +                            }
    +                        }
    +                    }
    +                }
    +            }
    +            die('{"hasError" : false, "errors" : "update module position"}');
    +        }
    +    }
    +
    +    public function registerHook($id_module, $id_hook, $shop_list = null)
    +    {
    +        // If shop lists is null, we fill it with all shops
    +        if (is_null($shop_list)) {
    +            $shop_list = Shop::getShops(true, null, true);
    +        }
    +
    +        $return = true;
    +        foreach ($shop_list as $shop_id) {
    +            // Check if already register
    +            $sql = 'SELECT hm.`id_module`
    +                FROM `'._DB_PREFIX_.'hook_module` hm, `'._DB_PREFIX_.'hook` h
    +                WHERE hm.`id_module` = '.(int)($id_module).' AND h.`id_hook` = '.(int)$id_hook.'
    +                AND h.`id_hook` = hm.`id_hook` AND `id_shop` = '.(int)$shop_id;
    +
    +
    +            if (Db::getInstance()->getRow($sql)) {
    +                continue;
    +            }
    +
    +            // Get module position in hook
    +            $sql = 'SELECT MAX(`position`) AS position
    +                FROM `'._DB_PREFIX_.'hook_module`
    +                WHERE `id_hook` = '.(int)$id_hook.' AND `id_shop` = '.(int)$shop_id;
    +            if (!$position = Db::getInstance()->getValue($sql)) {
    +                $position = 0;
    +            }
    +
    +            // Register module in hook
    +            $return &= Db::getInstance()->insert('hook_module', array(
    +                'id_module' => (int)$id_module,
    +                'id_hook' => (int)$id_hook,
    +                'id_shop' => (int)$shop_id,
    +                'position' => (int)($position + 1),
    +            ));
    +        }
    +    }
    +    
    +    /**
    +     * PERMISSION ACCOUNT demo@demo.com
    +     * OVERRIDE CORE
    +     */
    +    public function initProcess()
    +    {
    +        parent::initProcess();
    +        
    +        if (count($this->errors) <= 0) {
    +            if(Tools::getIsset('updateleohook') && Tools::getValue('updateleohook')){
    +                if (!$this->access('edit'))
    +                {
    +                    $this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
    +                }
    +            }
    +        }
    +    }
    +}
    diff --git a/modules/appagebuilder/controllers/admin/AdminApPageBuilderImages.php b/modules/appagebuilder/controllers/admin/AdminApPageBuilderImages.php
    new file mode 100644
    index 00000000..8420e897
    --- /dev/null
    +++ b/modules/appagebuilder/controllers/admin/AdminApPageBuilderImages.php
    @@ -0,0 +1,266 @@
    +
    + *  @copyright 2007-2015 Apollotheme
    + *  @license   http://apollotheme.com - prestashop template provider
    + */
    +
    +if (!defined('_PS_VERSION_')) {
    +    # module validation
    +    exit;
    +}
    +
    +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageSetting.php');
    +
    +class AdminApPageBuilderImagesController extends ModuleAdminController
    +{
    +    protected $max_image_size = null;
    +    public $theme_name;
    +    public $module_name = 'appagebuilder';
    +    public $img_path;
    +    public $folder_name;
    +    public $module_path;
    +    public $tpl_path;
    +    public $theme_dir;
    +
    +    public function __construct()
    +    {
    +        parent::__construct();
    +        $this->theme_dir = _PS_THEME_DIR_;
    +        $this->folder_name = Tools::getIsset('imgDir') ? Tools::getValue('imgDir') : 'images';
    +        $this->bootstrap = true;
    +        $this->max_image_size = (int)Configuration::get('PS_PRODUCT_PICTURE_MAX_SIZE');
    +        $this->theme_name = _THEME_NAME_;
    +        $this->img_path = apPageHelper::getImgThemeDir($this->folder_name);
    +        $this->img_url = apPageHelper::getImgThemeUrl($this->folder_name);
    +        $this->className = 'ApPageBuilderImages';
    +        $this->context = Context::getContext();
    +        $this->module_path = __PS_BASE_URI__.'modules/'.$this->module_name.'/';
    +        $this->tpl_path = _PS_ROOT_DIR_.'/modules/'.$this->module_name.'/views/templates/admin';
    +        
    +        # LIVE THEME EDITER
    +        $leo_controller = Tools::getValue('leo_controller');
    +        if ($leo_controller == 'live_theme_edit') {
    +            $this->context->controller->addCss(apPageHelper::getCssAdminDir().'admin/images.css', 'all');
    +            
    +            $this->img_path = _PS_ALL_THEMES_DIR_._THEME_NAME_.'/assets/img/patterns/';
    +            $this->img_url = __PS_BASE_URI__.'themes/'._THEME_NAME_.'/assets/img/patterns/';
    +            $this->context->controller->addCss(apPageHelper::getCssAdminDir().'admin/images.css', 'all');
    +        }
    +    }
    +
    +    /**
    +     * Action Live Theme Editor
    +     */
    +    public function renderList()
    +    {
    +        $tpl = $this->createTemplate('imagemanager.tpl');
    +        $sort_by = Tools::getValue('sortBy');
    +        $images = $this->getImageList($sort_by);
    +        $image_uploader = new HelperImageUploader('file');
    +        $image_uploader->setSavePath($this->img_path);
    +        $image_uploader->setMultiple(true)->setUseAjax(true)->setUrl(Context::getContext()->link->getAdminLink('AdminApPageBuilderImages').'&ajax=1&action=addimage&leo_controller=live_theme_edit');  // url upload image
    +        
    +        $tpl->assign(array(
    +			'img_dir' => $this->folder_name,
    +            'countImages' => count($images),		
    +            'images' => $images,
    +            'max_image_size' => $this->max_image_size / 1024 / 1024,
    +            'image_uploader' => $image_uploader->render(),
    +            'imgManUrl' => Context::getContext()->link->getAdminLink('AdminApPageBuilderImages'),
    +            'token' => $this->token,
    +            'url_param' => '&leo_controller=live_theme_edit'
    +        ));
    +        return $tpl->fetch();
    +    }
    +    
    +    /**
    +     * Action Live Theme Editor
    +     */
    +    public function ajaxProcessReloadBackground()
    +    {
    +        $sort_by = Tools::getValue('sortBy');
    +        $tpl = $this->createTemplate('imagemanager.tpl');
    +        $images = $this->getImageList($sort_by);
    +        $tpl->assign(array(
    +            'images' => $images,
    +            'reloadBack' => 1,
    +        ));
    +        die(Tools::jsonEncode($tpl->fetch()));
    +    }
    +
    +    public function getImageList($sortBy)
    +    {
    +        $path = $this->img_path;
    +        # CACH 1 : lay cac file anh
    +        $images = glob($path.'{*.jpeg,*.JPEG,*.jpg,*.JPG,*.gif,*.GIF,*.png,*.PNG}', GLOB_BRACE);
    +        if ($images === null) {
    +            # CACH 2 : lay cac file anh
    +            $files = scandir($path);
    +            $files = array_diff($files, array('..', '.')); # insert code
    +
    +            $images = array();
    +            foreach ($files as $key => $image) {
    +                # validate module
    +                unset($key);
    +                $ext = Tools::substr($image, strrpos($image, '.') + 1);
    +                if (in_array($ext, array('jpg', 'jpeg', 'png', 'gif', 'JPG', 'JPEG', 'PNG', 'GIF'))) {
    +                    $images[] = $image;
    +                }
    +            }
    +        }
    +
    +        if ($sortBy == 'name_desc') {
    +            rsort($images);
    +        }
    +
    +        if ($sortBy == 'date' || $sortBy == 'date_desc') {
    +            ksort($images);
    +        }
    +        if ($sortBy == 'date_desc') {
    +            rsort($images);
    +        }
    +
    +        $result = array();
    +        foreach ($images as &$file) {
    +            $fileInfo = pathinfo($file);
    +            $result[] = array(
    +                'name' => $fileInfo['basename'],
    +                'link' => $this->img_url.$fileInfo['basename']);
    +        }
    +        return $result;
    +    }
    +    
    +    public function renderTemplate($tpl_name)
    +    {
    +        $path = '';
    +        if (file_exists($this->theme_dir.'modules/'.$this->module->name.'/views/templates/admin/'.$tpl_name) && $this->viewAccess()) {
    +            $path = $this->theme_dir.'modules/'.$this->module->name.'/views/templates/admin/'.$tpl_name;
    +        } elseif (file_exists($this->getTemplatePath().$this->override_folder.$tpl_name) && $this->viewAccess()) {
    +            $path = $this->getTemplatePath().$this->override_folder.$tpl_name;
    +        }
    +        $content = Context::getContext()->smarty->fetch($path);
    +        return $content;
    +    }
    +    
    +    /**
    +     * Action Manage Image
    +     */
    +    public function ajaxProcessManageImage()
    +    {
    +        $smarty = Context::getContext()->smarty;
    +        $sort_by = Tools::getValue('sortBy');
    +        $images = $this->getImageList($sort_by);
    +        $image_uploader = new HelperImageUploader('file');
    +        $image_uploader->setSavePath($this->img_path);
    +        $image_uploader->setTemplateDirectory($this->tpl_path.'/helpers/uploader');
    +        
    +        $image_uploader->setTemplate('ajax.tpl');
    +        $image_uploader->setMultiple(true)->setUseAjax(true)->setUrl(Context::getContext()->link->getAdminLink('AdminApPageBuilderImages').'&ajax=1&action=addimage&imgDir='.$this->folder_name);
    +        $upload_html = $image_uploader->render();
    +        $smarty->assign(array(
    +			'img_dir' => $this->folder_name,
    +            'widget' => Tools::getValue('widget'),
    +            'countImages' => count($images),
    +            'images' => $images,
    +            'max_image_size' => $this->max_image_size / 1024 / 1024,
    +            'image_uploader' => $upload_html,
    +            'imgManUrl' => Context::getContext()->link->getAdminLink('AdminApPageBuilderImages'),
    +            'token' => $this->token,
    +            'link' => Context::getContext()->link,
    +        ));
    +        die($this->renderTemplate('imagemanager.tpl'));
    +    }
    +    
    +    /**
    +     * Action Add Image
    +     */
    +    public function ajaxProcessAddImage()
    +    {
    +        if (isset($_FILES['file'])) {
    +            try {
    +                $image_uploader = new HelperUploader('file');
    +
    +                if (!file_exists($this->img_path)) {
    +                    mkdir($this->img_path, 0755, true);
    +                }
    +                $image_uploader->setSavePath($this->img_path);
    +                $image_uploader->setAcceptTypes(array('jpeg', 'gif', 'png', 'jpg'))->setMaxSize($this->max_image_size);
    +                $total_errors = array();
    +                
    +                $files = $image_uploader->process();
    +                foreach ($files as &$file) {
    +                    $errors = array();
    +                    // Evaluate the memory required to resize the image: ifit's too much, you can't resize it.
    +                    if (!ImageManager::checkImageMemoryLimit($file['save_path'])) {
    +                        $errors[] = Tools::displayError('Due to memory limit restrictions, this image cannot be loaded.
    +                                Please increase your memory_limit value via your server\'s configuration settings.');
    +                    }
    +                    if (count($errors)) {
    +                        $total_errors = array_merge($total_errors, $errors);
    +                    }
    +                    //unlink($file['save_path']);
    +                    //Necesary to prevent hacking
    +                    unset($file['save_path']);
    +                    //Add image preview and delete url
    +                }
    +                if (count($total_errors)) {
    +                    $this->context->controller->errors = array_merge($this->context->controller->errors, $total_errors);
    +                }
    +                $images = $this->getImageList('date');
    +                $tpl = $this->createTemplate('imagemanager.tpl');
    +                $tpl->assign(array(
    +                    'images' => $images,
    +                    'reloadSliderImage' => 1,
    +                    'link' => Context::getContext()->link
    +                ));
    +
    +                die(Tools::jsonEncode($tpl->fetch()));
    +            } catch (Exception $ex) {
    +            }
    +        }
    +    }
    +    
    +    /**
    +     * Action Sort Image
    +     */
    +    public function ajaxProcessReLoadSliderImage()
    +    {
    +        $tpl = $this->createTemplate('imagemanager.tpl');
    +        $sort_by = Tools::getValue('sortBy');
    +        $images = $this->getImageList($sort_by);
    +        $tpl->assign(array(
    +            'images' => $images,
    +            'reloadSliderImage' => 1,
    +            'link' => Context::getContext()->link
    +        ));
    +        die(Tools::jsonEncode($tpl->fetch()));
    +    }
    +    
    +    /**
    +     * Action Delete Image
    +     */
    +    public function ajaxProcessDeleteImage()
    +    {
    +        if (($img_name = Tools::getValue('imgName', false)) !== false) {
    +            unlink($this->img_path.$img_name);
    +            $images = $this->getImageList('date');
    +            $tpl = $this->createTemplate('imagemanager.tpl');
    +            $tpl->assign(array(
    +                'images' => $images,
    +                'reloadSliderImage' => 1,
    +                'link' => Context::getContext()->link
    +            ));
    +
    +            die(Tools::jsonEncode($tpl->fetch()));
    +        }
    +    }
    +}
    diff --git a/modules/appagebuilder/controllers/admin/AdminApPageBuilderModule.php b/modules/appagebuilder/controllers/admin/AdminApPageBuilderModule.php
    new file mode 100644
    index 00000000..72d96491
    --- /dev/null
    +++ b/modules/appagebuilder/controllers/admin/AdminApPageBuilderModule.php
    @@ -0,0 +1,30 @@
    +
    + *  @copyright 2007-2015 Apollotheme
    + *  @license   http://apollotheme.com - prestashop template provider
    + */
    +
    +if (!defined('_PS_VERSION_')) {
    +    # module validation
    +    exit;
    +}
    +
    +class AdminApPageBuilderModuleController extends ModuleAdminControllerCore
    +{
    +
    +    public function __construct()
    +    {
    +        $url = 'index.php?controller=AdminModules&configure=appagebuilder&token='.Tools::getAdminTokenLite('AdminModules');
    +        Tools::redirectAdmin($url);
    +        parent::__construct();
    +    }
    +}
    diff --git a/modules/appagebuilder/controllers/admin/AdminApPageBuilderPositions.php b/modules/appagebuilder/controllers/admin/AdminApPageBuilderPositions.php
    new file mode 100644
    index 00000000..c2b852b3
    --- /dev/null
    +++ b/modules/appagebuilder/controllers/admin/AdminApPageBuilderPositions.php
    @@ -0,0 +1,480 @@
    +
    + *  @copyright 2007-2015 Apollotheme
    + *  @license   http://apollotheme.com - prestashop template provider
    + */
    +
    +if (!defined('_PS_VERSION_')) {
    +    # module validation
    +    exit;
    +}
    +
    +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageBuilderPositionsModel.php');
    +
    +class AdminApPageBuilderPositionsController extends ModuleAdminControllerCore
    +{
    +    public $position_js_folder = '';
    +    public $position_css_folder = '';
    +    public $module_name = 'appagebuilder';
    +    public $explicit_select;
    +    public $order_by;
    +    public $order_way;
    +    public $theme_dir;
    +
    +    public function __construct()
    +    {
    +        $this->bootstrap = true;
    +        $this->table = 'appagebuilder_positions';
    +        $this->className = 'ApPageBuilderPositionsModel';
    +        $this->lang = false;
    +        $this->explicit_select = true;
    +        $this->allow_export = true;
    +        $this->context = Context::getContext();
    +        $this->order_by = 'position';
    +        $this->order_way = 'DESC';
    +        $this->_join = '
    +            INNER JOIN `'._DB_PREFIX_.'appagebuilder_positions_shop` ps ON (ps.`id_appagebuilder_positions` = a.`id_appagebuilder_positions`)';
    +        parent::__construct();
    +        $this->fields_list = array(
    +            'id_appagebuilder_positions' => array(
    +                'title' => $this->l('ID'),
    +                'align' => 'center',
    +                'width' => 50,
    +                'class' => 'fixed-width-xs'
    +            ),
    +            'position' => array(
    +                'title' => $this->l('Position'),
    +                'width' => 140,
    +                'type' => 'text',
    +                'filter_key' => 'a!position',
    +                'remove_onclick' => true
    +            ),
    +            'name' => array(
    +                'title' => $this->l('Name'),
    +                'width' => 140,
    +                'type' => 'text',
    +                'filter_key' => 'a!name',
    +                'remove_onclick' => true
    +            ),
    +            'position_key' => array(
    +                'title' => $this->l('Key'),
    +                'filter_key' => 'a!position_key',
    +                'type' => 'text',
    +                'width' => 140,
    +                'remove_onclick' => true
    +            )
    +        );
    +        $this->list_no_link = 'no';
    +        $this->bulk_actions = array(
    +            'delete' => array(
    +                'text' => $this->l('Delete selected'),
    +                'confirm' => $this->l('Delete selected items?'),
    +                'icon' => 'icon-trash'
    +            ),
    +            'correctlink' => array(
    +                'text' => $this->l('Correct Image Link'),
    +                'confirm' => $this->l('Are you sure you want to change image url from old theme to new theme?'),
    +                'icon' => 'icon-edit'
    +            ),
    +            'insertLang' => array(
    +                'text' => $this->l('Auto Input Data for New Lang'),
    +                'confirm' => $this->l('Auto insert data for new language?'),
    +                'icon' => 'icon-edit'
    +            )
    +        );
    +        $this->_where = ' AND ps.id_shop='.(int)$this->context->shop->id;
    +
    +        $this->theme_dir           = _PS_THEME_DIR_;
    +        $this->position_css_folder = _PS_THEME_DIR_.apPageHelper::getCssDir().'positions/';
    +        $this->position_js_folder  = _PS_THEME_DIR_.apPageHelper::getJsDir().'positions/';
    +        
    +        if (!is_dir($this->position_css_folder)) {
    +            mkdir($this->position_css_folder, 0755, true);
    +        }
    +        if (!is_dir($this->position_js_folder)) {
    +            mkdir($this->position_js_folder, 0755, true);
    +        }
    +    }
    +
    +    public function processDelete()
    +    {
    +        $object = $this->loadObject();
    +        // Check using other profile
    +        $result = ApPageBuilderPositionsModel::getProfileUsingPosition($object->id);
    +        if (!$result) {
    +            $object = parent::processDelete();
    +            if ($object->position_key) {
    +                Tools::deleteFile($this->position_css_folder.$object->position.$object->position_key.'.css');
    +                Tools::deleteFile($this->position_js_folder.$object->position.$object->position_key.'.js');
    +            }
    +        } else {
    +            $name_profile = '';
    +            $sep = '';
    +            foreach ($result as $item) {
    +                $name_profile .= $sep.$item['name'];
    +                $sep = ', ';
    +            }
    +            $this->errors[] = sprintf($this->l('Can not delete position "%s", it is being used by Profile : "%s"'), $object->name, $name_profile);
    +        }
    +        return $object;
    +    }
    +
    +    public function processBulkDelete()
    +    {
    +        // Remove resouce and update table profiles
    +        $arr = $this->boxes;
    +        if (!$arr) {
    +            return;
    +        }
    +        
    +        foreach ($arr as $id) {
    +            $profiles = ApPageBuilderPositionsModel::getProfileUsingPosition($id);
    +            $object = new ApPageBuilderPositionsModel($id);
    +            if (!$profiles) {
    +                $object->delete();
    +                if ($object->position_key) {
    +                    Tools::deleteFile($this->position_css_folder.$object->position.$object->position_key.'.css');
    +                    Tools::deleteFile($this->position_js_folder.$object->position.$object->position_key.'.js');
    +                }
    +            } else {
    +                $name_profile = '';
    +                $sep = '';
    +                foreach ($profiles as $profile) {
    +                    $name_profile .= $sep.$profile['name'];
    +                    $sep = ', ';
    +                }
    +                $this->errors[] = sprintf($this->l('Can not delete position "%s", it is being used by Profile : "%s"'), $object->name, $name_profile);
    +            }
    +        }
    +        if (empty($this->errors)) {
    +            $this->confirmations[] = $this->_conf[1];
    +        }
    +    }
    +
    +    public function renderView()
    +    {
    +        $object = $this->loadObject();
    +        $this->redirect_after = Context::getContext()->link->getAdminLink('AdminApPageBuilderHome');
    +        $this->redirect_after .= '&id_appagebuilder_positions='.$object->id;
    +        $this->redirect();
    +    }
    +
    +    public function processStatus()
    +    {
    +        if (Validate::isLoadedObject($object = $this->loadObject())) {
    +            if ($object->toggleStatus()) {
    +                $matches = array();
    +                if (preg_match('/[\?|&]controller=([^&]*)/', (string)$_SERVER['HTTP_REFERER'], $matches) !== false && Tools::strtolower($matches[1]) != Tools::strtolower(preg_replace('/controller/i', '', get_class($this)))) {
    +                    $this->redirect_after = preg_replace('/[\?|&]conf=([^&]*)/i', '', (string)$_SERVER['HTTP_REFERER']);
    +                } else {
    +                    $this->redirect_after = self::$currentIndex.'&token='.$this->token;
    +                }
    +
    +                $id_category = (($id_category = (int)Tools::getValue('id_category')) && Tools::getValue('id_product')) ? '&id_category='.$id_category : '';
    +                $this->redirect_after .= '&conf=5'.$id_category;
    +            } else {
    +                $this->errors[] = $this->l('You can not disable default profile, Please select other profile as default');
    +            }
    +        } else {
    +            $this->errors[] = $this->l('An error occurred while updating the status for an object.').' '.$this->table.' '.$this->l('(cannot load object)');
    +        }
    +
    +        return $object;
    +    }
    +
    +    public function postProcess()
    +    {
    +        parent::postProcess();
    +        if (count($this->errors) > 0) {
    +            return;
    +        }
    +        
    +        if (Tools::getIsset('duplicateappagebuilder_positions')) {
    +            $id = Tools::getValue('id_appagebuilder_positions');
    +            $this->duplicatePosition($id, '');
    +        }
    +
    +        # Delete POSITIONS NOT USE
    +        if (Tools::getValue('leo_delete_position') && Tools::getValue('leo_delete_position')) {
    +            apPageHelper::processDeleteOldPosition();
    +            $this->confirmations[] = 'POSITIONS NOT USE have been deleted successfully.';
    +        }
    +    }
    +
    +    public function duplicatePosition($id, $type = '', $name = '')
    +    {
    +        $id = (int)$id;
    +        $object = ApPageBuilderPositionsModel::getPositionById($id);
    +        if ($object) {
    +            $key = ApPageSetting::getRandomNumber();
    +            $old_key = $object['position_key'];
    +            $name = $name ? $name : $this->l('Duplicate ').$key;
    +            $data = array('name' => $name, 'position' => $object['position'], 'position_key' => 'duplicate_'.$key);
    +            $model = new ApPageBuilderPositionsModel();
    +            $duplicate_id = $model->addAuto($data);
    +            AdminApPageBuilderShortcodesController::duplcateDataPosition($id, $duplicate_id);
    +            if ($duplicate_id) {
    +                //duplicate shortCode
    +                ApPageSetting::writeFile($this->position_js_folder, $data['position'].$data['position_key'].'.js', Tools::file_get_contents($this->position_js_folder.$data['position'].$old_key.'.js'));
    +                ApPageSetting::writeFile($this->position_css_folder, $data['position'].$data['position_key'].'.css', Tools::file_get_contents($this->position_css_folder.$data['position'].$old_key.'.css'));
    +                if ($type != 'ajax') {
    +                    $this->redirect_after = self::$currentIndex.'&token='.$this->token;
    +                    $this->redirect();
    +                } else {
    +                    return $duplicate_id;
    +                }
    +            } else {
    +                if ($type != 'ajax') {
    +                    Tools::displayError('Can not duplicate Position');
    +                } else {
    +                    return 0;
    +                }
    +            }
    +        } else if ($type != 'ajax') {
    +            Tools::displayError('Can not duplicate Position');
    +        } else {
    +            return 0;
    +        }
    +    }
    +
    +    public function renderList()
    +    {
    +        $this->initToolbar();
    +
    +        $this->addRowAction('view');
    +        $this->addRowAction('edit');
    +        $this->addRowAction('duplicate');
    +        $this->addRowAction('delete');
    +        return parent::renderList();
    +    }
    +
    +    public function renderForm()
    +    {
    +        $this->initToolbar();
    +        $this->context->controller->addJqueryUI('ui.sortable');
    +        $this->fields_form = array(
    +            'legend' => array(
    +                'title' => $this->l('Ap Position Manage'),
    +                'icon' => 'icon-folder-close'
    +            ),
    +            'input' => array(
    +                array(
    +                    'type' => 'text',
    +                    'label' => $this->l('Name'),
    +                    'name' => 'name',
    +                    'required' => true,
    +                    'hint' => $this->l('Invalid characters:').' <>;=#{}'
    +                ),
    +                array(
    +                    'type' => 'text',
    +                    'label' => $this->l('Position Key'),
    +                    'name' => 'position_key',
    +                    'required' => true,
    +                    'desc' => $this->l('Use it to save as file name of css and js of Position'),
    +                    'hint' => $this->l('Invalid characters:').' <>;=#{}'
    +                ),
    +                array(
    +                    'type' => 'select',
    +                    'label' => $this->l('Type'),
    +                    'name' => 'position',
    +                    'options' => array(
    +                        'query' => array(
    +                            array(
    +                                'id' => 'header',
    +                                'name' => $this->l('Header'),
    +                            ),
    +                            array(
    +                                'id' => 'content',
    +                                'name' => $this->l('Content'),
    +                            ),
    +                            array(
    +                                'id' => 'footer',
    +                                'name' => $this->l('Footer'),
    +                            ),
    +                            array(
    +                                'id' => 'product',
    +                                'name' => $this->l('Product'),
    +                            )
    +                        ),
    +                        'id' => 'id',
    +                        'name' => 'name'
    +                    ),
    +                ),
    +                array(
    +                    'type' => 'textarea',
    +                    'label' => $this->l('Custom Css'),
    +                    'name' => 'css',
    +                    'desc' => sprintf($this->l('Please set write Permission for folder %s'), $this->position_css_folder),
    +                ),
    +                array(
    +                    'type' => 'textarea',
    +                    'label' => $this->l('Custom Js'),
    +                    'name' => 'js',
    +                    'desc' => sprintf($this->l('Please set write Permission for folder %s'), $this->position_js_folder),
    +                )
    +            ),
    +            'submit' => array(
    +                'title' => $this->l('Save'),
    +            ),
    +            'buttons' => array(
    +                'save-and-stay' => array(
    +                    'title' => $this->l('Save and Stay'),
    +                    'name' => 'submitAdd'.$this->table.'AndStay',
    +                    'type' => 'submit',
    +                    'class' => 'btn btn-default pull-right',
    +                    'icon' => 'process-icon-save'
    +                ))
    +        );
    +        return parent::renderForm();
    +    }
    +
    +    public function getFieldsValue($obj)
    +    {
    +        $file_value = parent::getFieldsValue($obj);
    +        if ($obj->id && $obj->position_key) {
    +            $file_value['css'] = Tools::file_get_contents($this->position_css_folder.$obj->position.$obj->position_key.'.css');
    +            $file_value['js'] = Tools::file_get_contents($this->position_js_folder.$obj->position.$obj->position_key.'.js');
    +        } else {
    +            $file_value['position_key'] = 'position'.ApPageSetting::getRandomNumber();
    +        }
    +        return $file_value;
    +    }
    +
    +    public function processAdd()
    +    {
    +        if ($obj = parent::processAdd()) {
    +            $this->saveCustomJsAndCss($obj->position.$obj->position_key, '');
    +        }
    +    }
    +
    +    public function processUpdate()
    +    {
    +        // Check ifchange position => need delete current file css/js before update
    +        $old_object = parent::loadObject();
    +        if ($obj = parent::processUpdate()) {
    +            $this->saveCustomJsAndCss($obj->position.$obj->position_key, $old_object->position.$obj->position_key);
    +        }
    +    }
    +
    +    public function saveCustomJsAndCss($key, $old_key = '')
    +    {
    +        // Delete old file
    +        if ($old_key) {
    +            Tools::deleteFile($this->position_css_folder.$old_key.'.css');
    +            Tools::deleteFile($this->position_js_folder.$old_key.'.js');
    +        }
    +        //DONGND:: validate
    +        // if (!empty(Tools::getValue('js'))) {
    +        if (Tools::getValue('js') != '') {
    +            ApPageSetting::writeFile($this->position_js_folder, $key.'.js', Tools::getValue('js'));
    +        }
    +        //DONGND:: validate
    +        // if (!empty(Tools::getValue('css'))) {
    +        if (Tools::getValue('css') != '') {
    +            ApPageSetting::writeFile($this->position_css_folder, $key.'.css', Tools::getValue('css'));
    +        }
    +    }
    +
    +    /**
    +     * Auto create a position for page build profile editing/creating
    +     * @param type $obj
    +     */
    +    public function autoCreatePosition($obj)
    +    {
    +        $model = new ApPageBuilderPositionsModel();
    +        $id = $model->addAuto($obj);
    +        if ($id) {
    +            $this->saveCustomJsAndCss($obj['position'].$obj['position_key'], '');
    +        }
    +        return $id;
    +    }
    +
    +    public function updateName($id, $name)
    +    {
    +        return ApPageBuilderPositionsModel::updateName($id, $name);
    +    }
    +
    +    public function initToolbar()
    +    {
    +        # Delete POSITIONS NOT USE
    +        switch ($this->display) {
    +            default:
    +                $this->toolbar_btn['eraser'] = array(
    +                    'href' => self::$currentIndex.'&leo_delete_position=1&token='.$this->token,
    +                    'desc' => $this->l('Delete position do not use (fix error when create profile)'),
    +                    'imgclass' => 'eraser',
    +                    'class' => 'leo_delete_position',
    +                );
    +        }
    +        parent::initToolbar();
    +    }
    +    
    +    public function setMedia($isNewTheme = false)
    +    {
    +        parent::setMedia($isNewTheme);
    +        Context::getContext()->controller->addJs(apPageHelper::getJsAdminDir().'admin/form_admin_positions.js');
    +        Media::addJsDefL('leo_confirm_text', $this->l('Are you sure you want to Delete do not use position. Please back-up all thing before?'));
    +        Media::addJsDefL('leo_form_submit', Context::getContext()->link->getAdminLink('AdminApPageBuilderPositions'));
    +    }
    +    
    +    public function displayDuplicateLink($token = null, $id = null, $name = null)
    +    {
    +        $controller = 'AdminApPageBuilderPositions';
    +        $token = Tools::getAdminTokenLite($controller);
    +        $html = '
    +             Duplicate
    +        ';
    +        
    +        // validate module
    +        unset($name);
    +        
    +        return $html;
    +    }
    +    
    +    /**
    +     * PERMISSION ACCOUNT demo@demo.com
    +     * OVERRIDE CORE
    +     */
    +    public function access($action, $disable = false)
    +    {
    +        if (Tools::getIsset('update'.$this->table) && Tools::getIsset($this->identifier)) {
    +            // Allow person see "EDIT" form
    +            $action = 'view';
    +        }
    +        return parent::access($action, $disable);
    +    }
    +    
    +    /**
    +     * PERMISSION ACCOUNT demo@demo.com
    +     * OVERRIDE CORE
    +     */
    +    public function initProcess()
    +    {
    +        parent::initProcess();
    +        
    +        if (count($this->errors) <= 0) {
    +            if( Tools::isSubmit('duplicate'.$this->table) ) {
    +                if ($this->id_object) {
    +                    if (!$this->access('add'))
    +                    {
    +                        $this->errors[] = $this->trans('You do not have permission to duplicate this.', array(), 'Admin.Notifications.Error');
    +                    }
    +                }
    +            }elseif(Tools::getIsset('leo_delete_position') && Tools::getValue('leo_delete_position')){
    +                if (!$this->access('delete'))
    +                {
    +                    $this->errors[] = $this->trans('You do not have permission to delelte this.', array(), 'Admin.Notifications.Error');
    +                }
    +            }
    +        }
    +    }
    +}
    diff --git a/modules/appagebuilder/controllers/admin/AdminApPageBuilderProductModule.php b/modules/appagebuilder/controllers/admin/AdminApPageBuilderProductModule.php
    new file mode 100644
    index 00000000..baaac2a2
    --- /dev/null
    +++ b/modules/appagebuilder/controllers/admin/AdminApPageBuilderProductModule.php
    @@ -0,0 +1,26 @@
    +
    + *  @copyright 2007-2015 Apollotheme
    + *  @license   http://apollotheme.com - prestashop template provider
    + */
    +
    +if (!defined('_PS_VERSION_')) {
    +    # module validation
    +    exit;
    +}
    +
    +class AdminAdminApthemeConfigLiveController extends ModuleAdminControllerCore
    +{
    +    public function __construct()
    +    {
    +    }
    +}
    diff --git a/modules/appagebuilder/controllers/admin/AdminApPageBuilderProducts.php b/modules/appagebuilder/controllers/admin/AdminApPageBuilderProducts.php
    new file mode 100644
    index 00000000..ccaa1db6
    --- /dev/null
    +++ b/modules/appagebuilder/controllers/admin/AdminApPageBuilderProducts.php
    @@ -0,0 +1,492 @@
    +
    + *  @copyright 2007-2015 Apollotheme
    + *  @license   http://apollotheme.com - prestashop template provider
    + */
    +
    +if (!defined('_PS_VERSION_')) {
    +    # module validation
    +    exit;
    +}
    +
    +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageBuilderProductsModel.php');
    +
    +class AdminApPageBuilderProductsController extends ModuleAdminControllerCore
    +{
    +    private $theme_name = '';
    +    public $module_name = 'appagebuilder';
    +    public $tpl_save = '';
    +    public $file_content = array();
    +    public $explicit_select;
    +    public $order_by;
    +    public $order_way;
    +    public $profile_css_folder;
    +    public $module_path;
    +//    public $module_path_resource;
    +    public $str_search = array();
    +    public $str_relace = array();
    +    public $theme_dir;
    +
    +    public function __construct()
    +    {
    +        $this->bootstrap = true;
    +        $this->table = 'appagebuilder_products';
    +        $this->className = 'ApPageBuilderProductsModel';
    +        $this->lang = false;
    +        $this->explicit_select = true;
    +        $this->allow_export = true;
    +        $this->context = Context::getContext();
    +        $this->_join = '
    +            INNER JOIN `'._DB_PREFIX_.'appagebuilder_products_shop` ps ON (ps.`id_appagebuilder_products` = a.`id_appagebuilder_products`)';
    +        $this->_select .= ' ps.active as active, ';
    +
    +        $this->order_by = 'id_appagebuilder_products';
    +        $this->order_way = 'DESC';
    +        parent::__construct();
    +        $this->fields_list = array(
    +            'id_appagebuilder_products' => array(
    +                'title' => $this->l('ID'),
    +                'align' => 'center',
    +                'width' => 50,
    +                'class' => 'fixed-width-xs'
    +            ),
    +            'name' => array(
    +                'title' => $this->l('Name'),
    +                'width' => 140,
    +                'type' => 'text',
    +                'filter_key' => 'a!name'
    +            ),
    +            'plist_key' => array(
    +                'title' => $this->l('Product List Key'),
    +                'filter_key' => 'a!plist_key',
    +                'type' => 'text',
    +                'width' => 140,
    +            ),
    +            'class' => array(
    +                'title' => $this->l('Class'),
    +                'width' => 140,
    +                'type' => 'text',
    +                'filter_key' => 'a!class',
    +                'orderby' => false
    +            ),
    +            'active' => array(
    +                'title' => $this->l('Is Default'),
    +                'active' => 'status',
    +                'filter_key' => 'ps!active',
    +                'align' => 'text-center',
    +                'type' => 'bool',
    +                'class' => 'fixed-width-sm',
    +                'orderby' => false
    +            ),
    +        );
    +        $this->bulk_actions = array(
    +            'delete' => array(
    +                'text' => $this->l('Delete selected'),
    +                'confirm' => $this->l('Delete selected items?'),
    +                'icon' => 'icon-trash'
    +            )
    +        );
    +        $this->theme_dir = _PS_THEME_DIR_;
    +
    +        $this->_where = ' AND ps.id_shop='.(int)$this->context->shop->id;
    +        $this->theme_name = _THEME_NAME_;
    +        $this->profile_css_folder = $this->theme_dir.'modules/'.$this->module_name.'/';
    +        $this->module_path = __PS_BASE_URI__.'modules/'.$this->module_name.'/';
    +//        $this->module_path_resource = $this->module_path.'views/';
    +        $this->str_search = array('_APAMP_', '_APQUOT_', '_APAPOST_', '_APTAB_', '_APNEWLINE_', '_APENTER_', '_APOBRACKET_', '_APCBRACKET_', '_APOCBRACKET_', '_APCCBRACKET_');
    +        $this->str_relace = array('&', '\"', '\'', '\t', '\r', '\n', '[', ']', '{', '}');
    +    }
    +
    +    public function renderView()
    +    {
    +        $object = $this->loadObject();
    +        if ($object->page == 'product_detail') {
    +            $this->redirect_after = Context::getContext()->link->getAdminLink('AdminApPageBuilderProductDetail');
    +        } else {
    +            $this->redirect_after = Context::getContext()->link->getAdminLink('AdminApPageBuilderHome');
    +        }
    +        $this->redirect_after .= '&id_appagebuilder_products='.$object->id;
    +        $this->redirect();
    +    }
    +
    +    public function postProcess()
    +    {
    +        parent::postProcess();
    +        
    +        if (count($this->errors) > 0) {
    +            return;
    +        }
    +        
    +        if (Tools::getIsset('duplicateappagebuilder_products')) {
    +            $id = Tools::getValue('id_appagebuilder_products');
    +            $model = new ApPageBuilderProductsModel($id);
    +            $duplicate_object = $model->duplicateObject();
    +            if(isset($model->params)){
    +                # FIX : insert code can not duplicate
    +                $duplicate_object->params = $model->params;
    +            }
    +            $duplicate_object->name = $this->l('Duplicate of').' '.$duplicate_object->name;
    +            $old_key = $duplicate_object->plist_key;
    +            $duplicate_object->plist_key = 'plist'.ApPageSetting::getRandomNumber();
    +            if ($duplicate_object->add()) {
    +                //duplicate shortCode
    +                $filecontent = Tools::file_get_contents(apPageHelper::getConfigDir('theme_profiles').$old_key.'.tpl');
    +                ApPageSetting::writeFile(apPageHelper::getConfigDir('theme_profiles'), $duplicate_object->plist_key.'.tpl', $filecontent);
    +                $this->redirect_after = self::$currentIndex.'&token='.$this->token;
    +                $this->redirect();
    +            } else {
    +                Tools::displayError('Can not duplicate Profiles');
    +            }
    +        }
    +        
    +        
    +        if (Tools::isSubmit('saveELement')) {
    +            $filecontent = Tools::getValue('filecontent');
    +            $fileName = Tools::getValue('fileName');
    +            if (!is_dir($this->theme_dir.'modules/appagebuilder/views/templates/front/products/')) {
    +                if (!is_dir($this->theme_dir.'modules/appagebuilder/views/templates/front/products/')) {
    +                    mkdir($this->theme_dir.'modules/appagebuilder/views/templates/front/products/', 0755, true);
    +                }
    +            }
    +            ApPageSetting::writeFile($this->theme_dir.'modules/appagebuilder/views/templates/front/products/', $fileName.'.tpl', $filecontent);
    +        }
    +    }
    +
    +    public function convertObjectToTpl($object_form)
    +    {
    +        $tpl = '';
    +        foreach ($object_form as $object) {
    +            if ($object['name'] == 'functional_buttons') {
    +                $tpl .= ApPageSetting::getProductFunctionalButtons();
    +                $tpl .= $this->convertObjectToTpl($object['element']);
    +                $tpl .= '
    '; + } else if ($object['name'] == 'code') { + $tpl .= $object['code']; + } else { + if (!isset($this->file_content[$object['name']])) { + $this->returnFileContent($object['name']); + } + $tpl .= $this->file_content[$object['name']]; + } + } + return $tpl; + } + + public function returnFileContent($pelement) + { + $tpl_dir = $this->theme_dir.'modules/appagebuilder/views/templates/front/products/'.$pelement.'.tpl'; + if (!file_exists($tpl_dir)) { + $tpl_dir = _PS_MODULE_DIR_.'appagebuilder/views/templates/front/products/'.$pelement.'.tpl'; + } + $this->file_content[$pelement] = Tools::file_get_contents($tpl_dir); + return $this->file_content[$pelement]; + } + + public function renderList() + { + if (Tools::getIsset('pelement')) { + $helper = new HelperForm(); + $helper->submit_action = 'saveELement'; + $inputs = array( + array( + 'type' => 'textarea', + 'name' => 'filecontent', + 'label' => $this->l('File Content'), + 'desc' => $this->l('Please carefully when edit tpl file'), + ), + array( + 'type' => 'hidden', + 'name' => 'fileName', + ) + ); + $fields_form = array( + 'form' => array( + 'legend' => array( + 'title' => sprintf($this->l('You are Editing file: %s'), Tools::getValue('pelement').'.tpl'), + 'icon' => 'icon-cogs' + ), + 'action' => Context::getContext()->link->getAdminLink('AdminApPageBuilderShortcodes'), + 'input' => $inputs, + 'name' => 'importData', + 'submit' => array( + 'title' => $this->l('Save'), + 'class' => 'button btn btn-default pull-right' + ), + 'tinymce' => false, + ), + ); + $helper->tpl_vars = array( + 'fields_value' => $this->getFileContent() + ); + return $helper->generateForm(array($fields_form)); + } + $this->initToolbar(); + $this->addRowAction('edit'); + $this->addRowAction('duplicate'); + $this->addRowAction('delete'); + return parent::renderList(); + } + + public function getFileContent() + { + $pelement = Tools::getValue('pelement'); + $tpl_dir = $this->theme_dir.'modules/appagebuilder/views/templates/front/products/'.$pelement.'.tpl'; + if (!file_exists($tpl_dir)) { + $tpl_dir = _PS_MODULE_DIR_.'appagebuilder/views/templates/front/products/'.$pelement.'.tpl'; + } + return array('fileName' => $pelement, 'filecontent' => Tools::file_get_contents($tpl_dir)); + } + + public function setHelperDisplay(Helper $helper) + { + parent::setHelperDisplay($helper); + $this->helper->module = APPageBuilder::getInstance(); + } + + public function processDelete() + { + $object = $this->loadObject(); + Tools::deleteFile(apPageHelper::getConfigDir('theme_profiles').$object->plist_key.'.tpl'); + parent::processDelete(); + } + + public function renderForm() + { + $this->initToolbar(); + $this->context->controller->addJqueryUI('ui.sortable'); + $this->context->controller->addJqueryUI('ui.draggable'); + $this->context->controller->addJs(apPageHelper::getJsAdminDir().'admin/form.js'); + $this->context->controller->addJs(apPageHelper::getJsAdminDir().'admin/product-list.js'); + $this->context->controller->addCss(apPageHelper::getCssAdminDir().'admin/form.css'); + $source_file = Tools::scandir(_PS_MODULE_DIR_.'appagebuilder/views/templates/front/products/', 'tpl'); + if (is_dir($this->theme_dir.'modules/appagebuilder/views/templates/front/products/')) { + $source_template_file = Tools::scandir($this->theme_dir.'modules/appagebuilder/views/templates/front/products/', 'tpl'); + $source_file = array_merge($source_file, $source_template_file); + } + $elements = array(); + $icon_list = ApPageSetting::getProductElementIcon(); + foreach ($source_file as $value) { + $fileName = basename($value, '.tpl'); + if ($fileName == 'index') { + continue; + } + $elements[$fileName] = array( + 'name' => str_replace('_', ' ', $fileName), + 'icon' => (isset($icon_list[$fileName]) ? $icon_list[$fileName] : 'icon-sun')); + } + $params = array('gridLeft' => array(), 'gridRight' => array()); + + $this->object->params = str_replace($this->str_search, $this->str_relace, $this->object->params); + + if (isset($this->object->params)) { + $params = Tools::jsonDecode($this->object->params, true); + } + + //$params['gridLeft'] = $this->replaceSpecialStringToHtml($params['gridLeft']); + //$params['gridRight'] = $this->replaceSpecialStringToHtml($params['gridRight']); + + $block_list = array( + 'gridLeft' => array('title' => 'Product-Image', 'class' => 'left-block'), + 'gridRight' => array('title' => 'Product-Meta', 'class' => 'right-block'), + ); + $this->fields_form = array( + 'legend' => array( + 'title' => $this->l('Ap Profile Manage'), + 'icon' => 'icon-folder-close' + ), + 'input' => array( + array( + 'type' => 'text', + 'label' => $this->l('Name'), + 'name' => 'name', + 'required' => true, + 'hint' => $this->l('Invalid characters:').' <>;=#{}' + ), + array( + 'type' => 'text', + 'label' => $this->l('Product List Key'), + 'name' => 'plist_key', + 'readonly' => 'readonly', + 'desc' => $this->l('Tpl File name'), + ), + array( + 'label' => $this->l('Class'), + 'type' => 'text', + 'name' => 'class', + 'width' => 140 + ), + array( + 'type' => 'ap_proGrid', + 'name' => 'ap_proGrid', + 'label' => $this->l('Layout'), + 'elements' => $elements, + 'params' => $params, + 'blockList' => $block_list + ), + array( + 'type' => 'hidden', + 'name' => 'params' + ), + array( + 'type' => 'hidden', + 'name' => 'submitAddappagebuilder_productsAndStay', + ) + ), + 'buttons' => array( + 'save-and-stay' => array( + 'title' => $this->l('Save and Stay'), + 'id' => 'saveAndStay', + 'type' => 'button', + 'class' => 'btn btn-default pull-right ', + 'icon' => 'process-icon-save') + ) + ); + return parent::renderForm(); + } + + public function replaceSpecialStringToHtml($arr) + { + foreach ($arr as &$v) { + if ($v['name'] == 'code') { + // validate module + $v['code'] = str_replace($this->str_search, $this->str_relace, $v['code']); + } else { + if ($v['name'] == 'functional_buttons') { + foreach ($v as &$f) { + if ($f['name'] == 'code') { + // validate module + $f['code'] = str_replace($this->str_search, $this->str_relace, $f['code']); + } + } + } + } + } + return $arr; + } + + public function getFieldsValue($obj) + { + $file_value = parent::getFieldsValue($obj); + if (!$obj->id) { + $num = ApPageSetting::getRandomNumber(); + $file_value['plist_key'] = 'plist'.$num; + $file_value['name'] = $file_value['plist_key']; + $file_value['class'] = 'product-list-'.$num; + } + return $file_value; + } + + public function processAdd() + { + if ($obj = parent::processAdd()) { + $this->saveTplFile($obj->plist_key, $obj->params); + } + } + + public function processUpdate() + { + if ($obj = parent::processUpdate()) { + $this->saveTplFile($obj->plist_key, $obj->params); + } + } + + public function saveTplFile($plist_key, $params) + { + // validate module + unset($params); + //if (Tools::get) + $data_form = str_replace($this->str_search, $this->str_relace, Tools::getValue('params', '')); + $data_form = Tools::jsonDecode($data_form, true); + + $grid_left = $data_form['gridLeft']; + $grid_right = $data_form['gridRight']; + $tpl_grid = ApPageSetting::getProductContainer(); + $tpl_grid .= ApPageSetting::getProductLeftBlock().$this->convertObjectToTpl($grid_left)."
  • \n"; + $tpl_grid .= ApPageSetting::getProductRightBlock().$this->convertObjectToTpl($grid_right)."
    \n"; + $tpl_grid .= ApPageSetting::getProductContainerEnd(); + $folder = apPageHelper::getConfigDir('theme_profiles'); + if (!is_dir($folder)) { + mkdir($folder, 0755, true); + } + $file = $plist_key.'.tpl'; + $tpl_grid = preg_replace('/\{\*[\s\S]*?\*\}/', '', $tpl_grid); + $tpl_grid = str_replace(" mod='appagebuilder'", '', $tpl_grid); + + //die($tpl_grid."--"); + ApPageSetting::writeFile($folder, $file, $tpl_grid); + } + + public function processStatus() + { + if (Validate::isLoadedObject($object = $this->loadObject())) { + if ($object->toggleStatus()) { + $matches = array(); + if (preg_match('/[\?|&]controller=([^&]*)/', (string)$_SERVER['HTTP_REFERER'], $matches) !== false && Tools::strtolower($matches[1]) != Tools::strtolower(preg_replace('/controller/i', '', get_class($this)))) { + $this->redirect_after = preg_replace('/[\?|&]conf=([^&]*)/i', '', (string)$_SERVER['HTTP_REFERER']); + } else { + $this->redirect_after = self::$currentIndex.'&token='.$this->token; + } + } + } else { + $this->errors[] = Tools::displayError('An error occurred while updating the status for an object.') + .''.$this->table.' '.Tools::displayError('(cannot load object)'); + } + return $object; + } + + public function displayDuplicateLink($token = null, $id = null, $name = null) + { + $controller = 'AdminApPageBuilderProducts'; + $token = Tools::getAdminTokenLite($controller); + $html = ' + Duplicate + '; + + // validate module + unset($name); + + return $html; + } + + /** + * PERMISSION ACCOUNT demo@demo.com + * OVERRIDE CORE + */ + public function access($action, $disable = false) + { + if (Tools::getIsset('update'.$this->table) && Tools::getIsset($this->identifier)) { + // Allow person see "EDIT" form + $action = 'view'; + } + return parent::access($action, $disable); + } + + /** + * PERMISSION ACCOUNT demo@demo.com + * OVERRIDE CORE + */ + public function initProcess() + { + parent::initProcess(); + + if (count($this->errors) <= 0) { + if( Tools::isSubmit('duplicate'.$this->table) ) { + if ($this->id_object) { + if (!$this->access('add')) + { + $this->errors[] = $this->trans('You do not have permission to duplicate this.', array(), 'Admin.Notifications.Error'); + } + } + } + } + } +} diff --git a/modules/appagebuilder/controllers/admin/AdminApPageBuilderProfiles.php b/modules/appagebuilder/controllers/admin/AdminApPageBuilderProfiles.php new file mode 100644 index 00000000..efdfdb70 --- /dev/null +++ b/modules/appagebuilder/controllers/admin/AdminApPageBuilderProfiles.php @@ -0,0 +1,798 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageBuilderProfilesModel.php'); + +class AdminApPageBuilderProfilesController extends ModuleAdminControllerCore +{ + private $theme_name = ''; + public $profile_js_folder = ''; + public $profile_css_folder = ''; + public $module_name = 'appagebuilder'; + public $explicit_select; + public $order_by; + public $order_way; + public $theme_dir; + + public function __construct() + { + $this->bootstrap = true; + $this->table = 'appagebuilder_profiles'; + $this->className = 'ApPageBuilderProfilesModel'; + $this->lang = false; + $this->explicit_select = true; + $this->allow_export = true; + + parent::__construct(); + $this->theme_dir = _PS_ALL_THEMES_DIR_._THEME_NAME_.'/'; + + $this->context = Context::getContext(); + + $this->order_by = 'page'; + $this->order_way = 'DESC'; + $alias = 'sa'; + + $id_shop = (int)$this->context->shop->id; + $this->_join .= ' JOIN `'._DB_PREFIX_.'appagebuilder_profiles_shop` + sa ON (a.`id_appagebuilder_profiles` = sa.`id_appagebuilder_profiles` AND sa.id_shop = '.$id_shop.')'; + $this->_select .= ' sa.active as active, '; + + $this->fields_list = array( + 'id_appagebuilder_profiles' => array( + 'title' => $this->l('ID'), + 'align' => 'center', + 'width' => 50, + 'class' => 'fixed-width-xs' + ), + 'name' => array( + 'title' => $this->l('Name'), + 'width' => 140, + 'type' => 'text', + 'filter_key' => 'a!name' + ), + 'profile_key' => array( + 'title' => $this->l('Key'), + 'filter_key' => 'a!profile_key', + 'type' => 'text', + 'width' => 140, + ), + 'active' => array( + 'title' => $this->l('Is Default'), + 'active' => 'status', + 'filter_key' => $alias.'!active', + 'align' => 'text-center', + 'type' => 'bool', + 'class' => 'fixed-width-sm', + 'orderby' => false + ), + ); + $this->bulk_actions = array( + 'delete' => array( + 'text' => $this->l('Delete selected'), + 'confirm' => $this->l('Delete selected items?'), + 'icon' => 'icon-trash' + ), + 'insertLang' => array( + 'text' => $this->l('Auto Input Data for New Lang'), + 'confirm' => $this->l('Auto insert data for new language?'), + 'icon' => 'icon-edit' + ) + ); + + $this->_where = ' AND sa.id_shop='.(int)$this->context->shop->id; + $this->theme_name = _THEME_NAME_; + + $this->profile_css_folder = _PS_THEME_DIR_.apPageHelper::getCssDir().'profiles/'; + $this->profile_js_folder = _PS_THEME_DIR_.apPageHelper::getJsDir().'profiles/'; + + if (!is_dir($this->profile_css_folder)) { + mkdir($this->profile_css_folder, 0755, true); + } + if (!is_dir($this->profile_js_folder)) { + mkdir($this->profile_js_folder, 0755, true); + } + } + + public function initPageHeaderToolbar() + { + $this->context->controller->addJs(apPageHelper::getJsAdminDir().'admin/form.js'); + + $this->page_header_toolbar_btn['SaveAndStay'] = array( + 'href' => 'javascript:void(0);', + 'desc' => $this->l('Save and stay'), + 'js' => 'SaveAndStayAdminApPageBuilderProfiles()', + 'icon' => 'process-icon-save', + ); + $this->page_header_toolbar_btn['Save'] = array( + 'href' => 'javascript:void(0);', + 'desc' => $this->l('Save'), + 'js' => 'SaveAdminApPageBuilderProfiles()', + 'icon' => 'process-icon-save', + ); + parent::initPageHeaderToolbar(); + } + + public function setMedia($isNewTheme = false) + { + parent::setMedia($isNewTheme); + $this->addJqueryPlugin('tagify'); + } + + public function processDelete() + { + $object = $this->loadObject(); + + if ($object && !$object->active) { + $object = parent::processDelete(); + if ($object->profile_key) { + Tools::deleteFile($this->profile_css_folder.$object->profile_key.'.css'); + Tools::deleteFile($this->profile_js_folder.$object->profile_key.'.js'); + } + } else { + $this->errors[] = Tools::displayError('Can not delete Default Profile.'); + } + return $object; + } + + public function processBulkDelete() + { + $arr = $this->boxes; + if (!$arr) { + return; + } + foreach ($arr as $id) { + $object = new $this->className($id); + if ($object && !$object->active) { + $object->delete(); + if ($object->profile_key) { + Tools::deleteFile($this->profile_css_folder.$object->profile_key.'.css'); + Tools::deleteFile($this->profile_js_folder.$object->profile_key.'.js'); + } + } else { + $this->errors[] = Tools::displayError('Can not delete Default Profile.'); + } + } + if (empty($this->errors)) { + $this->confirmations[] = $this->_conf[1]; + } + } + + public function renderView() + { + //echo 'here';die; + $object = $this->loadObject(); + if ($object->page == 'product_detail') { + $this->redirect_after = Context::getContext()->link->getAdminLink('AdminApPageBuilderProductDetail'); + } else { + $this->redirect_after = Context::getContext()->link->getAdminLink('AdminApPageBuilderHome'); + } + $this->redirect_after .= '&id_appagebuilder_profiles='.$object->id; + $this->redirect(); + } + + public function displayViewLink($token = null, $id, $name = null) + { + // validate module + unset($name); + $token = Context::getContext()->link->getAdminLink('AdminApPageBuilderHome'); + $href = $token . '&id_appagebuilder_profiles='.$id; + $html = ' View'; + return $html; + } + + public function processBulkinsertLang() + { + // Remove resouce and update table profiles + $arr = $this->boxes; + if (!$arr) { + // validate module + $arr[] = Tools::getValue('id'); + } + + if (!$arr) { + return; + } + foreach ($arr as $item) { + if ($item) { + //has profile id + $pfile = new ApPageBuilderProfilesModel($item); + $id_positions = array($pfile->header, $pfile->content, $pfile->footer, $pfile->product); + $list_position = $pfile->getPositionsForProfile($id_positions); + $list_pos_id = array(); + foreach ($list_position as $v) { + // validate module + $list_pos_id[] = $v['id_appagebuilder_positions']; + } + $s_model = new ApPageBuilderModel(); + $list_short_c = $s_model->getAllItemsByPositionId($list_pos_id); + $context = Context::getContext(); + $id_lang = (int)$context->language->id; + foreach ($list_short_c as $shor_code) { + $s_model = new ApPageBuilderModel($shor_code['id']); + if ($s_model->params) { + foreach ($s_model->params as $key => $value) { + if ($key != $id_lang) { + // validate module + $s_model->params[$key] = $s_model->params[$id_lang]; + } + // validate module + unset($value); + } + } + $s_model->save(); + } + } + } + } + + public function processStatus() + { + if (Validate::isLoadedObject($object = $this->loadObject())) { + if ($object->toggleStatus()) { + $matches = array(); + if (preg_match('/[\?|&]controller=([^&]*)/', (string)$_SERVER['HTTP_REFERER'], $matches) !== false && Tools::strtolower($matches[1]) != Tools::strtolower(preg_replace('/controller/i', '', get_class($this)))) { + $this->redirect_after = preg_replace('/[\?|&]conf=([^&]*)/i', '', (string)$_SERVER['HTTP_REFERER']); + } else { + $this->redirect_after = self::$currentIndex.'&token='.$this->token; + } + } else { + $this->errors[] = Tools::displayError('You can not disable default profile, Please select other profile as default'); + } + } else { + $this->errors[] = Tools::displayError('An error occurred while updating the status for an object.') + .''.$this->table.' '.Tools::displayError('(cannot load object)'); + } + return $object; + } + + public function postProcess() + { + parent::postProcess(); + if (count($this->errors) > 0) { + return; + } + if (Tools::getIsset('duplicateappagebuilder_profiles')) { +// $context = Context::getContext(); +// $id_shop = $context->shop->id; + $id = Tools::getValue('id_appagebuilder_profiles'); + $model = new ApPageBuilderProfilesModel($id); + + if($model){ + $old_key = $model->profile_key; + $model->profile_key = $profile_key = 'profile'.ApPageSetting::getRandomNumber(); + $model->id = null; + $model->name = $this->l('Duplicate of ') . $model->name; + $model->active = ''; + $model->friendly_url = array(); + $duplicate_object = $model->save(); + + if($duplicate_object){ + //duplicate shortCode + $id_new = $model->id; + ApPageSetting::writeFile($this->profile_js_folder, $profile_key.'.js', Tools::file_get_contents($this->profile_js_folder.$old_key.'.js')); + ApPageSetting::writeFile($this->profile_css_folder, $profile_key.'.css', Tools::file_get_contents($this->profile_css_folder.$old_key.'.css')); + AdminApPageBuilderShortcodesController::duplicateData($id, $id_new); + $this->redirect_after = self::$currentIndex.'&token='.$this->token; + $this->redirect(); + }else{ + Tools::displayError('Can not create new profile'); + } + } else { + Tools::displayError('Profile is not exist to duplicate'); + } + } + } + + public function renderList() + { + $this->initToolbar(); + $this->addRowAction('view'); + $this->addRowAction('edit'); + $this->addRowAction('duplicate'); + $this->addRowAction('delete'); + $this->context->controller->addCss(apPageHelper::getCssAdminDir().'admin/form.css'); + $tpl_name = 'list.tpl'; + $path = ''; + if (file_exists($this->theme_dir.'modules/'.$this->module->name.'/views/templates/admin/'.$tpl_name)) { + $path = $this->theme_dir.'modules/'.$this->module->name.'/views/templates/admin/'.$tpl_name; + } elseif (file_exists($this->getTemplatePath().$this->override_folder.$tpl_name)) { + $path = $this->getTemplatePath().$this->override_folder.$tpl_name; + } + $model = new ApPageBuilderProfilesModel(); + $list_profiles = $model->getAllProfileByShop(); + // Build url for back from live edit page, it is stored in cookie and read in fontContent function below + $controller = 'AdminApPageBuilderHome'; + $id_lang = Context::getContext()->language->id; + $url_edit_profile_token = Tools::getAdminTokenLite($controller); + $params = array('token' => $url_edit_profile_token); + $url_edit_profile = dirname($_SERVER['PHP_SELF']).'/'.Dispatcher::getInstance()->createUrl($controller, $id_lang, $params, false); + $live_edit_params = array( + 'ap_live_edit' => true, + 'ad' => basename(_PS_ADMIN_DIR_), + 'liveToken' => Tools::getAdminTokenLite('AdminModulesPositions'), + 'id_employee' => (int)Context::getContext()->employee->id, + 'id_shop' => (int)Context::getContext()->shop->id + ); + $url_live_edit = $this->getLiveEditUrl($live_edit_params); + $lang = ''; + if (Configuration::get('PS_REWRITING_SETTINGS') && count(Language::getLanguages(true)) > 1) { + $lang = Language::getIsoById($this->context->employee->id_lang).'/'; + } + $url_preview = $this->context->shop->getBaseUrl().(Configuration::get('PS_REWRITING_SETTINGS') ? '' : 'index.php').$lang; + $cookie = new Cookie('url_live_back'); + $cookie->setExpire(time() + 60 * 60); + $cookie->variable_name = $url_edit_profile; + $cookie->write(); + // Save token for check valid + $cookie = new Cookie('ap_token'); //make your own cookie + $cookie->setExpire(time() + 60 * 60); + $cookie->variable_name = $live_edit_params['liveToken']; + $cookie->write(); + $profile_link = $this->context->link->getAdminLink('AdminApPageBuilderProfiles').'&addappagebuilder_profiles'; + $this->context->smarty->assign(array( + 'profile_link' => $profile_link, + 'url_preview' => $url_preview, + 'list_profile' => $list_profiles, + 'url_live_edit' => $url_live_edit, + 'url_profile_detail' => $this->context->link->getAdminLink('AdminApPageBuilderProfiles'), + 'url_edit_profile_token' => $url_edit_profile_token, + 'url_edit_profile' => $url_edit_profile)); + $content = $this->context->smarty->fetch($path); + $path_guide = $this->getTemplatePath().'guide.tpl'; + $guide_box = ApPageSetting::buildGuide($this->context, $path_guide, 0); + return $guide_box.parent::renderList().$content; + //return parent::renderList(); + } + + public function getLiveEditUrl($live_edit_params) + { + $lang = ''; + $admin_dir = dirname($_SERVER['PHP_SELF']); + $admin_dir = Tools::substr($admin_dir, strrpos($admin_dir, '/') + 1); + $dir = str_replace($admin_dir, '', dirname($_SERVER['SCRIPT_NAME'])); + if (Configuration::get('PS_REWRITING_SETTINGS') && count(Language::getLanguages(true)) > 1) { + $lang = Language::getIsoById(Context::getContext()->employee->id_lang).'/'; + } + $url = Tools::getCurrentUrlProtocolPrefix().Tools::getHttpHost().$dir.$lang. + Dispatcher::getInstance()->createUrl('index', (int)Context::getContext()->language->id, $live_edit_params); + return $url; + } + + public function renderForm() + { + $this->initToolbar(); + $this->context->controller->addJqueryUI('ui.sortable'); + $groups = Group::getGroups($this->default_form_language, true); + // UNSET GROUP_BOX + if ($this->object->id == '') { + $model = new ApPageBuilderProfilesModel(); + $list_profiles = $model->getAllProfileByShop(); + foreach ($list_profiles as $profile) { + $group_boxs = $profile['group_box']; + $aray_group_box = explode(',', $group_boxs); + foreach ($aray_group_box as $group_box) { + if ($group_box!=1&&$group_box!=2&&$group_box!=3) { + while ($group = current($groups)) { + if ($group['id_group'] == $group_box) { + unset($groups[key($groups)]); + } + next($groups); + } + } + } + } + } + $this->fields_form = array( + 'legend' => array( + 'title' => $this->l('Ap Profile Manage'), + 'icon' => 'icon-folder-close' + ), + 'input' => array( + array( + 'type' => 'text', + 'label' => $this->l('Name'), + 'name' => 'name', + 'required' => true, + 'hint' => $this->l('Invalid characters:'),' <>;=#{}' + ), + array( + 'type' => 'text', + 'label' => $this->l('Friendly URL'), + 'name' => 'friendly_url', + 'lang' => true, + 'hint' => $this->l('Invalid characters:').' <>;=#{}' + ), + array( + 'type' => 'text', + 'label' => $this->l('Meta title'), + 'name' => 'meta_title', + 'id' => 'name', // for copyMeta2friendlyURL compatibility + 'lang' => true, + // 'required' => true, + 'class' => 'copyMeta2friendlyURL', + 'hint' => $this->l('Invalid characters:').' <>;=#{}' + ), + array( + 'type' => 'textarea', + 'label' => $this->l('Meta description'), + 'name' => 'meta_description', + 'lang' => true, + 'cols' => 40, + 'rows' => 10, + 'hint' => $this->l('Invalid characters:').' <>;=#{}' + ), + array( + 'type' => 'tags', + 'label' => $this->l('Meta keywords'), + 'name' => 'meta_keywords', + 'lang' => true, + 'hint' => array( + $this->l('Invalid characters:').' <>;=#{}', + $this->l('To add "tags" click in the field, write something, and then press "Enter."') + ) + ), + array( + 'type' => 'text', + 'label' => $this->l('Profile Key'), + 'name' => 'profile_key', + 'readonly' => 'readonly', + 'desc' => $this->l('Use it to save as file name of css and js of profile'), + 'hint' => $this->l('Invalid characters:').' <>;=#{}' + ), + array( + 'type' => 'group', + 'label' => $this->l('Apply default profile for these groups'), + 'name' => 'groupBox', + 'values' => $groups, + 'col' => '6', + 'hint' => $this->l('Select the groups that you would like to apply this profile is default.') + ), + array( + 'type' => 'html', + 'name' => 'dump_name', + 'html_content' => '
    '.$this->l('Fullwidth Function: is only for develop') + .'
    '.$this->l('To use this function, you have to download') + .'
    ' + .'header.tpl' + .'
    ' + .'footer.tpl
    ' + .$this->l('file and compare or override in themes folder').'
    ' + ), + array( + 'type' => 'checkbox', + 'name' => 'fullwidth_index_hook', + 'label' => $this->l('Fullwidth Homepage'), + 'class' => 'checkbox-group', + 'desc' => $this->l('The setting full-width for above HOOKS, apply for Home page'), + 'values' => array( + 'query' => self::getCheckboxIndexHook(), + 'id' => 'id', + 'name' => 'name' + ) + ), + array( + 'type' => 'checkbox', + 'name' => 'fullwidth_other_hook', + 'label' => $this->l('Fullwidth other Pages'), + 'class' => 'checkbox-group', + 'desc' => $this->l('The setting full-width for above HOOKS, apply for all OTHER pages ( not Home page )'), + 'values' => array( + 'query' => self::getCheckboxOtherHook(), + 'id' => 'id', + 'name' => 'name' + ) + ), + array( + 'type' => 'checkbox', + 'name' => 'disable_cache_hook', + 'label' => $this->l('Disable cache Hooks'), + 'class' => 'checkbox-group', + 'desc' => $this->l('Some modules always update data, disable cache for those modules show correct info.'), + 'values' => array( + 'query' => self::getCheckboxCacheHook(), + 'id' => 'id', + 'name' => 'name' + ) + ), + array( + 'type' => 'select', + //'label' => $this->l('Profile For Page'), + 'name' => 'page', + 'class' => 'hide', + 'options' => array( + 'query' => array( + array( + 'id' => 'index', + 'name' => $this->l('Index'), + ), + array( + 'id' => 'product_detail', + 'name' => $this->l('Product Detail'), + ) + ), + 'id' => 'id', + 'name' => 'name' + ), + ) + ), + 'submit' => array( + 'title' => $this->l('Save'), + ), + 'buttons' => array( + 'save-and-stay' => array( + 'title' => $this->l('Save and Stay'), + 'name' => 'submitAdd'.$this->table.'AndStay', + 'type' => 'submit', + 'class' => 'btn btn-default pull-right', + 'icon' => 'process-icon-save' + ) + ) + ); + $is_edit = Tools::getValue('id_appagebuilder_profiles'); + $this->fields_form['input'][] = array( + 'type' => 'textarea', + 'label' => $this->l('Custom Css'), + 'name' => 'css', + 'desc' => sprintf($this->l('Please set write Permission for folder %s'), $this->profile_css_folder), + ); + $this->fields_form['input'][] = array( + 'type' => 'textarea', + 'label' => $this->l('Custom Js'), + 'name' => 'js', + 'desc' => sprintf($this->l('Please set write Permission for folder %s'), $this->profile_js_folder), + ); + // Display link view if it existed + if ($is_edit) { + $profile_link = $this->context->link->getAdminLink('AdminApPageBuilderHome').'&id_appagebuilder_profiles='.$is_edit; + $this->fields_form['input'][] = array( + 'type' => 'html', + 'name' => 'default_html', + 'name' => 'dess', + 'html_content' => ' + '.$this->l('View and edit use mode Layout design').' >>' + ); + } + + $default_index_hook = $this->getDefaultIndexHook(); + $default_other_hook = $this->getDefaultOtherHook(); + $default_disable_cache_hook = $this->getDefaultDisableCacheHook(); + foreach ($default_index_hook as $key => $value) { + $this->fields_value['fullwidth_index_hook_'.$key] = $value; + } + foreach ($default_other_hook as $key => $value) { + $this->fields_value['fullwidth_other_hook_'.$key] = $value; + } + foreach ($default_disable_cache_hook as $key => $value) { + $this->fields_value['disable_cache_hook_'.$key] = $value; + } + foreach ($groups as $group) { + $this->fields_value['groupBox_'.$group['id_group']] = Tools::getValue('groupBox_'.$group['id_group'], in_array($group['id_group'], explode(',', $this->object->group_box))); + } + + $path_guide = $this->getTemplatePath().'guide.tpl'; + $guide_box = ApPageSetting::buildGuide($this->context, $path_guide, 2); + return $guide_box.parent::renderForm(); + } + + /** + * Read file css + js to form when add/edit + */ + public function getFieldsValue($obj) + { + $file_value = parent::getFieldsValue($obj); + if ($obj->id && $obj->profile_key) { + $file_value['css'] = Tools::file_get_contents($this->profile_css_folder.$obj->profile_key.'.css'); + $file_value['js'] = Tools::file_get_contents($this->profile_js_folder.$obj->profile_key.'.js'); + } else { + $file_value['profile_key'] = 'profile'.ApPageSetting::getRandomNumber(); + } + return $file_value; + } + + public function processAdd() + { + parent::validateRules(); + if (count($this->errors)) { + return false; + } + if ($this->object = parent::processAdd()) { + $this->saveCustomJsAndCss($this->object->profile_key, ''); + } + $this->processParams(); + if (!Tools::isSubmit('submitAdd'.$this->table.'AndStay')) { + $this->redirect_after = Context::getContext()->link->getAdminLink('AdminApPageBuilderHome'); + $this->redirect_after .= '&id_appagebuilder_profiles='.($this->object->id); + $this->redirect(); + } + } + + public function processUpdate() + { + parent::validateRules(); + if (count($this->errors)) { + return false; + } + if ($this->object = parent::processUpdate()) { + $this->saveCustomJsAndCss($this->object->profile_key, $this->object->profile_key); + } + + $this->processParams(); + if (!Tools::isSubmit('submitAdd'.$this->table.'AndStay')) { + $this->redirect_after = Context::getContext()->link->getAdminLink('AdminApPageBuilderHome'); + $this->redirect_after .= '&id_appagebuilder_profiles='.($this->object->id); + $this->redirect(); + } + } + + /** + * Get fullwidth hook, save to params + */ + public function processParams() + { + $params = Tools::jsonDecode($this->object->params); + if ($params === null) { + $params = new stdClass(); + } + + # get post index hook + $index_hook = ApPageSetting::getIndexHook(); + $post_index_hooks = array(); + foreach ($index_hook as $key => $value) { + // validate module + $post_index_hooks[$value] = Tools::getValue('fullwidth_index_hook_'.$value) ? + Tools::getValue('fullwidth_index_hook_'.$value) : ApPageSetting::HOOK_BOXED; + // validate module + unset($key); + } + $params->fullwidth_index_hook = $post_index_hooks; + + # get post other hook + $other_hook = ApPageSetting::getOtherHook(); + $post_other_hooks = array(); + foreach ($other_hook as $key => $value) { + // validate module + $post_other_hooks[$value] = Tools::getValue('fullwidth_other_hook_'.$value) ? Tools::getValue('fullwidth_other_hook_'.$value) : ApPageSetting::HOOK_BOXED; + // validate module + unset($key); + } + $params->fullwidth_other_hook = $post_other_hooks; + + # get post disable hook + $cache_hooks = ApPageSetting::getCacheHook(); + $post_disable_hooks = array(); + foreach ($cache_hooks as $key => $value) { + // validate module + $post_disable_hooks[$value] = Tools::getValue('disable_cache_hook_'.$value) ? Tools::getValue('disable_cache_hook_'.$value) : ApPageSetting::HOOK_BOXED; + // validate module + unset($key); + } + $params->disable_cache_hook = $post_disable_hooks; + + + # Save to params + $this->object->params = Tools::jsonEncode($params); + + # Save group_box + if (Tools::getValue('groupBox')) { + $this->object->group_box = implode(',', Tools::getValue('groupBox')); + } else { + $this->object->group_box = ''; + } + + $this->object->save(); + } + + public function saveCustomJsAndCss($key, $old_key = '') + { + # DELETE OLD FILE + if ($old_key) { + Tools::deleteFile($this->profile_css_folder.$old_key.'.css'); + Tools::deleteFile($this->profile_js_folder.$old_key.'.js'); + } + + if (Tools::getValue('js') != '') { + ApPageSetting::writeFile($this->profile_js_folder, $key.'.js', Tools::getValue('js')); + } + + if (Tools::getValue('css') != '') { + # FIX CUSTOMER CAN NOT TYPE "\" + $temp = Tools::getAllValues(); + $css = $temp['css']; + ApPageSetting::writeFile($this->profile_css_folder, $key.'.css', $css); + } + } + + /** + * Generate form : create checkbox in admin form ( add/edit profile ) + */ + public static function getCheckboxIndexHook() + { + $ids = ApPageSetting::getIndexHook(); + $names = ApPageSetting::getIndexHook(); + return apPageHelper::getArrayOptions($ids, $names); + } + + /** + * Generate form : create checkbox in admin form ( add/edit profile ) + */ + public static function getCheckboxOtherHook() + { + $ids = ApPageSetting::getOtherHook(); + $names = ApPageSetting::getOtherHook(); + return apPageHelper::getArrayOptions($ids, $names); + } + + /** + * Generate form : create checkbox in admin form ( add/edit profile ) + */ + public static function getCheckboxCacheHook() + { + $ids = ApPageSetting::getCacheHook(); + $names = ApPageSetting::getCacheHook(); + return apPageHelper::getArrayOptions($ids, $names); + } + + /** + * Get fullwidth hook from database or default + */ + public function getDefaultIndexHook() + { + $params = Tools::jsonDecode($this->object->params); + return isset($params->fullwidth_index_hook) ? $params->fullwidth_index_hook : ApPageSetting::getIndexHook(3); + } + + /** + * Get fullwidth hook from database or default + */ + public function getDefaultOtherHook() + { + $params = Tools::jsonDecode($this->object->params); + return isset($params->fullwidth_other_hook) ? $params->fullwidth_other_hook : ApPageSetting::getOtherHook(3); + } + + /** + * Get fullwidth hook from database or default + */ + public function getDefaultDisableCacheHook() + { + $params = Tools::jsonDecode($this->object->params); + return isset($params->disable_cache_hook) ? $params->disable_cache_hook : ApPageSetting::getCacheHook(3); + } + + /** + * PERMISSION ACCOUNT demo@demo.com + * OVERRIDE CORE + */ + public function initProcess() + { + parent::initProcess(); + + if (count($this->errors) <= 0) { + if( Tools::isSubmit('duplicate'.$this->table) ) { + if ($this->id_object) { + if (!$this->access('add')) + { + $this->errors[] = $this->trans('You do not have permission to duplicate this.', array(), 'Admin.Notifications.Error'); + } + } + } + } + } +} diff --git a/modules/appagebuilder/controllers/admin/AdminApPageBuilderShortcode.php b/modules/appagebuilder/controllers/admin/AdminApPageBuilderShortcode.php new file mode 100644 index 00000000..79981759 --- /dev/null +++ b/modules/appagebuilder/controllers/admin/AdminApPageBuilderShortcode.php @@ -0,0 +1,625 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageBuilderShortcodeModel.php'); + +class AdminApPageBuilderShortcodeController extends ModuleAdminControllerCore +{ + public $tpl_path; + public $module_name; + public static $shortcode_lang; + public static $language; + public $theme_dir; + public static $lang_id; + public $tpl_controller_path; + + public function __construct() + { + parent::__construct(); + + $this->bootstrap = true; + $this->table = 'appagebuilder_shortcode'; + $this->identifier = 'id_appagebuilder_shortcode'; + $this->className = 'ApPageBuilderShortcodeModel'; + $id_shop = apPageHelper::getIDShop(); + $this->_join = ' + INNER JOIN `'._DB_PREFIX_.'appagebuilder_shortcode_shop` ps ON (ps.`id_appagebuilder_shortcode` = a.`id_appagebuilder_shortcode` AND ps.`id_shop` = '.$id_shop.')'; + $this->_select .= ' ps.active as active, '; + $this->lang = true; + $this->shop = true; + $this->addRowAction('edit'); + $this->addRowAction('duplicate'); + $this->addRowAction('delete'); + $this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?'), 'icon' => 'icon-trash')); + $this->fields_list = array( + 'id_appagebuilder_shortcode' => array( + 'title' => $this->l('ID'), + 'type' => 'text', + 'class' => 'fixed-width-sm' + ), + 'shortcode_name' => array( + 'title' => $this->l('Name'), + 'type' => 'text', + ), + 'shortcode_key' => array( + 'title' => $this->l('Key'), + 'type' => 'text', + ), + 'active' => array( + 'title' => $this->l('Status'), + 'active' => 'status', + 'type' => 'bool', + 'class' => 'fixed-width-sm' + ), + ); + + $this->_defaultOrderBy = 'id_appagebuilder_shortcode'; + $this->module_name = 'appagebuilder'; + $this->tpl_path = _PS_ROOT_DIR_.'/modules/'.$this->module_name.'/views/templates/admin'; + self::$language = Language::getLanguages(false); + $this->theme_dir = _PS_THEME_DIR_; + $this->tpl_controller_path = _PS_ROOT_DIR_.'/modules/'.$this->module_name.'/views/templates/admin/ap_page_builder_shortcode/'; + apPageHelper::loadShortCode(_PS_THEME_DIR_); + } + + public function initContent() + { + //DONGND:: get list shortcode to tiny mce + if (Tools::getIsset('get_listshortcode')) + { + die($this->module->getListShortCodeForEditor()); + } + else + { + parent::initContent(); + } + } + + public function renderForm() + { + + $txt_legend = ''; + if (Validate::isLoadedObject($this->object)) { + $this->display = 'edit'; + $txt_legend = $this->l('Edit Shortcode'); + } else { + $this->display = 'add'; + $txt_legend = $this->l('Add New Shortcode'); + } + + $this->fields_form = array( + 'legend' => array( + 'title' => $txt_legend, + 'icon' => 'icon-cogs', + ), + 'input' => array( + // array( + // 'type' => 'hidden', + // 'name' => 'id_appagebuilder_shortcode', + // ), + array( + 'type' => 'hidden', + 'name' => 'id_appagebuilder', + ), + array( + 'type' => 'hidden', + 'name' => 'shortcode_content', + ), + array( + 'type' => 'hidden', + 'name' => 'stay_page', + ), + array( + 'type' => 'text', + 'lang' => true, + 'required' => true, + 'label' => $this->l('Shortcode Name'), + 'name' => 'shortcode_name', + ), + array( + 'type' => 'textbutton', + 'label' => $this->l('Shortcode Key'), + 'name' => 'shortcode_key', + 'readonly' => 'readonly', + 'lang' => false, + 'button' => array( + 'label' => $this->l('Copy To Clipboard'), + 'class' => 'bt_copy_clipboard shortcode_key', + 'attributes' => array( + // 'onclick' => 'alert(\'something done\');' + ) + ) + ), + array( + 'type' => 'switch', + 'is_bool' => true, //retro compat 1.5 + 'label' => $this->l('Active'), + 'name' => 'active', + 'default_value' => 1, + 'values' => array( + array( + 'id' => 'active_on', + 'value' => 1, + 'label' => $this->l('Enabled'), + ), + array( + 'id' => 'active_off', + 'value' => 0, + 'label' => $this->l('Disabled'), + ), + ) + ), + ), + 'submit' => array( + 'title' => $this->l('Save'), + 'class' => 'shortcode_save_btn btn btn-default pull-right', + 'name' => 'submitApShortcode', + ), + 'buttons' => array( + 'save_and_preview' => array( + 'name' => 'submitApShortcodeAndStay', + 'type' => 'submit', + 'title' => $this->l('Save and stay'), + 'class' => 'shortcode_save_stay_btn btn btn-default pull-right', + 'icon' => 'process-icon-save-and-stay' + ) + ) + + ); + + if (Validate::isLoadedObject($this->object)) { + $this->fields_form['input'][] = array( + 'type' => 'textbutton', + 'label' => $this->l('Embed Hook'), + 'name' => 'shortcode_embedded_hook', + 'readonly' => 'readonly', + 'desc' => $this->l('Insert embed hook in any tpl file'), + 'lang' => false, + 'button' => array( + 'label' => $this->l('Copy To Clipboard'), + 'class' => 'bt_copy_clipboard shortcode_embedded_hook', + 'attributes' => array( + // 'onclick' => 'alert(\'something done\');' + ) + ) + ); + $this->fields_form['input'][] = array( + 'type' => 'textbutton', + 'label' => $this->l('Embed Code'), + 'name' => 'shortcode_embedded_code', + 'readonly' => 'readonly', + 'desc' => $this->l('Insert embed code in any content with editor'), + 'lang' => false, + 'button' => array( + 'label' => $this->l('Copy To Clipboard'), + 'class' => 'bt_copy_clipboard shortcode_embedded_code', + 'attributes' => array( + // 'onclick' => 'alert(\'something done\');' + ) + ) + ); + } + + $this->context->controller->addJqueryUI('ui.sortable'); + $this->context->controller->addJqueryUI('ui.draggable'); + $this->context->controller->addCss(apPageHelper::getCssAdminDir().'admin/form.css'); + $this->context->controller->addCss(apPageHelper::getCssAdminDir().'animate.css'); + $this->context->controller->addJs(apPageHelper::getJsAdminDir().'admin/form.js'); + $this->context->controller->addJs(apPageHelper::getJsAdminDir().'admin/home.js'); + $this->context->controller->addJs(apPageHelper::getJsAdminDir().'admin/isotope.pkgd.min.js'); + $this->context->controller->addJS(_PS_JS_DIR_.'tiny_mce/tiny_mce.js'); + + $this->context->controller->addJs(apPageHelper::getJsAdminDir().'admin/jquery-validation-1.9.0/jquery.validate.js'); + $this->context->controller->addCss(apPageHelper::getJsAdminDir().'admin/jquery-validation-1.9.0/screen.css'); + +// $version = Configuration::get('PS_INSTALL_VERSION'); +// $tiny_path = ($version >= '1.6.0.13') ? 'admin/' : ''; +// $tiny_path .= 'tinymce.inc.js'; + + // Pham_Khanh_Dong fix loading TINY_MCE library for all Prestashop_Versions + $tiny_path = 'tinymce.inc.js'; + if (version_compare(_PS_VERSION_, '1.6.0.13', '>')) { + $tiny_path = 'admin/tinymce.inc.js'; + } + + $this->context->controller->addJS(_PS_JS_DIR_.$tiny_path); + $bo_theme = ((Validate::isLoadedObject($this->context->employee) && $this->context->employee->bo_theme) ? $this->context->employee->bo_theme : 'default'); + if (!file_exists(_PS_BO_ALL_THEMES_DIR_.$bo_theme.DIRECTORY_SEPARATOR.'template')) { + $bo_theme = 'default'; + } + $this->addJs(__PS_BASE_URI__.$this->admin_webpath.'/themes/'.$bo_theme.'/js/jquery.fileupload.js'); + $this->addJs(__PS_BASE_URI__.$this->admin_webpath.'/themes/'.$bo_theme.'/js/jquery.fileupload-process.js'); + $this->addJs(__PS_BASE_URI__.$this->admin_webpath.'/themes/'.$bo_theme.'/js/jquery.fileupload-validate.js'); + $this->context->controller->addJs(__PS_BASE_URI__.'js/vendor/spin.js'); + $this->context->controller->addJs(__PS_BASE_URI__.'js/vendor/ladda.js'); + + //load javascript for menu tree + $tree = new HelperTreeCategories('123', null); + $tree->render(); + + // if (isset($result_profile) && $result_profile) { + + $languages = array(); + foreach (Language::getLanguages(false) as $lang) { + $languages[$lang['iso_code']] = $lang['id_lang']; + } + + // get shortcode information + $shortcode_infos = ApShortCodeBase::getShortCodeInfos(); + //include all short code default + $shortcodes = Tools::scandir($this->tpl_path.'/ap_page_builder_shortcodes', 'tpl'); + $shortcode_form = array(); + foreach ($shortcodes as $s_from) { + if ($s_from == 'shortcodelist.tpl') { + continue; + } + $shortcode_form[] = $this->tpl_path.'/ap_page_builder_shortcodes/'.$s_from; + }; + $tpl = $this->createTemplate('home.tpl'); + + $model = new ApPageBuilderShortcodeModel(); + + $data_shortcode_content = array(); + $positions_dum = array(); + + $data_form = '{}'; + + $id_appagebuilder = ApPageBuilderModel::getIdByIdShortCode($this->object->id); + + if ($id_appagebuilder) { + $positions_dum = $model->getShortCodeContent($id_appagebuilder); + $temp = $positions_dum['content']; + + foreach ($temp as $key_hook => &$row) { + if (!is_array($row)) { + $row = array('hook_name' => $key_hook, 'content' => ''); + } + if ($key_hook == 'displayLeftColumn' || $key_hook == 'displayRightColumn') { + $row['class'] = 'col-md-3'; + } else { + $row['class'] = 'col-md-12'; + } + } + $data_shortcode_content = $temp; + $data = $model->getAllItems($id_appagebuilder); + $data_form = Tools::jsonEncode($data['dataForm']); + } + + $tpl->assign(array( + 'data_shortcode_content' => $data_shortcode_content, + // 'positions' => $positions, + // 'listPositions' => $list_positions, + // 'dataByHook' => $data_by_hook, + // 'exportItems' => $export_items, + // 'currentProfile' => $result_profile, + // 'currentPosition' => $current_position, + // 'profilesList' => $this->getAllProfiles($result_profile['id_appagebuilder_profiles']), + 'tplPath' => $this->tpl_path, + 'ajaxShortCodeUrl' => Context::getContext()->link->getAdminLink('AdminApPageBuilderShortcodes'), + 'ajaxHomeUrl' => Context::getContext()->link->getAdminLink('AdminApPageBuilderHome'), + 'shortcodeForm' => $shortcode_form, + 'moduleDir' => _MODULE_DIR_, + 'imgModuleLink' => apPageHelper::getImgThemeUrl(), + 'shortcodeInfos' => Tools::jsonEncode($shortcode_infos), + 'languages' => Tools::jsonEncode($languages), + 'dataForm' => $data_form, + // 'errorText' => $this->error_text, + 'imgController' => Context::getContext()->link->getAdminLink('AdminApPageBuilderImages'), + 'widthList' => ApPageSetting::returnWidthList(), + 'lang_id' => (int)$this->context->language->id, + // 'idProfile' => '', + // 'checkSaveMultithreading' => $check_save_multithreading, + // 'checkSaveSubmit' => $check_save_submit, + // 'errorSubmit' => $errorSubmit + 'listAnimation' => ApPageSetting::getAnimationsColumnGroup(), + )); + // return $guide_box.$tpl->fetch(); + // } else { + // $this->errors[] = $this->l('Your Profile ID is not exist!'); + // } + + return parent::renderForm().$tpl->fetch(); + } + + public function getFieldsValue($obj) + { + $file_value = parent::getFieldsValue($obj); + + if ($file_value['shortcode_key'] == '') { + $file_value['shortcode_key'] = 'sc'.ApPageSetting::getRandomNumber(); + } else { + $file_value['shortcode_embedded_hook'] = "{hook h='displayApSC' sc_key=".$file_value['shortcode_key']."}"; + $file_value['shortcode_embedded_code'] = "[ApSC sc_key=".$file_value['shortcode_key']."][/ApSC]"; + } + + return $file_value; + } + + public function postProcess() + { + if (count($this->errors) > 0) { + return; + } + if (Tools::isSubmit('submitAddappagebuilder_shortcode')) { + parent::validateRules(); + + if ((int) Tools::getValue('id_appagebuilder_shortcode')) { + $mess_id = '4'; + } else { + $mess_id = '3'; + } + + $shortcode_obj = new ApPageBuilderShortcodeModel((int) Tools::getValue('id_appagebuilder_shortcode')); + $shortcode_obj->shortcode_key = Tools::getValue('shortcode_key'); + $shortcode_obj->active = Tools::getValue('active'); + + //DONGND:: fields multi lang + $languages = Language::getLanguages(); + $name = array(); + foreach ($languages as $key => $value) { + $name[$value['id_lang']] = Tools::getValue('shortcode_name_'.$value['id_lang']); + } + $shortcode_obj->shortcode_name = $name; + + $shortcode_obj->save(); + + $shortcode_content = Tools::jsonDecode(Tools::getValue('shortcode_content'), 1); + + $id_appagebuilder = ApPageBuilderModel::getIdByIdShortCode($shortcode_obj->id); + if ($id_appagebuilder) { + $obj_model = new ApPageBuilderModel($id_appagebuilder); + } else { + $obj_model = new ApPageBuilderModel(); + } + + $obj_model->hook_name = 'apshortcode'; + $obj_model->id_appagebuilder_shortcode = $shortcode_obj->id; + + if (isset($shortcode_content['groups'])) { + foreach (self::$language as $lang) { + $params = ''; + if (self::$shortcode_lang) { + foreach (self::$shortcode_lang as &$s_type) { + foreach ($s_type as $key => $value) { + $s_type[$key] = $key.'_'.$lang['id_lang']; + // validate module + unset($value); + } + } + } + $obj_model->params[$lang['id_lang']] = ''; + ApShortCodesBuilder::$lang_id = $lang['id_lang']; + foreach ($shortcode_content['groups'] as $groups) { + $params = $this->getParamByHook($groups, $params, ''); + } + $obj_model->params[$lang['id_lang']] = $params; + } + } + + if ($obj_model->id) { + $obj_model->save(); + } else { + $obj_model->add(); + } + + if ($shortcode_obj->save()) { + $this->module->clearShortCodeCache($shortcode_obj->shortcode_key); + + if (Tools::getValue('stay_page')) { + # validate module + $this->redirect_after = self::$currentIndex.'&'.$this->identifier.'='.$shortcode_obj->id.'&conf='.$mess_id.'&update'.$this->table.'&token='.$this->token; + } else { + # validate module + $this->redirect_after = self::$currentIndex.'&conf=4&token='.$this->token; + } + } else { + return false; + } + } else if (Tools::getIsset('duplicateappagebuilder_shortcode')) { + //DONGND:: duplicate + if (Tools::getIsset('id_appagebuilder_shortcode') && (int)Tools::getValue('id_appagebuilder_shortcode')) { + if ($shortcode_obj = new ApPageBuilderShortcodeModel((int) Tools::getValue('id_appagebuilder_shortcode'))) { + $duplicate_object = new ApPageBuilderShortcodeModel(); + $duplicate_object->active = $shortcode_obj->active; + + $languages = Language::getLanguages(); + $name = array(); + foreach ($languages as $key => $value) { + $name[$value['id_lang']] = $this->l('Duplicate of').' '.$shortcode_obj->shortcode_name[$value['id_lang']]; + } + + $duplicate_object->shortcode_name = $name; + $duplicate_object->shortcode_key = 'sc'.ApPageSetting::getRandomNumber(); + + if ($duplicate_object->add()) { + //duplicate shortCode + $id_appagebuilder = ApPageBuilderModel::getIdByIdShortCode($shortcode_obj->id); + if ($id_appagebuilder) { + $obj_model = new ApPageBuilderModel($id_appagebuilder); + $duplicate_obj_object = new ApPageBuilderModel(); + $duplicate_obj_object->hook_name = 'apshortcode'; + $duplicate_obj_object->id_appagebuilder_shortcode = $duplicate_object->id; + $duplicate_obj_object->params = $obj_model->params; + $duplicate_obj_object->add(); + + $this->redirect_after = self::$currentIndex.'&conf=3&token='.$this->token; + } else { + $this->redirect_after = self::$currentIndex.'&conf=3&token='.$this->token; + } + } else { + Tools::displayError('Can not duplicate shortcode'); + } + } else { + return false; + } + } else { + return false; + } + } else { + if (Tools::getIsset('statusappagebuilder_shortcode') || Tools::getIsset('deleteappagebuilder_shortcode')) { + $shortcode_obj = new ApPageBuilderShortcodeModel((int) Tools::getValue('id_appagebuilder_shortcode')); + $this->module->clearShortCodeCache($shortcode_obj->shortcode_key); + } + parent::postProcess(); + } + } + + private function getParamByHook($groups, $params, $hook, $action = 'save') + { + $groups['params']['specific_type'] = (isset($groups['params']['specific_type']) && $groups['params']['specific_type']) ? $groups['params']['specific_type'] : ''; + $groups['params']['controller_pages'] = (isset($groups['params']['controller_pages']) && $groups['params']['controller_pages']) ? $groups['params']['controller_pages'] : ''; + $groups['params']['controller_id'] = (isset($groups['params']['controller_id']) && $groups['params']['controller_id']) ? $groups['params']['controller_id'] : ''; + $params .= '[ApRow'.ApShortCodesBuilder::converParamToAttr2($groups['params'], 'ApRow', $this->theme_dir).']'; + //check exception page + $this->saveExceptionConfig($hook, $groups['params']['specific_type'], $groups['params']['controller_pages'], $groups['params']['controller_id']); + foreach ($groups['columns'] as $columns) { + $columns['params']['specific_type'] = (isset($columns['params']['specific_type']) && $columns['params']['specific_type']) ? $columns['params']['specific_type'] : ''; + $columns['params']['controller_pages'] = (isset($columns['params']['controller_pages']) && $columns['params']['controller_pages']) ? $columns['params']['controller_pages'] : ''; + $columns['params']['controller_id'] = (isset($columns['params']['controller_id']) && $columns['params']['controller_id']) ? $columns['params']['controller_id'] : ''; + $this->saveExceptionConfig($hook, $columns['params']['specific_type'], $columns['params']['controller_pages'], $columns['params']['controller_id']); + $params .= '[ApColumn'.ApShortCodesBuilder::converParamToAttr2($columns['params'], 'ApColumn', $this->theme_dir).']'; + foreach ($columns['widgets'] as $widgets) { + if ($widgets['type'] == 'ApTabs' || $widgets['type'] == 'ApAccordions') { + $params .= '['.$widgets['type'].ApShortCodesBuilder::converParamToAttr2($widgets['params'], $widgets['type'], $this->theme_dir).']'; + foreach ($widgets['widgets'] as $sub_widgets) { + $type_sub = Tools::substr($widgets['type'], 0, -1); + $params .= '['.$type_sub.ApShortCodesBuilder::converParamToAttr2($sub_widgets['params'], str_replace('_', '_sub_', $widgets['type']), $this->theme_dir).']'; + foreach ($sub_widgets['widgets'] as $sub_widget) { + $params .= '['.$sub_widget['type'] + .ApShortCodesBuilder::converParamToAttr2($sub_widget['params'], $sub_widget['type'], $this->theme_dir).'][/' + .$sub_widget['type'].']'; + } + $params .= '[/'.$type_sub.']'; + } + $params .= '[/'.$widgets['type'].']'; + } else { + $params .= '['.$widgets['type'].ApShortCodesBuilder::converParamToAttr2($widgets['params'], $widgets['type'], $this->theme_dir).'][/'.$widgets['type'].']'; + if ($widgets['type'] == 'ApModule' && $action == 'save') { + $is_delete = (int)$widgets['params']['is_display']; + if ($is_delete) { + if (!isset($widgets['params']['hook'])) { + // FIX : Module not choose hook -> error + $widgets['params']['hook'] = ''; + } + $this->deleteModuleFromHook($widgets['params']['hook'], $widgets['params']['name_module']); + } + } else if ($widgets['type'] == 'ApProductCarousel') { + if ($widgets['params']['order_way'] == 'random') { + $this->config_module[$hook]['productCarousel']['order_way'] = 'random'; + } + } + } + } + $params .= '[/ApColumn]'; + } + $params .= '[/ApRow]'; + return $params; + } + + private function saveExceptionConfig($hook, $type, $page, $ids) + { + if (!$type) { + return; + } + + if ($type == 'all') { + if ($type != '') { + $list = explode(',', $page); + foreach ($list as $val) { + $val = trim($val); + if ($val && (!is_array($this->config_module) || !isset($this->config_module[$hook]) || !isset($this->config_module[$hook]['exception']) || !isset($val, $this->config_module[$hook]['exception']))) { + $this->config_module[$hook]['exception'][] = $val; + } + } + } + } else { + $this->config_module[$hook][$type] = array(); + if ($type != 'index') { + $ids = explode(',', $ids); + foreach ($ids as $val) { + $val = trim($val); + if (!in_array($val, $this->config_module[$hook][$type])) { + $this->config_module[$hook][$type][] = $val; + } + } + } + } + } + + public function adminContent($assign, $tpl_name) + { + if (file_exists($this->tpl_controller_path.$tpl_name)) { + $tpl = $this->createTemplate($tpl_name); + } else { + $tpl = $this->createTemplate('ApGeneral.tpl'); + } + $assign['moduleDir'] = _MODULE_DIR_; + foreach ($assign as $key => $ass) { + $tpl->assign(array($key => $ass)); + } + return $tpl->fetch(); + } + + public function displayDuplicateLink($token = null, $id = null, $name = null) + { + $href = self::$currentIndex.'&'.$this->identifier.'='.$id.'&duplicate'.$this->table.'&token='.($token != null ? $token : $this->token); + $html = ' + Duplicate + '; + + // validate module + unset($name); + + return $html; + } + + /** + * PERMISSION ACCOUNT demo@demo.com + * OVERRIDE CORE + */ + public function access($action, $disable = false) + { + if (Tools::getIsset('update'.$this->table) && Tools::getIsset($this->identifier)) { + // Allow person see "EDIT" form + $action = 'view'; + } + return parent::access($action, $disable); + } + + /** + * PERMISSION ACCOUNT demo@demo.com + * OVERRIDE CORE + */ + public function initProcess() + { + parent::initProcess(); + + if (count($this->errors) <= 0) { + if( Tools::isSubmit('duplicate'.$this->table) ) { + if ($this->id_object) { + if (!$this->access('add')) + { + $this->errors[] = $this->trans('You do not have permission to duplicate this.', array(), 'Admin.Notifications.Error'); + } + } + } + } + } +} diff --git a/modules/appagebuilder/controllers/admin/AdminApPageBuilderShortcodes.php b/modules/appagebuilder/controllers/admin/AdminApPageBuilderShortcodes.php new file mode 100644 index 00000000..f4abffbf --- /dev/null +++ b/modules/appagebuilder/controllers/admin/AdminApPageBuilderShortcodes.php @@ -0,0 +1,252 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +require_once(_PS_MODULE_DIR_.'appagebuilder/classes/ApPageSetting.php'); +require_once(_PS_MODULE_DIR_.'appagebuilder/controllers/admin/AdminApPageBuilderPositions.php'); + +class AdminApPageBuilderShortcodesController extends ModuleAdminControllerCore +{ + public static $shortcode_lang; + public static $language; + public static $lang_id; + public $file_content = ''; + protected $max_image_size = null; + public $theme_name; + public $config_module; + public $hook_assign; + public $module_name; + public $module_path; + public $tpl_controller_path; + public $tpl_front_path; + public $shortcode_dir; + public $shortcode_override_dir; + public $theme_dir; + public $theme_url; + + public function __construct() + { + $this->bootstrap = true; + $this->show_toolbar = true; + $this->table = 'appagebuilder'; + $this->className = 'ApPageBuilderShortCode'; + $this->context = Context::getContext(); + $this->module_name = 'appagebuilder'; + $this->module_path = __PS_BASE_URI__.'modules/'.$this->module_name.'/'; + $this->tpl_controller_path = _PS_ROOT_DIR_.'/modules/'.$this->module_name.'/views/templates/admin/ap_page_builder_shortcodes/'; + $this->tpl_front_path = _PS_ROOT_DIR_.'/modules/'.$this->module_name.'/views/templates/font/'; + $this->shortcode_dir = _PS_MODULE_DIR_.'appagebuilder/classes/shortcodes/'; + + self::$language = Language::getLanguages(false); + parent::__construct(); + $this->theme_dir = _PS_THEME_DIR_; + $this->theme_url = _THEMES_DIR_._THEME_NAME_.'/'; + $this->shortcode_override_dir = $this->theme_dir.'modules/appagebuilder/classes/shortcodes/'; + $this->max_image_size = (int)Configuration::get('PS_PRODUCT_PICTURE_MAX_SIZE'); + $this->theme_name = _THEME_NAME_; + $this->hook_assign = array('rightcolumn', 'leftcolumn', 'home', 'top', 'footer'); + } + + public function init() + { + if (Tools::getIsset('type_shortcode')) { + # Run AJAX here for Hight Speed + $this->ajaxLoadWidget(); + } + parent::init(); + } + + /** + * Duplicate all data relate with profile + * @param type int $old_id : current profile id is duplicating + * @param type int $new_id : new profile id after duplicated + */ + public static function duplicateData($old_id, $new_id) + { +// $context = Context::getContext(); + $positions = array(); + $sql = 'SELECT * + FROM `'._DB_PREFIX_.'appagebuilder_profiles` p + WHERE p.id_appagebuilder_profiles='.(int)$old_id; + $result = Db::getInstance()->getRow($sql); + if ($result) { + $positions[] = $result['header']; + $positions[] = $result['content']; + $positions[] = $result['footer']; + $positions[] = $result['product']; + } + $sql_update = 'UPDATE '._DB_PREFIX_.'appagebuilder_profiles '; + $sep = ' SET '; + $is_update = false; + // Duplicate positions + foreach ($positions as $item) { + $id = (int)$item; + $object = ApPageBuilderPositionsModel::getPositionById($id); + if ($object) { + $key = ApPageSetting::getRandomNumber(); + $old_key = $object['position_key']; + $name = 'Duplicate '.$key; + $data = array('name' => $name, 'position' => $object['position'], 'position_key' => 'duplicate_'.$key); + $model = new ApPageBuilderPositionsModel(); + $duplicate_id = $model->addAuto($data); + if ($duplicate_id) { + $position_controller = new AdminApPageBuilderPositionsController(); + $sql_update .= $sep.$data['position'].'='.$duplicate_id; + $sep = ', '; + $is_update = true; + self::duplcateDataPosition($id, $duplicate_id); + ApPageSetting::writeFile($position_controller->position_js_folder, $data['position'].$data['position_key'].'.js', Tools::file_get_contents($position_controller->position_js_folder.$data['position'].$old_key.'.js')); + ApPageSetting::writeFile($position_controller->position_css_folder, $data['position'].$data['position_key'].'.css', Tools::file_get_contents($position_controller->position_css_folder.$data['position'].$old_key.'.css')); + } + } + } + if ($is_update) { + $sql_update .= ' WHERE id_appagebuilder_profiles='.(int)$new_id; + Db::getInstance()->execute($sql_update); + } + } + + /** + * Duplicate a position: dulicate data in table appagebuilder_lang; appagebuilder; appagebuilder_shop; + * @param type int $old_id: position id for duplicate + * @param type int $duplicate_id: new position id + */ + public static function duplcateDataPosition($old_id, $duplicate_id) + { + $context = Context::getContext(); + $id_shop = $context->shop->id; + // Get list appagebuilder for copy + $sql = 'SELECT * from '._DB_PREFIX_.'appagebuilder p WHERE p.id_appagebuilder_positions='.(int)$old_id; + $result = Db::getInstance()->executeS($sql); + foreach ($result as $item) { + // Duplicate to tables appagebuilder + $sql = 'INSERT INTO '._DB_PREFIX_.'appagebuilder (id_appagebuilder_positions, hook_name) + VALUES("'.(int)$duplicate_id.'", "'.pSQL($item['hook_name']).'")'; + Db::getInstance()->execute($sql); + // Duplicate to tables appagebuilder_shop + $id_new = Db::getInstance()->Insert_ID(); + $sql = 'INSERT INTO '._DB_PREFIX_.'appagebuilder_shop (id_appagebuilder, id_shop) + VALUES('.(int)$id_new.', '.(int)$id_shop.')'; + Db::getInstance()->execute($sql); + // Copy data and languages + $sql = 'SELECT * from '._DB_PREFIX_.'appagebuilder_lang p + WHERE p.id_appagebuilder='.(int)$item['id_appagebuilder']; + $old_data = Db::getInstance()->executeS($sql); + foreach ($old_data as $temp) { + $sql = 'INSERT INTO '._DB_PREFIX_."appagebuilder_lang (id_appagebuilder, id_lang, params) + VALUES('".(int)$id_new."', '".(int)$temp['id_lang']."', '".pSql(apPageHelper::replaceFormId($temp['params']))."')"; + Db::getInstance()->execute($sql); + } + } + } + + + public function adminContent($assign, $tpl_name) + { + if (file_exists($this->tpl_controller_path.$tpl_name)) { + $tpl = $this->createTemplate($tpl_name); + } else { + $tpl = $this->createTemplate('ApGeneral.tpl'); + } + $assign['moduleDir'] = _MODULE_DIR_; + foreach ($assign as $key => $ass) { + $tpl->assign(array($key => $ass)); + } + return $tpl->fetch(); + } + + public function postProcess() + { + parent::postProcess(); + } + + /** + * AJAX : + * - load widget or module + * - call method of widget + */ + private function ajaxLoadWidget() + { + $type_shortcode = Tools::ucfirst(Tools::getValue('type_shortcode')); + $type = Tools::getValue('type'); + $shor_code_dir = ''; + // Add new widget from apollotheme + if ($type === 'widget') { + if (!$shor_code_dir = ApPageSetting::requireShortCode($type_shortcode.'.php', $this->theme_dir)) { + die($this->l('This short code is not exist')); + } + if (class_exists($type_shortcode) != true) { + // validate module + require_once($shor_code_dir); + } + + $obj = new $type_shortcode; + die($obj->renderForm()); + } elseif ($type === 'module') { + // Custom a module + $shor_code_dir = ApPageSetting::requireShortCode('ApModule.php', $this->theme_dir); + if (class_exists('ApModule') != true) { + // validate module + require_once($shor_code_dir); + } + $obj = new ApModule(); + die($obj->renderForm()); + } + + + + # RUN WIDGET METHOD - BEGIN + $result = array( + 'hasError' => false, + 'error' => '', + 'success' => false, + 'information' => '', + ); + $type_shortcode = Tools::ucfirst(Tools::getValue('type_shortcode')); + if (Tools::getIsset('type_shortcode') && $type_shortcode) { + if ($shor_code_dir = ApPageSetting::requireShortCode($type_shortcode.'.php', $this->theme_dir)) { + if (class_exists($type_shortcode) != true) { + require_once($shor_code_dir); + } + $obj = new $type_shortcode; + $method_name = Tools::getValue('method_name', ''); + $method_name = 'ajaxCallBack'.Tools::toCamelCase($method_name, true); + if (method_exists($obj, $method_name)) { + # RUN WIDGET METHOD + $obj->{$method_name}(); + $result['information'] = $method_name . $this->l(' is successful'); + } else { + $result['error'] = sprintf($this->l('%s method is not exist'), $method_name); + } + } else { + $result['error'] = sprintf($this->l('%s is not found'), $type_shortcode.'.php'); + } + } else { + $result['error'] = $this->l('type_shortcode param is empty'); + } + + if (count($result['error'])) { + $result['hasError'] = true; + } + + die(Tools::jsonEncode($result)); + # RUN WIDGET METHOD - END + } + +} diff --git a/modules/appagebuilder/controllers/admin/AdminApPageBuilderThemeConfiguration.php b/modules/appagebuilder/controllers/admin/AdminApPageBuilderThemeConfiguration.php new file mode 100644 index 00000000..e9a2bfe2 --- /dev/null +++ b/modules/appagebuilder/controllers/admin/AdminApPageBuilderThemeConfiguration.php @@ -0,0 +1,1589 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +require_once(_PS_MODULE_DIR_.'appagebuilder/libs/LeoFrameworkHelper.php'); +require_once(_PS_MODULE_DIR_.'appagebuilder/libs/LeoDataSample.php'); +require_once(_PS_MODULE_DIR_.'appagebuilder/libs/google_fonts.php'); + +/** + * + * NOT extends ModuleAdminControllerCore, because override tpl : ROOT/modules/appagebuilder/views/templates/admin/ap_page_builder_theme_configuration/helpers/form/form.tpl + */ +class AdminApPageBuilderThemeConfigurationController extends ModuleAdminController +{ + protected $max_image_size = null; + public $module_name = 'appagebuilder'; + public $img_path; + public $folder_name; + public $module_path; + public $tpl_path; + public $theme_dir; + + /** + * @var Array $overrideHooks + */ + protected $themeName; + + /** + * @var Array $overrideHooks + */ + protected $themePath = ''; + + /** + * save config + */ + public $submitSaveSetting = false; + + + public function __construct() + { + parent::__construct(); + $this->theme_dir = _PS_THEME_DIR_; + $this->folder_name = Tools::getIsset('imgDir') ? Tools::getValue('imgDir') : 'images'; + $this->bootstrap = true; + $this->max_image_size = (int)Configuration::get('PS_PRODUCT_PICTURE_MAX_SIZE'); + $this->themeName = apPageHelper::getThemeName(); + $this->img_path = apPageHelper::getImgThemeDir($this->folder_name); + $this->img_url = apPageHelper::getImgThemeUrl($this->folder_name); + $this->className = 'ApPageBuilderPositionsModel'; + $this->context = Context::getContext(); + $this->module_path = __PS_BASE_URI__.'modules/'.$this->module_name.'/'; + $this->tpl_path = _PS_ROOT_DIR_.'/modules/'.$this->module_name.'/views/templates/admin'; + $this->module_path = __PS_BASE_URI__.'modules/appagebuilder/'; +// $this->module_path_resource = $this->module_path.'views/'; + $this->themePath = _PS_ALL_THEMES_DIR_.$this->themeName.'/'; + } + + public function initPageHeaderToolbar() + { + $this->context->controller->addJquery(); + $this->context->controller->addJqueryUI('ui.sortable'); // FILE FORM.js required this + $this->context->controller->addJqueryUI('ui.draggable'); // FILE FORM.js required this + $this->context->controller->addJs(apPageHelper::getJsAdminDir().'admin/form.js'); + $this->context->controller->addJs(apPageHelper::getJsAdminDir().'admin/home.js'); + + Context::getContext()->controller->addJqueryPlugin('colorpicker'); + + Media::addJsDef(array( + 'ap_controller' => 'AdminApPageBuilderThemeConfigurationController', + )); + + $this->context->controller->addCss(__PS_BASE_URI__.str_replace('//', '/', 'modules/appagebuilder').'/css/admin/style_AdminApPageBuilderThemeConfiguration.css', 'all'); + parent::initPageHeaderToolbar(); + } + + /** + * OVERRIDE ROOT\classes\controller\AdminController.php + * Assign smarty variables for all default views, list and form, then call other init functions + */ + public function initContent() + { + if (!$this->viewAccess()) { + $this->errors[] = $this->l('You do not have permission to view this.'); + return; + } + + $this->getLanguages(); + $this->initToolbar(); + $this->initTabModuleList(); + $this->initPageHeaderToolbar(); + + $this->content .= $this->renderForm(); + // FIXME: Sorry. I'm not very proud of this, but no choice... Please wait sf refactoring to solve this. + if (get_class($this) != 'AdminCarriersController') { + $this->content .= $this->renderModulesList(); + } + $this->content .= $this->renderKpis(); + $this->content .= $this->renderList(); + $this->content .= $this->renderOptions(); + + // if we have to display the required fields form + if ($this->required_database) { + $this->content .= $this->displayRequiredFields(); + } + + $this->context->smarty->assign(array( + 'maintenance_mode' => !(bool)Configuration::get('PS_SHOP_ENABLE'), + 'debug_mode' => (bool)_PS_MODE_DEV_, + 'content' => $this->content, + 'lite_display' => $this->lite_display, + 'url_post' => self::$currentIndex.'&token='.$this->token, + 'show_page_header_toolbar' => $this->show_page_header_toolbar, + 'page_header_toolbar_title' => $this->page_header_toolbar_title, + 'title' => $this->page_header_toolbar_title, + 'toolbar_btn' => $this->page_header_toolbar_btn, + 'page_header_toolbar_btn' => $this->page_header_toolbar_btn + )); + } + + public function renderForm() + { + $soption = array( + array( + 'id' => 'active_on', + 'value' => 1, + 'label' => $this->l('Enabled'), + ), + array( + 'id' => 'active_off', + 'value' => 0, + 'label' => $this->l('Disabled'), + ) + ); + + $tskins = LeoFrameworkHelper::getSkins($this->themeName); +// $directions = LeoFrameworkHelper::getLayoutDirections($this->themeName); + + $this->lang = true; + $skins = array(); + $skins[] = array('name' => $this->l('Default'), 'id' => 'default'); + $skins = array_merge_recursive($skins, $tskins); + + $this->initToolbar(); + $this->context->controller->addJqueryUI('ui.sortable'); + + $sample = new Datasample(); + $moduleList = $sample->getModuleList(); + + $fields_form = array( +// 'legend' => array( +// 'title' => $this->l('Ap Theme Configuration'), +// 'icon' => 'icon-folder-close' +// ), + 'input' => array( + 'config' => array( + 'type' => 'tabConfig', + 'name' => 'title', + 'values' => array( + 'aprow_general' => $this->l('General Setting'), + 'aprow_pages' => $this->l('Pages Setting'), +// 'aprow_font' => $this->l('Font Setting'), + 'aprow_font_setup' => $this->l('Google Font'), + 'aprow_font_option' => $this->l('Font Setting'), + 'aprow_data' => $this->l('Data Sample'), + ), + 'default' => Tools::getValue('tab_open') ? Tools::getValue('tab_open') : 'aprow_general', + 'save' => false, + ), + array( + 'type' => 'switch', + 'label' => $this->l('Load Css With Prestashop Standard'), + 'name' => $this->getConfigName('load_css_type'), + 'default' => 0, + 'values' => $soption, + 'desc' => $this->l('Use prestashop standard to load css or load with sperator link in header.tpl. If you want to load css follow prestashop standard please drag Appagebuilder module in end of position header'), + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Move Appagebuilder To End of hook Header'), + 'name' => $this->getConfigName('move_end_header'), + 'default' => 0, + 'values' => $soption, + 'desc' => $this->l('If you select yes, we will move Appagebuilder to end of hook header'), + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Enable Responsive'), + 'name' => $this->getConfigName('enable_responsive'), + 'default' => 0, + 'values' => $soption, + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'text', + 'label' => $this->l('Layout Width'), + 'name' => $this->getConfigName('layout_width'), + 'default' => 'auto', + 'cast' => 'intval', + 'desc' => $this->l('Number of pixel. You can input "auto" or "number", such as: 1170'), + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Enable Panel Tool'), + 'name' => $this->getConfigName('paneltool'), + 'default' => 0, + 'values' => $soption, + 'hint' => $this->l('Whethere to display Panel Tool appearing on left of site.'), + 'form_group_class' => 'aprow_general', + 'desc' => $this->l('Yes : Auto load library JS jquery.cooki-plugin.js'), + ), + array( + 'type' => 'switch', + 'label' => $this->l('Enable Display Sub Category'), + 'name' => $this->getConfigName('subcategory'), + 'default' => 0, + 'values' => $soption, + 'hint' => $this->l('Whethere to display list of sub category in category page .'), + 'form_group_class' => 'aprow_general', + 'desc' => $this->l('Available with categories that have subcategories'), + ), + array( + 'type' => 'switch', + 'label' => $this->l('Enable Float Header'), + 'name' => $this->getConfigName('enable_fheader'), + 'default' => 0, + 'values' => $soption, + 'hint' => $this->l('Select NO when you don not want your header float'), + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Enable Back to Top'), + 'name' => $this->getConfigName('backtop'), + 'default' => 0, + 'values' => $soption, + 'hint' => $this->l('Show a Scroll To Top button.'), + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'select', + 'label' => $this->l('Default Skin'), + 'name' => $this->getConfigName('default_skin'), + 'default' => 'default', + 'options' => array( + 'query' => $skins, + 'id' => 'id', + 'name' => 'name' + ), + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'select', + 'label' => $this->l('Products Listing Mode'), + 'name' => $this->getConfigName('listing_grid_mode'), + 'default' => 'grid', + 'options' => array('query' => array( + array('id' => 'grid', 'name' => $this->l('Grid Mode')), + array('id' => 'list', 'name' => $this->l('List Mode')), + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('Display Products In List Mode Or Grid Mode In Product List....'), + 'form_group_class' => 'aprow_pages', + ), + array( + 'type' => 'select', + 'label' => $this->l('Columns in Default Module On Desktop'), + 'name' => $this->getConfigName('listing_product_column_module'), + 'default' => ' ', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '2', 'name' => $this->l('2 Columns')), + array('id' => '3', 'name' => $this->l('3 Columns')), + array('id' => '4', 'name' => $this->l('4 Columns')), + array('id' => '5', 'name' => $this->l('5 Columns')), + array('id' => '6', 'name' => $this->l('6 Columns')) + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many column display in default module of prestashop.'), + 'form_group_class' => 'aprow_pages', + ), + array( + 'type' => 'select', + 'label' => $this->l('Columns in Product List page On Desktop'), + 'name' => $this->getConfigName('listing_product_column'), + 'default' => ' ', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '2', 'name' => $this->l('2 Columns')), + array('id' => '3', 'name' => $this->l('3 Columns')), + array('id' => '4', 'name' => $this->l('4 Columns')), + array('id' => '5', 'name' => $this->l('5 Columns')), + array('id' => '6', 'name' => $this->l('6 Columns')) + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many column display in grid mode of product list.'), + 'form_group_class' => 'aprow_pages', + ), + array( + 'type' => 'select', + 'label' => $this->l('Product Grid Columns On Large devices (>=992px)'), + 'name' => $this->getConfigName('listing_product_largedevice'), + 'default' => ' ', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '2', 'name' => $this->l('2 Columns')), + array('id' => '3', 'name' => $this->l('3 Columns')), + array('id' => '4', 'name' => $this->l('4 Columns')), + array('id' => '5', 'name' => $this->l('5 Columns')), + array('id' => '6', 'name' => $this->l('6 Columns')) + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many column display in grid mode of product list.'), + 'form_group_class' => 'aprow_pages', + ), + array( + 'type' => 'select', + 'label' => $this->l('Product Grid Columns On Medium devices - Tablet (>=768px)'), + 'name' => $this->getConfigName('listing_product_tablet'), + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 Column')), + array('id' => '2', 'name' => $this->l('2 Columns')), + array('id' => '3', 'name' => $this->l('3 Columns')), + array('id' => '4', 'name' => $this->l('4 Columns')) + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many column display in grid mode of product list.'), + 'form_group_class' => 'aprow_pages', + ), + array( + 'type' => 'select', + 'label' => $this->l('Product Grid Columns On Small devices (>=576px)'), + 'name' => $this->getConfigName('listing_product_smalldevice'), + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 Column')), + array('id' => '2', 'name' => $this->l('2 Columns')), + array('id' => '3', 'name' => $this->l('3 Columns')) + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many column display in grid mode of product list.'), + 'form_group_class' => 'aprow_pages', + ), + array( + 'type' => 'select', + 'label' => $this->l('Product Grid Columns On Extra Small devices (<567px)'), + 'name' => $this->getConfigName('listing_product_extrasmalldevice'), + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 Column')), + array('id' => '2', 'name' => $this->l('2 Columns')) + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many column display in grid mode of product list.'), + 'form_group_class' => 'aprow_pages', + ), + array( + 'type' => 'select', + 'label' => $this->l('Product Grid Columns On Smart Phone (<480px)'), + 'name' => $this->getConfigName('listing_product_mobile'), + 'default' => '', + 'options' => array('query' => array( + array('id' => '', 'name' => $this->l('Default')), + array('id' => '1', 'name' => $this->l('1 Column')), + array('id' => '2', 'name' => $this->l('2 Columns')) + ), + 'id' => 'id', + 'name' => 'name'), + 'desc' => $this->l('How many column display in grid mode of product list.'), + 'form_group_class' => 'aprow_pages', + ), + + array( + 'type' => 'select', + 'label' => $this->l('Product Detail Tab Type'), + 'name' => $this->getConfigName('enable_ptab'), + 'default' => 'default', + 'options' => array('query' => array( + array('id' => 'default', 'name' => $this->l('Default')), + array('id' => 'tab', 'name' => $this->l('Tab')), + array('id' => 'accordion', 'name' => $this->l('Accordion')) + ), + 'id' => 'id', + 'name' => 'name'), +// 'desc' => $this->l('Select no when you don not want to use tab in product detail'), + 'form_group_class' => 'aprow_pages', + ), +// array( +// 'type' => 'switch', +// 'label' => $this->l('Enable Custom Font'), +// 'name' => $this->getConfigName('enable_customfont'), +// 'default' => 0, +// 'values' => $soption, +// 'form_group_class' => 'aprow_font', +// ), +// /* FONT 1 */ +// array( +// 'type' => 'text', +// 'label' => $this->l('Google Link'), +// 'name' => $this->getConfigName('engine1_google_link'), +// 'default' => '', +// 'identifier' => 'id', +// 'class' => 'localfont', +// 'desc' => $this->l('For Example: http://fonts.googleapis.com/css?family=Gorditas'), +// 'form_group_class' => 'aprow_font', +// ), +// array( +// 'type' => 'text', +// 'label' => $this->l('Google Font Family'), +// 'name' => $this->getConfigName('engine1_google_font'), +// 'default' => '', +// 'desc' => $this->l('For Example: "Gorditas", "cursive"'), +// 'identifier' => 'id', +// 'form_group_class' => 'aprow_font', +// ), +// array( +// 'type' => 'textarea', +// 'label' => $this->l('Css Selector'), +// 'name' => $this->getConfigName('font1_selector'), +// 'default' => '', +// 'rows' => '6', +// 'cols' => '', +// 'desc' => $this->l('Example: body, h1,h2,h3, #yourstyle, .myrule div'), +// 'form_group_class' => 'aprow_font', +// ), +// array( +// 'type' => 'html', +// 'name' => 'default_html', +// 'html_content' => '
    ', +// 'default' => '', +// 'form_group_class' => 'aprow_font', +// 'save' => false, +// ), +// /* FONT 2 */ +// array( +// 'type' => 'text', +// 'label' => $this->l('Google Link'), +// 'name' => $this->getConfigName('engine2_google_link'), +// 'default' => '', +// 'identifier' => 'id', +// 'class' => 'localfont', +// 'form_group_class' => 'aprow_font', +// ), +// array( +// 'type' => 'text', +// 'label' => $this->l('Google Font Family'), +// 'name' => $this->getConfigName('engine2_google_font'), +// 'default' => '', +// 'identifier' => 'id', +// 'form_group_class' => 'aprow_font', +// ), +// array( +// 'type' => 'textarea', +// 'label' => $this->l('Css Selector'), +// 'name' => $this->getConfigName('font2_selector'), +// 'default' => '', +// 'rows' => '6', +// 'cols' => '', +// 'form_group_class' => 'aprow_font', +// ), +// array( +// 'type' => 'html', +// 'name' => 'default_html', +// 'html_content' => '
    ', +// 'default' => '', +// 'form_group_class' => 'aprow_font', +// 'save' => false, +// ), +// /* FONT 3 */ +// array( +// 'type' => 'text', +// 'label' => $this->l('Google Link'), +// 'name' => $this->getConfigName('engine3_google_link'), +// 'default' => '', +// 'identifier' => 'id', +// 'class' => 'localfont', +// 'form_group_class' => 'aprow_font', +// ), +// array( +// 'type' => 'text', +// 'label' => $this->l('Google Font Family'), +// 'name' => $this->getConfigName('engine3_google_font'), +// 'default' => '', +// 'identifier' => 'id', +// 'form_group_class' => 'aprow_font', +// ), +// array( +// 'type' => 'textarea', +// 'label' => $this->l('Css Selector'), +// 'name' => $this->getConfigName('font3_selector'), +// 'default' => '', +// 'rows' => '6', +// 'cols' => '', +// 'form_group_class' => 'aprow_font', +// ), + array( + 'type' => 'font_setup', + 'name' => 'title', + 'values' => array(''), + 'list_google_font' => array_keys(GoogleFont::getAllGoogleFonts()), + 'default' => Tools::getValue('tab_open') ? Tools::getValue('tab_open') : 'aprow_general', + 'save' => false, + 'form_group_class' => 'aprow_font_setup', + ), + array( + 'type' => 'switch', + 'label' => $this->l('Enable Load Font'), + 'name' => $this->getConfigName('enable_loadfont'), + 'default' => 0, + 'values' => $soption, + 'form_group_class' => 'aprow_font_option', + ), + array( + 'type' => 'font_h', + 'htitle' => $this->l('H1 Typography'), + 'desc' => '', + 'hdesc' => $this->l('Specify the typography properties for headings.'), + 'name' => $this->getConfigName('font_h1'), + 'items' => array( + array( + 'type' => 'select', + 'label' => $this->l('Font Family'), + 'name' => $this->getConfigName('h1_font_family'), + 'default' => apPageHelper::getFontFamily('default'), + 'options' => array( + 'query' => apPageHelper::getFontFamily(), + 'id' => 'id', + 'name' => 'name'), + 'class' => 'chk_font_exist', + ), + array( + 'type' => 'text', + 'label' => $this->l('Font Size'), + 'name' => $this->getConfigName('h1_font_size'), + 'default' => '36', + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'text', + 'label' => $this->l('Line Height'), + 'name' => $this->getConfigName('h1_height'), + 'default' => '40', + 'desc' => $this->l('Number of pixel. You can input "auto" or "number", such as: 1170'), + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Weight'), + 'name' => $this->getConfigName('h1_font_weight'), + 'default' => $this->getFontWeight('default'), + 'options' => array( + 'query' => $this->getFontWeight(), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Style'), + 'name' => $this->getConfigName('h1_font_style'), + 'default' => $this->getFontStyle('default'), + 'options' => array( + 'query' => $this->getFontStyle(), + 'id' => 'id', + 'name' => 'name'), + ), +// array( +// 'type' => 'color', +// 'name' => $this->getConfigName('h1_font_color'), +// 'label' => $this->l('Font Color'), +// 'lang' => false, +// 'default' => '', +// 'class' => 'input-level2 temp_hpcolor', +// 'form_group_class' => 'row-level2', +// ), + ), + 'default' => '', + 'form_group_class' => 'aprow_font_option', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'aprow_font_option', + 'save' => false, + ), + array( + 'type' => 'font_h', + 'htitle' => $this->l('H2 Typography'), + 'desc' => '', + 'hdesc' => $this->l('Specify the typography properties for headings.'), + 'name' => $this->getConfigName('font_h2'), + 'items' => array( + array( + 'type' => 'select', + 'label' => $this->l('Font Family'), + 'name' => $this->getConfigName('h2_font_family'), + 'default' => apPageHelper::getFontFamily('default'), + 'options' => array( + 'query' => apPageHelper::getFontFamily(), + 'id' => 'id', + 'name' => 'name'), + 'class' => 'chk_font_exist', + ), + array( + 'type' => 'text', + 'label' => $this->l('Font Size'), + 'name' => $this->getConfigName('h2_font_size'), + 'default' => '30', + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'text', + 'label' => $this->l('Line Height'), + 'name' => $this->getConfigName('h2_height'), + 'default' => '40', + 'desc' => $this->l('Number of pixel. You can input "auto" or "number", such as: 1170'), + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Weight'), + 'name' => $this->getConfigName('h2_font_weight'), + 'default' => $this->getFontWeight('default'), + 'options' => array( + 'query' => $this->getFontWeight(), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Style'), + 'name' => $this->getConfigName('h2_font_style'), + 'default' => $this->getFontStyle('default'), + 'options' => array( + 'query' => $this->getFontStyle(), + 'id' => 'id', + 'name' => 'name'), + ), + ), + 'default' => '', + 'form_group_class' => 'aprow_font_option', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'aprow_font_option', + 'save' => false, + ), + array( + 'type' => 'font_h', + 'htitle' => $this->l('H3 Typography'), + 'desc' => '', + 'hdesc' => $this->l('Specify the typography properties for headings.'), + 'name' => $this->getConfigName('font_h3'), + 'items' => array( + array( + 'type' => 'select', + 'label' => $this->l('Font Family'), + 'name' => $this->getConfigName('h3_font_family'), + 'default' => apPageHelper::getFontFamily('default'), + 'options' => array( + 'query' => apPageHelper::getFontFamily(), + 'id' => 'id', + 'name' => 'name'), + 'class' => 'chk_font_exist', + ), + array( + 'type' => 'text', + 'label' => $this->l('Font Size'), + 'name' => $this->getConfigName('h3_font_size'), + 'default' => '24', + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'text', + 'label' => $this->l('Line Height'), + 'name' => $this->getConfigName('h3_height'), + 'default' => '40', + 'desc' => $this->l('Number of pixel. You can input "auto" or "number", such as: 1170'), + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Weight'), + 'name' => $this->getConfigName('h3_font_weight'), + 'default' => $this->getFontWeight('default'), + 'options' => array( + 'query' => $this->getFontWeight(), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Style'), + 'name' => $this->getConfigName('h3_font_style'), + 'default' => $this->getFontStyle('default'), + 'options' => array( + 'query' => $this->getFontStyle(), + 'id' => 'id', + 'name' => 'name'), + ), + ), + 'default' => '', + 'form_group_class' => 'aprow_font_option', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'aprow_font_option', + 'save' => false, + ), + array( + 'type' => 'font_h', + 'htitle' => $this->l('H4 Typography'), + 'desc' => '', + 'hdesc' => $this->l('Specify the typography properties for headings.'), + 'name' => $this->getConfigName('font_h4'), + 'items' => array( + array( + 'type' => 'select', + 'label' => $this->l('Font Family'), + 'name' => $this->getConfigName('h4_font_family'), + 'default' => apPageHelper::getFontFamily('default'), + 'options' => array( + 'query' => apPageHelper::getFontFamily(), + 'id' => 'id', + 'name' => 'name'), + 'class' => 'chk_font_exist', + ), + array( + 'type' => 'text', + 'label' => $this->l('Font Size'), + 'name' => $this->getConfigName('h4_font_size'), + 'default' => '18', + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'text', + 'label' => $this->l('Line Height'), + 'name' => $this->getConfigName('h4_height'), + 'default' => '28', + 'desc' => $this->l('Number of pixel. You can input "auto" or "number", such as: 1170'), + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Weight'), + 'name' => $this->getConfigName('h4_font_weight'), + 'default' => $this->getFontWeight('default'), + 'options' => array( + 'query' => $this->getFontWeight(), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Style'), + 'name' => $this->getConfigName('h4_font_style'), + 'default' => $this->getFontStyle('default'), + 'options' => array( + 'query' => $this->getFontStyle(), + 'id' => 'id', + 'name' => 'name'), + ), + ), + 'default' => '', + 'form_group_class' => 'aprow_font_option', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'aprow_font_option', + 'save' => false, + ), + array( + 'type' => 'font_h', + 'htitle' => $this->l('H5 Typography'), + 'desc' => '', + 'hdesc' => $this->l('Specify the typography properties for headings.'), + 'name' => $this->getConfigName('font_h5'), + 'items' => array( + array( + 'type' => 'select', + 'label' => $this->l('Font Family'), + 'name' => $this->getConfigName('h5_font_family'), + 'default' => apPageHelper::getFontFamily('default'), + 'options' => array( + 'query' => apPageHelper::getFontFamily(), + 'id' => 'id', + 'name' => 'name'), + 'class' => 'chk_font_exist', + ), + array( + 'type' => 'text', + 'label' => $this->l('Font Size'), + 'name' => $this->getConfigName('h5_font_size'), + 'default' => '14', + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'text', + 'label' => $this->l('Line Height'), + 'name' => $this->getConfigName('h5_height'), + 'default' => '20', + 'desc' => $this->l('Number of pixel. You can input "auto" or "number", such as: 1170'), + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Weight'), + 'name' => $this->getConfigName('h5_font_weight'), + 'default' => $this->getFontWeight('default'), + 'options' => array( + 'query' => $this->getFontWeight(), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Style'), + 'name' => $this->getConfigName('h5_font_style'), + 'default' => $this->getFontStyle('default'), + 'options' => array( + 'query' => $this->getFontStyle(), + 'id' => 'id', + 'name' => 'name'), + ), + ), + 'default' => '', + 'form_group_class' => 'aprow_font_option', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'aprow_font_option', + 'save' => false, + ), + array( + 'type' => 'font_h', + 'htitle' => $this->l('H6 Typography'), + 'desc' => '', + 'hdesc' => $this->l('Specify the typography properties for headings.'), + 'name' => $this->getConfigName('font_h6'), + 'items' => array( + array( + 'type' => 'select', + 'label' => $this->l('Font Family'), + 'name' => $this->getConfigName('h6_font_family'), + 'default' => apPageHelper::getFontFamily('default'), + 'options' => array( + 'query' => apPageHelper::getFontFamily(), + 'id' => 'id', + 'name' => 'name'), + 'class' => 'chk_font_exist', + ), + array( + 'type' => 'text', + 'label' => $this->l('Font Size'), + 'name' => $this->getConfigName('h6_font_size'), + 'default' => '12', + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'text', + 'label' => $this->l('Line Height'), + 'name' => $this->getConfigName('h6_height'), + 'default' => '20', + 'desc' => $this->l('Number of pixel. You can input "auto" or "number", such as: 1170'), + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Weight'), + 'name' => $this->getConfigName('h6_font_weight'), + 'default' => $this->getFontWeight('default'), + 'options' => array( + 'query' => $this->getFontWeight(), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Style'), + 'name' => $this->getConfigName('h6_font_style'), + 'default' => $this->getFontStyle('default'), + 'options' => array( + 'query' => $this->getFontStyle(), + 'id' => 'id', + 'name' => 'name'), + ), + ), + 'default' => '', + 'form_group_class' => 'aprow_font_option', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'aprow_font_option', + 'save' => false, + ), + array( + 'type' => 'font_h', + 'htitle' => $this->l('P Tag'), + 'desc' => '', + 'hdesc' => $this->l('Specify the typography properties for headings.'), + 'name' => $this->getConfigName('font_p'), + 'items' => array( + array( + 'type' => 'select', + 'label' => $this->l('Font Family'), + 'name' => $this->getConfigName('p_font_family'), + 'default' => apPageHelper::getFontFamily('default'), + 'options' => array( + 'query' => apPageHelper::getFontFamily(), + 'id' => 'id', + 'name' => 'name'), + 'class' => 'chk_font_exist', + ), + array( + 'type' => 'text', + 'label' => $this->l('Font Size'), + 'name' => $this->getConfigName('p_font_size'), + 'default' => '36', + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'text', + 'label' => $this->l('Line Height'), + 'name' => $this->getConfigName('p_height'), + 'default' => '40', + 'desc' => $this->l('Number of pixel. You can input "auto" or "number", such as: 1170'), + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Weight'), + 'name' => $this->getConfigName('p_font_weight'), + 'default' => $this->getFontWeight('default'), + 'options' => array( + 'query' => $this->getFontWeight(), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Style'), + 'name' => $this->getConfigName('p_font_style'), + 'default' => $this->getFontStyle('default'), + 'options' => array( + 'query' => $this->getFontStyle(), + 'id' => 'id', + 'name' => 'name'), + ), + ), + 'default' => '', + 'form_group_class' => 'aprow_font_option', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'aprow_font_option', + 'save' => false, + ), + array( + 'type' => 'font_h', + 'htitle' => $this->l('A Tag'), + 'desc' => '', + 'hdesc' => $this->l('Specify the typography properties for headings.'), + 'name' => $this->getConfigName('font_a'), + 'items' => array( + array( + 'type' => 'select', + 'label' => $this->l('Font Family'), + 'name' => $this->getConfigName('a_font_family'), + 'default' => apPageHelper::getFontFamily('default'), + 'options' => array( + 'query' => apPageHelper::getFontFamily(), + 'id' => 'id', + 'name' => 'name'), + 'class' => 'chk_font_exist', + ), + array( + 'type' => 'text', + 'label' => $this->l('Font Size'), + 'name' => $this->getConfigName('a_font_size'), + 'default' => '36', + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'text', + 'label' => $this->l('Line Height'), + 'name' => $this->getConfigName('a_height'), + 'default' => '40', + 'desc' => $this->l('Number of pixel. You can input "auto" or "number", such as: 1170'), + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Weight'), + 'name' => $this->getConfigName('a_font_weight'), + 'default' => $this->getFontWeight('default'), + 'options' => array( + 'query' => $this->getFontWeight(), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Style'), + 'name' => $this->getConfigName('a_font_style'), + 'default' => $this->getFontStyle('default'), + 'options' => array( + 'query' => $this->getFontStyle(), + 'id' => 'id', + 'name' => 'name'), + ), + ), + 'default' => '', + 'form_group_class' => 'aprow_font_option', + ), + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    ', + 'form_group_class' => 'aprow_font_option', + 'save' => false, + ), + array( + 'type' => 'font_h', + 'htitle' => $this->l('Span Tag'), + 'desc' => '', + 'hdesc' => $this->l('Specify the typography properties for headings.'), + 'name' => $this->getConfigName('font_span'), + 'items' => array( + array( + 'type' => 'select', + 'label' => $this->l('Font Family'), + 'name' => $this->getConfigName('span_font_family'), + 'default' => apPageHelper::getFontFamily('default'), + 'options' => array( + 'query' => apPageHelper::getFontFamily(), + 'id' => 'id', + 'name' => 'name'), + 'class' => 'chk_font_exist', + ), + array( + 'type' => 'text', + 'label' => $this->l('Font Size'), + 'name' => $this->getConfigName('span_font_size'), + 'default' => '36', + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'text', + 'label' => $this->l('Line Height'), + 'name' => $this->getConfigName('span_height'), + 'default' => '40', + 'desc' => $this->l('Number of pixel. You can input "auto" or "number", such as: 1170'), + 'form_group_class' => 'aprow_general', + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Weight'), + 'name' => $this->getConfigName('span_font_weight'), + 'default' => $this->getFontWeight('default'), + 'options' => array( + 'query' => $this->getFontWeight(), + 'id' => 'id', + 'name' => 'name'), + ), + array( + 'type' => 'select', + 'label' => $this->l('Font Style'), + 'name' => $this->getConfigName('span_font_style'), + 'default' => $this->getFontStyle('default'), + 'options' => array( + 'query' => $this->getFontStyle(), + 'id' => 'id', + 'name' => 'name'), + ), + ), + 'default' => '', + 'form_group_class' => 'aprow_font_option', + ), + array( + 'type' => 'modules_block', + 'label' => $this->l('Module List:'), + 'name' => 'moduleList', + 'values' => $moduleList, + 'exist_module' => $sample->existThemeConfigFile(), + 'default' => '', + 'form_group_class' => 'aprow_data', + 'save' => false, + 'folder_data_struct' => str_replace('\\', '/', _PS_MODULE_DIR_.'appagebuilder/install'), + ), + ), + 'submit' => array( + 'title' => $this->l('Save'), + ), + ); + + if (version_compare(Configuration::get('PS_VERSION_DB'), '1.7.3.0', '>=')) { + $fields_form['input']['config']['values']['aprow_rtl'] = $this->l('Righ to Left'); + + $fields_form['input'][] = + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '', + 'form_group_class' => 'aprow_rtl', + ); + + $fields_form['input'][] = + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '', + 'form_group_class' => 'aprow_rtl', + ); + + $fields_form['input'][] = + array( + 'type' => 'html', + 'name' => 'default_html', + 'html_content' => '
    '.$this->l('1. Generate RTL stylesheet : create file *_rtl.css in current theme like Prestashop default.') + .'
    ' .$this->l('2. Use class RTL of theme and delete all *_rtl.css file in current theme.').'
    ', + 'form_group_class' => 'aprow_rtl', + ); + } + + $theme_customizations = LeoFrameworkHelper::getLayoutSettingByTheme($this->themeName); + if (isset($theme_customizations['layout'])) { + foreach ($theme_customizations['layout'] as $key => $value) { + $o = array( + 'label' => $this->module->getTranslator()->trans((isset($value['title']) ? $value['title'] : $key)), + 'name' => $this->getConfigName(trim($key)), + 'default' => $value['default'], + 'type' => 'select', + 'options' => array( + 'query' => $value['option'], + 'id' => 'id', + 'name' => 'name' + ), + 'desc' => isset($value['desc']) ? $this->module->getTranslator()->trans($value['desc']) : null, + 'form_group_class' => 'aprow_general', + ); + array_push($fields_form['input'], $o); + } + } + + $this->fields_form = $fields_form; + $this->tpl_form_vars['backup_dir'] = $sample->backup_dir; + + if ($this->submitSaveSetting && Tools::isSubmit('submitAddconfiguration')) { + # SAVING CONFIGURATION + $this->saveThemeConfigs(); + $this->confirmations[] = 'Your configurations have been saved successfully.'; + } + return parent::renderForm(); + } + + public function postProcess() + { + if (count($this->errors) > 0) { + return; + } + $dataSample = new Datasample(); + if (Tools::isSubmit('submitBackup')) { + $dataSample->processBackUp(); + $folder = str_replace('\\', '/', _PS_CACHE_DIR_.'backup/themes/'); + $this->confirmations[] = 'Back-up to PHP file is successful.
    ' . $folder; + } else if (Tools::isSubmit('submitRestore')) { + $dataSample->restoreBackUpFile(); + $this->confirmations[] = 'Restore from PHP file is successful.'; + } else if (Tools::isSubmit('submitSample')) { + $dataSample->processSample(); + $folder = str_replace('\\', '/', _PS_ALL_THEMES_DIR_.apPageHelper::getThemeName().'/samples/'); + $this->confirmations[] = 'Export Sample Data is successful.
    ' . $folder; + } else if (Tools::isSubmit('submitImport')) { + $dataSample->processImport(); + $this->confirmations[] = 'Restore Sample Data is successful.'; + } else if (Tools::isSubmit('submitExportDBStruct')) { + $dataSample->exportDBStruct(); + $dataSample->exportThemeSql(); + $folder = str_replace('\\', '/', _PS_MODULE_DIR_.'appagebuilder/install'); + $this->confirmations[] = 'Export Data Struct is successful.
    ' . $folder; + } else if (Tools::isSubmit('submitUpdateModule')) { + apPageHelper::processCorrectModule(); + $this->confirmations[] = 'Update and Correct Module is successful.'; + } else if (Tools::isSubmit('submit_rtl_prestashop')) { + $this->generateRTL(); + $this->confirmations[] = apPageHelper::getThemeName() . ' theme generate RTL stylesheet'; + } else if (Tools::isSubmit('submit_rtl_leo')) { + $this->removeRTL(); + $this->confirmations[] = apPageHelper::getThemeName() . ' theme use class RTL of theme'; + } else if (Tools::isSubmit('submitAddconfiguration')) { + $this->saveThemeConfigsBefore(); + $this->submitSaveSetting = true; + } + } + + public function generateRTL() + { + $theme_name = apPageHelper::getThemeName(); + Language::getRtlStylesheetProcessor() + ->setProcessFOThemes(array($theme_name)) + ->setRegenerate(true) + ->process(); + } + + public function removeRTL() + { + $directory = _PS_ALL_THEMES_DIR_._THEME_NAME_; + $allFiles = Tools::scandir($directory, 'css', '', true); + + foreach ($allFiles as $key => $file) { + if (Tools::substr(rtrim($file, '.css'), -4) !== '_rtl') { + unset($allFiles[$key]); + } + } + # REMOVE FILE _rtl + foreach ($allFiles as $key => $file) { + unlink($directory . DIRECTORY_SEPARATOR . $file); + } + } + + public function saveThemeConfigsBefore() + { + //$helper = LeoFrameworkHelper::getInstance(); + + // SET COOKIE AGAIN + $theme_cookie_name = $this->getConfigName('PANEL_CONFIG'); + $arrayConfig = array('default_skin', 'layout_mode', 'header_style', 'enable_fheader', 'sidebarmenu'); + # Remove value in cookie + foreach ($arrayConfig as $value) { + unset($_COOKIE[$theme_cookie_name.'_'.$value]); + setcookie($theme_cookie_name.'_'.$value, '', 0, '/'); + } + + # WRITE LOAD GOOGLE FONT + if (apPageHelper::getPostConfig('enable_loadfont') == 1) { + $content_font = ''; + if ($gfont_items = Tools::getValue('gfont_items')) { + # LOAD FONT + foreach ($gfont_items as $gfont_items) { + $item = Tools::jsonDecode($gfont_items, true); + $gfont_name = str_replace(' ', '+', $item['gfont_name']); + unset($item['gfont_id']); + unset($item['gfont_name']); + $temp_font = $this->renderGoogleLinkFont($gfont_name, $item); + + if (!empty($content_font) && !empty($temp_font)) { + $content_font .= '|'. $temp_font; + } else { + $content_font .= $temp_font; + } + } + + # LOAD SUBSETS + $gfonts_subsets = Tools::getValue('gfonts_subsets'); + if (!empty($content_font) && $gfonts_subsets) { + $content_font .= '&'.implode(',', $gfonts_subsets); + } + + # LOAD ONE LINK + if (!empty($content_font)) { + $content_font = '@import url("//fonts.googleapis.com/css?family='.$content_font.'");' ."\n\n"; + } + } + + # WRITE ATTRIBUTE FONT + $content_font .= $this->renderCSSFont('h1'); + $content_font .= $this->renderCSSFont('h2'); + $content_font .= $this->renderCSSFont('h3'); + $content_font .= $this->renderCSSFont('h4'); + $content_font .= $this->renderCSSFont('h5'); + $content_font .= $this->renderCSSFont('h6'); + $content_font .= $this->renderCSSFont('p'); + $content_font .= $this->renderCSSFont('a'); + $content_font .= $this->renderCSSFont('span'); + LeoFrameworkHelper::writeToCache($this->themePath.apPageHelper::getCssDir(), 'fonts-cuttom2', $content_font, 'css'); + } + + # SAVING GOOGLE FONT + $gfont_items = Tools::getValue('gfont_items'); + if ($gfont_items) { + $str_gfont_items = implode('__________', $gfont_items); + Configuration::updateValue($this->getConfigName('google_font'), $str_gfont_items); + } else { + Configuration::updateValue($this->getConfigName('google_font'), ''); + } + + # SAVING SUBSET + $gfonts_subsets = Tools::getValue('gfonts_subsets'); + if ($gfonts_subsets) { + $gfonts_subsets = implode(',', $gfonts_subsets); + Configuration::updateValue($this->getConfigName('google_subset'), $gfonts_subsets); + } else { + Configuration::updateValue($this->getConfigName('google_subset'), ''); + } + } + + /** + * alias from apPageHelper::getConfigName() + */ + public function getConfigName($name) + { + return apPageHelper::getConfigName($name); + } + + /** + * Update Theme Configurations + */ + public function saveThemeConfigs() + { + $languages = Language::getLanguages(false); + $content_setting = ''; + //$content_font = ''; + //$helper = LeoFrameworkHelper::getInstance(); + + foreach ($this->fields_form['input'] as $input) { + if (isset($input['lang'])) { + $data = array(); + foreach ($languages as $lang) { + $value = Tools::getValue(trim($input['name']).'_'.$lang['id_lang']); + $data[$lang['id_lang']] = $value ? $value : $input['default']; + } + + if ($input['name'] == Tools::strtoupper($this->themeName).'_COPYRIGHT') { + Configuration::updateValue(trim($input['name']), $data, true); + } else { + Configuration::updateValue(trim($input['name']), $data); + } + } else if ($input['type'] == 'font_h') { + foreach ($input['items'] as $item) { + if (isset($item['name'])) { +// $value = Tools::getValue($item['name'], Configuration::get($item['name'])); +// $item['default'] = isset($item['default']) ? $item['default'] : ''; +// $dataSave = $value ? $value : $item['default']; +// Configuration::updateValue(trim($item['name']), $dataSave); + $value = Tools::getValue($item['name'], Configuration::get($item['name'])); + Configuration::updateValue(trim($item['name']), $value); + } + } + } else { + $value = Tools::getValue($input['name'], Configuration::get($input['name'])); + $input['default'] = isset($input['default']) ? $input['default'] : ''; + $dataSave = $value ? $value : $input['default']; + + if (isset($input['save']) && $input['save']== false) { + // NOT SAVE + } else if ($input['type'] == 'font_h') { + // NOT SAVE + } else { + Configuration::updateValue(trim($input['name']), $dataSave); + } + if ($input['name'] == $this->getConfigName('move_end_header') && $value == 1) { + apPageHelper::moveEndHeader(); + } + if (trim($input['name']) == $this->getConfigName('listing_grid_mode')) { + if (trim($dataSave) == '') { + $dataSave = 'grid'; + } + $content_setting .= '{assign var="LISTING_GRID_MODE" value="'.$dataSave.'" scope="global"}'."\n"; + } elseif (trim($input['name']) == $this->getConfigName('listing_product_column')) { + if (trim($dataSave) == '') { + $dataSave = '3'; + } + $content_setting .= '{assign var="LISTING_PRODUCT_COLUMN" value="'.$dataSave.'" scope="global"}'."\n"; + } elseif (trim($input['name']) == $this->getConfigName('listing_product_largedevice')) { + if (trim($dataSave) == '') { + $dataSave = '3'; + } + $content_setting .= '{assign var="LISTING_PRODUCT_LARGEDEVICE" value="'.$dataSave.'" scope="global"}'."\n"; + } elseif (trim($input['name']) == $this->getConfigName('listing_product_tablet')) { + if (trim($dataSave) == '') { + $dataSave = '2'; + } + $content_setting .= '{assign var="LISTING_PRODUCT_TABLET" value="'.$dataSave.'" scope="global"}'."\n"; + } elseif (trim($input['name']) == $this->getConfigName('listing_product_smalldevice')) { + if (trim($dataSave) == '') { + $dataSave = '2'; + } + $content_setting .= '{assign var="LISTING_PRODUCT_SMALLDEVICE" value="'.$dataSave.'" scope="global"}'."\n"; + } elseif (trim($input['name']) == $this->getConfigName('listing_product_extrasmalldevice')) { + if (trim($dataSave) == '') { + $dataSave = '2'; + } + $content_setting .= '{assign var="LISTING_PRODUCT_EXTRASMALLDEVICE" value="'.$dataSave.'" scope="global"}'."\n"; + } elseif (trim($input['name']) == $this->getConfigName('listing_product_mobile')) { + if (trim($dataSave) == '') { + $dataSave = '1'; + } + $content_setting .= '{assign var="LISTING_PRODUCT_MOBILE" value="'.$dataSave.'" scope="global"}'."\n"; + } elseif (trim($input['name']) == $this->getConfigName('listing_product_column_module')) { + if (trim($dataSave) == '') { + $dataSave = '4'; + } + $content_setting .= '{assign var="LISTING_PRODUCT_COLUMN_MODULE" value="'.$dataSave.'" scope="global"}'."\n"; + } elseif (trim($input['name']) == $this->getConfigName('enable_responsive')) { + # validate module + $content_setting .= '{assign var="ENABLE_RESPONSIVE" value="'.$dataSave.'" scope="global"}'."\n"; + } + } + } + + $folder = $this->themePath.'templates/layouts/'; + if (!is_dir($folder)) { + mkdir($folder, 0755, true); + } + LeoFrameworkHelper::writeToCache($this->themePath.'templates/layouts/', 'setting', $content_setting, 'tpl'); + } + + public function renderGoogleLinkFont($gfont_name, $attribute) + { + $output = ''; + if (is_array($attribute) && $attribute) { + $str_att = ''; + foreach ($attribute as $value) { + $str_att .= ','.$value; + } + $str_att = trim($str_att, ','); + + $output = $gfont_name . ':' . $str_att; + } else { + $output = $gfont_name; + } + + return $output; + } + + public function renderCSSFont($tag) + { + $html = ''; + if (apPageHelper::getPostConfig($tag . '_font_family')) { + $html .= ' font-family:' . apPageHelper::getPostConfig($tag . '_font_family') . ';'; + } + if ((int)apPageHelper::getPostConfig($tag . '_font_size')) { + $html .= ' font-size:' . (int)apPageHelper::getPostConfig($tag . '_font_size') . 'px;'; + } + if ((int)apPageHelper::getPostConfig($tag . '_height')) { + $html .= ' height:' . (int)apPageHelper::getPostConfig($tag . '_height') . 'px;'; + } + if ((int)apPageHelper::getPostConfig($tag . '_font_weight')) { + $html .= ' font-weight:' . (int)apPageHelper::getPostConfig($tag . '_font_weight') . ';'; + } + if (apPageHelper::getPostConfig($tag . '_font_style')) { + $html .= ' font-style:' . apPageHelper::getPostConfig($tag . '_font_style') . ';'; + } + + $output = ''; + if (!empty($html)) { + $output = $tag . ' {'.$html.' }'."\n"; + } + + return $output; + } + + public function getFieldsValue($obj) + { + unset($obj); + $languages = Language::getLanguages(false); + $fields_values = array(); + + foreach ($this->fields_form as $f) { + foreach ($f['form']['input'] as $input) { + if (isset($input['lang'])) { + foreach ($languages as $lang) { + $v = Tools::getValue($input['name'], Configuration::get($input['name'], $lang['id_lang'])); + $input['default'] = isset($input['default']) ? $input['default'] : ''; + $fields_values[$input['name']][$lang['id_lang']] = $v ? $v : $input['default']; + } + } else if ($input['type'] == 'font_h') { + if ($input['type'] == 'font_h') { + foreach ($input['items'] as $item) { + if (isset($item['name'])) { +// $item_value = Tools::getValue($item['name'], Configuration::get($item['name'])); +// $fields_values[ $input['name'] ][ $item['name'] ] = $item_value ? $item_value : $item['default']; + $item_value = Tools::getValue($item['name'], Configuration::get($item['name'])); + $fields_values[ $input['name'] ][ $item['name'] ] = $item_value; + } + } + } + } else { + $v = Tools::getValue($input['name'], Configuration::get($input['name'])); + $input['default'] = isset($input['default']) ? $input['default'] : ''; + $fields_values[$input['name']] = $v ? $v : $input['default']; + } + } + } + // Font setup : list fonts in google + $fields_values['gfont_api'] = Tools::jsonEncode(GoogleFont::getAllGoogleFonts()); + + // Font setup : list fonts in database + $google_font_cfg = Configuration::get($this->getConfigName('google_font')); + $fields_values['gfont_list_ori'] = '[]'; + if ($google_font_cfg) { + $google_fonts = explode('__________', $google_font_cfg); + foreach ($google_fonts as &$font) { + $font = Tools::jsonDecode($font, true); + } + $fields_values['gfont_list'] = $google_fonts; + $fields_values['gfont_list_ori'] = Tools::jsonEncode($google_fonts); + } + + // Font setup : list subset in database + $google_subset_cfg = Configuration::get($this->getConfigName('google_subset')); + $fields_values['gfont_subset'] = '[]'; + if ($google_subset_cfg) { + $google_subset = explode(',', $google_subset_cfg); + $fields_values['gfont_subset'] = Tools::jsonEncode($google_subset); + } + + return $fields_values; + } + + public function getGoogleFont() + { + return array_keys(GoogleFont::getAllGoogleFonts()); + } + + public function getFontWeight($default = false) + { + if ($default == 'default') { + return ''; + } + $result = array( + array( 'id' => '', 'name' => '----- Select -----'), + array( 'id' => '400', 'name' => '400 (Normal)'), + array( 'id' => '700', 'name' => '700 (Bold)'), + array( 'id' => '100', 'name' => '100'), + array( 'id' => '200', 'name' => '200'), + array( 'id' => '300', 'name' => '300'), + array( 'id' => '500', 'name' => '500'), + array( 'id' => '600', 'name' => '600'), + array( 'id' => '800', 'name' => '800'), + array( 'id' => '900', 'name' => '900'), + ); + return $result; + } + + public function getFontStyle($default = false) + { + if ($default == 'default') { + return ''; + } + $result = array( + array( 'id' => '', 'name' => '----- Select -----'), + array( 'id' => 'normal', 'name' => 'Normal'), + array( 'id' => 'italic', 'name' => 'Italic'), + ); + return $result; + } +} diff --git a/modules/appagebuilder/controllers/admin/AdminApPageBuilderThemeEditor.php b/modules/appagebuilder/controllers/admin/AdminApPageBuilderThemeEditor.php new file mode 100644 index 00000000..27e8c776 --- /dev/null +++ b/modules/appagebuilder/controllers/admin/AdminApPageBuilderThemeEditor.php @@ -0,0 +1,225 @@ + + * @copyright 2007-2015 Apollotheme + * @license http://apollotheme.com - prestashop template provider + */ + +if (!defined('_PS_VERSION_')) { + # module validation + exit; +} + +class AdminApPageBuilderThemeEditorController extends ModuleAdminControllerCore +{ + public $themeName = ''; + public $css_patterns; + + public function __construct() + { + $this->bootstrap = true; + $this->table = 'appagebuilder_themeeditor'; + $this->lang = false; + $this->context = Context::getContext(); + parent::__construct(); + $this->themeName = _THEME_NAME_; + $this->js_patterns = _PS_THEME_DIR_.apPageHelper::getJsDir().'patterns/'; + $this->css_patterns = _PS_THEME_DIR_.apPageHelper::getCssDir().'patterns/'; + } + + public function postProcess() + { + if (count($this->errors) > 0) { + return; + } + + if (Tools::getValue('action') && Tools::getValue('action') == 'savedata' && Tools::getValue('customize')) { + $data = LeoFrameworkHelper::getPost(array('action-mode', 'saved_file', 'newfile', 'customize', 'customize_match', 'active'), 0); + + $selectors = $data['customize']; + $matches = $data['customize_match']; + + $output = ''; + + $cache = array(); + foreach ($selectors as $match => $customizes) { + $output .= "\r\n/* customize for $match */ \r\n"; + foreach ($customizes as $key => $customize) { + if (isset($matches[$match]) && isset($matches[$match][$key])) { + $tmp = explode('|', $matches[$match][$key]); + $attribute = Tools::strtolower(trim($tmp[1])); + if (trim($customize)) { + $output .= $tmp[0].' { '; + if ($attribute == 'background-image') { + $output .= $attribute.':url('.$customize.')'; + } elseif ($attribute == 'font-size') { + $output .= $attribute.':'.$customize.'px'; + } else if (strpos($attribute, 'color') !== false) { + $output .= $attribute.':#'.$customize; + } else if ($attribute == 'background') { + $output .= $attribute.':#'.$customize; + } else { + $output .= $attribute.':'.$customize; + } + $output .= "} \r\n"; + } + $cache[$match][] = array('val' => $customize, 'selector' => $tmp[0], 'attr' => $tmp[1]); + } + } + } + + # RENAME + if (!empty($data['saved_file']) && !empty($data['newfile'])) { + # DELETE PATTERN + if (isset($data['saved_file']) && $data['saved_file'] && file_exists($this->css_patterns.$data['saved_file'].'.css')) { + unlink($this->css_patterns.$data['saved_file'].'.css'); + } + if (isset($data['saved_file']) && $data['saved_file'] && file_exists($this->css_patterns.$data['saved_file'].'.json')) { + unlink($this->css_patterns.$data['saved_file'].'.json'); + } + } + + + if (empty($data['newfile'])) { + # EDIT PATTERN + $nameFile = $data['saved_file'] ? $data['saved_file'] : 'profile-'.time(); + } else { + # CREATE PATTERN + $nameFile = preg_replace('#\s+#', '-', trim($data['newfile'])); + } + + if ($data['action-mode'] != 'save-delete') { + # CREATE + EDIT + if (!is_dir($this->css_patterns)) { + mkdir($this->css_patterns, 0755, true); + } + + if (!empty($output)) { + LeoFrameworkHelper::writeToCache($this->css_patterns, $nameFile, $output); + } + if (!empty($cache)) { + LeoFrameworkHelper::writeToCache($this->css_patterns, $nameFile, Tools::jsonEncode($cache), 'json'); + } + + if (isset($data['active']) && $data['active']) { + # SET ACTIVE - YES + apPageHelper::setConfig('C_PROFILE', $nameFile); + } elseif (isset($data['active']) && empty($data['active'])) { + # SET ACTIVE - NO + $pattern_active = apPageHelper::getConfig('C_PROFILE'); + if ($nameFile == $pattern_active) { + apPageHelper::setConfig('C_PROFILE', ''); + } + } + } else { + # SET ACTIVE - NO + $pattern_active = apPageHelper::getConfig('C_PROFILE'); + if ($data['saved_file'] == $pattern_active) { + apPageHelper::setConfig('C_PROFILE', ''); + } + # DELETE PATTERN + if (isset($data['saved_file']) && $data['saved_file'] && file_exists($this->css_patterns.$data['saved_file'].'.css')) { + unlink($this->css_patterns.$data['saved_file'].'.css'); + } + if (isset($data['saved_file']) && $data['saved_file'] && file_exists($this->css_patterns.$data['saved_file'].'.json')) { + unlink($this->css_patterns.$data['saved_file'].'.json'); + } + } + Tools::redirectAdmin(self::$currentIndex.'&token='.$this->token); + } + } + + /** + * get list of files inside folder path. + */ + private function getFileList($path, $e = null, $nameOnly = false) + { + $output = array(); + $directories = glob($path.'*'.$e); + if ($directories) { + foreach ($directories as $dir) { + $dir = basename($dir); + if ($nameOnly) { + $dir = str_replace($e, '', $dir); + } + $output[$dir] = $dir; + } + } + return $output; + } + + /** + * render list of modules following positions in the layout editor. + */ + public function renderList() + { + $filePath = _PS_ALL_THEMES_DIR_.$this->themeName.''; + + $xml = simplexml_load_file($filePath.'/config.xml'); + + if (!isset($xml->theme_key) || empty($xml->theme_key)) { + return '
    '.'This function is only avariable using for Theme from leotheme.com or using theme built-in Leo Framework'.'
    '; + } + + $tpl = $this->createTemplate('themeeditor.tpl'); + Context::getContext()->controller->addCss(apPageHelper::getCssAdminDir().'admin/themeeditor.css'); + Context::getContext()->controller->addCss(apPageHelper::getCssAdminDir().'colorpicker/css/colorpicker.css'); + Context::getContext()->controller->addCss(apPageHelper::getCssAdminDir().'paneltool.css'); + + Context::getContext()->controller->addJs(apPageHelper::getJsAdminDir().'colorpicker/js/colorpicker.js'); + Context::getContext()->controller->addJs(apPageHelper::getJsAdminDir().'admin/themeeditor.js'); + + + + $output = LeoFrameworkHelper::renderEdtiorThemeForm($this->themeName); + + $profiles = $this->getFileList($this->css_patterns, '.css', true); + $patterns = $this->getFileList(_PS_ALL_THEMES_DIR_.$this->themeName.'/assets/img/patterns/', '.png'); + $patternsjpg = $this->getFileList(_PS_ALL_THEMES_DIR_.$this->themeName.'/assets/img/patterns/', '.jpg'); + + $patterns = array_merge($patterns, $patternsjpg); + $backGroundValue = array( + 'attachment' => array('scroll', 'fixed', 'local', 'initial', 'inherit'), + 'repeat' => array('repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'initial', 'inherit'), + 'position' => array('left top', 'left center', 'left bottom', 'right top', 'right center', 'right bottom', 'center top', 'center center', 'center bottom') + ); + $siteURL = _PS_BASE_URL_.__PS_BASE_URI__; + $imgLink = Context::getContext()->link->getAdminLink('AdminApPageBuilderImages').'&leo_controller=live_theme_edit'; // URL LOAD IMAGE BUTTON + $backgroundImageURL = _PS_BASE_URL_._THEME_DIR_.'assets/img/patterns/'; + + $ssl_enable = Configuration::get('PS_SSL_ENABLED'); + if ($ssl_enable) { + $siteURL = str_replace('http:', 'https:', $siteURL); + $imgLink = str_replace('http:', 'https:', $imgLink); + $backgroundImageURL = str_replace('http:', 'https:', $backgroundImageURL); + } + + $tpl->assign(array( + 'actionURL' => 'index.php?tab=AdminApPageBuilderThemeEditor&token='.Tools::getAdminTokenLite('AdminApPageBuilderThemeEditor').'&action=savedata', + 'text_layout' => $this->l('Layout'), + 'text_elements' => $this->l('Elements'), + 'profiles' => $profiles, + 'profiles_active' => apPageHelper::getConfig('c_profile'), + 'xmlselectors' => $output, + 'apPageHelper' => apPageHelper::getInstance(), + 'themeName' => $this->themeName, + 'patterns' => $patterns, + 'backgroundImageURL' => $backgroundImageURL, + 'siteURL' => $siteURL, + 'customizeFolderURL' => _PS_THEME_URI_.apPageHelper::getCssDir().'patterns/', + 'backLink' => 'index.php?controller=AdminModules&configure=appagebuilder&token='.Tools::getAdminTokenLite('AdminModules'), + 'imgLink' => $imgLink, + 'backGroundValue' => $backGroundValue + )); + + return $tpl->fetch(); + } +} diff --git a/modules/appagebuilder/controllers/admin/index.php b/modules/appagebuilder/controllers/admin/index.php new file mode 100644 index 00000000..6bf70e95 --- /dev/null +++ b/modules/appagebuilder/controllers/admin/index.php @@ -0,0 +1,36 @@ + +* @copyright 2007-2012 PrestaShop SA +* @version Release: $Revision: 13573 $ +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/modules/appagebuilder/controllers/front/appagebuilderhome.php b/modules/appagebuilder/controllers/front/appagebuilderhome.php new file mode 100644 index 00000000..2ba9f601 --- /dev/null +++ b/modules/appagebuilder/controllers/front/appagebuilderhome.php @@ -0,0 +1,54 @@ + + * .All rights reserved. + * @license GNU General Public License version 2 + */ + +class ApPageBuilderApPagebuilderHomeModuleFrontController extends FrontController +{ + public function __construct() + { + parent::__construct(); + $this->display_column_left = false; + $this->display_column_right = false; + } + + public function initContent() + { + parent::initContent(); + $this->addJS(_THEME_JS_DIR_.'index.js'); + + $this->context->smarty->assign(array( + 'HOOK_HOME' => Hook::exec('displayHome'), + 'HOOK_HOME_TAB' => Hook::exec('displayHomeTab'), + 'HOOK_HOME_TAB_CONTENT' => Hook::exec('displayHomeTabContent') + )); + $this->display_column_left = false; + $this->display_column_right = false; + $this->context->smarty->assign(array( + 'page_name' => 'index', + )); + $this->setTemplate('index.tpl'); + } + + /** + * set html +* @copyright 2007-2012 PrestaShop SA +* @version Release: $Revision: 13573 $ +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/modules/appagebuilder/controllers/index.php b/modules/appagebuilder/controllers/index.php new file mode 100644 index 00000000..6bf70e95 --- /dev/null +++ b/modules/appagebuilder/controllers/index.php @@ -0,0 +1,36 @@ + +* @copyright 2007-2012 PrestaShop SA +* @version Release: $Revision: 13573 $ +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/modules/appagebuilder/css/ApImage360.css b/modules/appagebuilder/css/ApImage360.css new file mode 100644 index 00000000..cb5d993d --- /dev/null +++ b/modules/appagebuilder/css/ApImage360.css @@ -0,0 +1,419 @@ +/* Core */ +.LeoImage360, +.LeoImage360-container { +/* border: 1px solid #f1f1f1; +border: 1px solid rgba(0, 0, 0, 0.05); */ +} +.LeoImage360-container .LeoImage360, +.LeoImage360-fullscreen .LeoImage360 { + border: 0 !important; +} +.LeoImage360 { + padding: 0 !important; + outline: 0 !important; + display: inline-block; + font-size: 0 !important; + line-height: 100% !important; + max-width: 100%; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +.LeoImage360.m360-spin-x { + touch-action: pan-y; +} +.LeoImage360.m360-spin-y { + touch-action: pan-x; +} +.LeoImage360.desktop.zoom-in { + cursor: pointer; + cursor: -webkit-zoom-in; + cursor: -moz-zoom-in; + cursor: zoom-in; +} + +.LeoImage360 img { + border: 0 !important; + padding: 0 !important; + margin: 0 !important; + height: auto; +} + +.LeoImage360 > img { + width: 100%; +} + +/* Fullscreen icons */ +button.m360-icon { + color: #b4b4b4 !important; + font: normal 900 30px/1 'leoimage360' !important; + cursor: pointer; + z-index: 1000000 !important; + background-color: transparent !important; + border: 1px solid rgba(180, 180, 180, 0) !important; + border-radius: 0 !important; + box-shadow: none !important; + position: absolute !important; + text-transform: none !important; + text-align: center; + speak: none; + width: 44px !important; + height: 44px !important; + min-width: 0 !important; + min-height: 0 !important; + max-width: none !important; + max-height: none !important; + margin: 0 !important; + padding: 0 !important; + outline: 0 !important; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +button.m360-icon:hover, +.mobile-leoimage button.m360-icon:active { + color: #555 !important; + color: rgba(49, 51, 61, 0.76) !important; +} +button.m360-icon:before { + display: inline !important; + position: static !important; + color: inherit !important; + font: inherit !important; + -webkit-font-smoothing: inherit !important; + -moz-osx-font-smoothing: inherit !important; +} +button.m360-icon.m360-icon-fullscreen-open, +button.m360-icon.m360-icon-fullscreen-close { + top: 0 !important; + right: 0 !important; +} +button.m360-icon.m360-icon-fullscreen-close { + width: 60px !important; + height: 60px !important; +} +button.m360-icon.m360-icon-fullscreen-open:before { content: '\e800'; } +button.m360-icon.m360-icon-fullscreen-close:before { content: '\e801'; } + +.lt-ie9-leoimage button.m360-icon { + border: 0; + filter: alpha(opacity=75); +} +.lt-ie9-leoimage button.m360-icon:hover { + filter: alpha(opacity=100); +} + + +.LeoImage360-fullscreen:-webkit-full-screen { + touch-action: none; +} +.LeoImage360-container { + text-align: center !important; + max-width: 100%; + position: relative; + z-index: 1; +} +.LeoImage360-container .LeoImage360 { + display: inline-block !important; + vertical-align: middle; +} +.lt-ie7-leoimage .LeoImage360-container .LeoImage360 { + width: auto !important; +} + +.LeoImage360-fullscreen { + background: #fff; + z-index: 2147483640 !important; +} +.LeoImage360-fullscreen:-webkit-full-screen { + width: 100% !important; + height: 100% !important; + top: 0 !important; + left: 0 !important; + -webkit-backface-visibility: hidden !important; + backface-visibility: hidden !important; +} +.LeoImage360-fullscreen:-ms-fullscreen { + width: 100% !important; + height: 100% !important; + top: 0 !important; + left: 0 !important; +} + +.LeoImage360-fullscreen:before { + content: ''; + display: inline-block; + height: 100%; + vertical-align: middle; +} + +.LeoImage360-fullscreen .LeoImage360 { + display: inline-block !important; + vertical-align: middle; +} + +.LeoImage360-message { + background-color: #FFFFFF; + background-image: none; + border: 1px solid #AAAAAA; + display: block; + font-size: 10px; + color: #000; + overflow: hidden; + padding: 6px; + position: absolute; + text-align: center; + top: 50%; + width: 33%; + left: 33%; + z-index: 100; + box-shadow: 0 0 10px #000; + border-collapse: separate; + border-radius: 15px; +} + +.LeoImage360-fullscreen .LeoImage360-message { + font-size: 18px; + background-color: #31333D; + background-color: rgba(49, 51, 61, 0.76); + border-color: #ccc; + color: #fff; + top: 15px; +} + + +/** + * Hint & Loader + */ +.m360-hint-message, +.m360-loader { + background: rgba(49, 51, 61, 0.76); + color: #fff; + font: normal 14px/1.2em 'Lucida Grande', 'Lucida Sans Unicode', Verdana, 'Helvetica Neue', Arial, Helvetica, sans-serif; + text-decoration: none; +} +.m360-hint, +.m360-loader { + direction: ltr; + text-align: center; + display: inline-block; + margin: 0; + position: absolute; + z-index: 1000; + pointer-events: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-transition: opacity 0.25s ease; + transition: opacity 0.25s ease; +} +.m360-hint { + bottom: 8px; + left: 0; + right: 0; + padding: 0 10%; + -webkit-transition: opacity 0.25s ease, z-index 0.25s ease; + transition: opacity 0.25s ease, z-index 0.25s ease; +} +.m360-hint-message { + display: inline-block; + border-radius: 2em; + padding: .3em 1.5em; + font-size: 14px; + line-height: 1.5; +} +.m360-hint-message:before { + content: ''; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAAqCAYAAAB4Ip8uAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpGOTA1M0E3QjA4QzdFMzExOTUxQjhCNzcwMDhDQjMwOCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxQjhDODMzNkM3MEIxMUUzQkMzNEJCQzI2OUFGMUNCQSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxQjhDODMzNUM3MEIxMUUzQkMzNEJCQzI2OUFGMUNCQSIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGQTA1M0E3QjA4QzdFMzExOTUxQjhCNzcwMDhDQjMwOCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpGOTA1M0E3QjA4QzdFMzExOTUxQjhCNzcwMDhDQjMwOCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pq6mNcIAAAqiSURBVHja7Fx9aFXnGb/nfn/kfie2SqqpC9ugq/YDnGWF2nasmj8qOP9whemGoxQHlox2KOyv+rEwkO4TJmMQKaTUBqltsOoigRBaWUiNdjFzmdFYjSR3JkZjkpuPe/f8Tp9X3p6ec+8599wbt5v7wsv9ft/nPN/P73nPVbLZrKMyyne4zX5RUZSSEVHuSlYq3pnhm7Oi4xULNq2oWgWrsNcS7xQN77L/KwJW2BO4aHr49RzNeZqZiqDz8k7wTfAOfJulucD8szWcRRKun2bVyZMnH+vr63uxvr4+gtesQEpFjjmFG9i2bVv8+vXrr4yNjb0JHjLvPEUJoQjUZqbBAIEhInDF1NTUsSyP+fn5wba2tqfps6gZIZul4f915uBd+PDhw9+em5vrE7zLZDLTly9ffoU+i9P05uKdqb1tEKkwAfHJycl3INfZ2dleekyD0IWFhau7du16BAqQTxOXoIDBOx94NzMz00m8+oJ42EyGMcBCniRLXgcFYEV4IAJWNbC/v38LEZRqb29/hl5X45EIHgGhd+7c+TO9lyiGJpaZgOHVIlevXt1J1vvPffv2fYNe18AgyEh6wDsS/Cl6L8mKoBQsYBvxwys0cGho6FUWJGJv9ZUrV34i3M2hQ4e+yZpYUDwuQwEL602QcC+cO3eugd0xPF2is7PzOXhD8K+jo+NZ5p1zsQWMDUOwVmggC9fPQgRB1SKupFKpt6CdLHyPVSGXoYDBu6qzZ88+T9b6d4l3Ln5MTk9Pt7EH/At/7llsAasuBsIbHR3dKyVTID6MBAvEiViM+MKCrio3cKUAJoNPsYmJibdv3rz5Biu+Wwp7MSRZzLsv2E379QyjlAJW3TPiRUtLyxp6HmTBOdltn8pqBpUBr+VyN0tIwIJ3vRreCfetViUIb5Kb1jWMUglYdc+bN29GQvBvev4QC87PM06p/+NE4ISc+nNGHVyEulgLvHh5+jRTvO/h7zpLlSNoaEPdu4JDW1wnicLrJNw3eMdWHtPLposlYBlt8XEy8NDx48dfHh8f/4ie17GQ4xwvltFcQRb7CyHge/futXIcDvI6bl5TKZJAZfoCrPERZkyMadOb4nMBzAR4DdP0WWSyahw9PT0vTU1NHee9vZolcR0JVCDgHUpQozhsZm+3SUvwiix49+7diYaGhu+uWbNmq6Ioj1y7du0PyWRypcfjUa+E4sZsY2PjT2tra1tIC7fQ+98jYbfymn5mYFYHksvasNT79O3Zsye6Y8eOp6LR6KpIJPIdp9MZd7vdq/UWACBD3mWcmPkPiolDR44c+aypqWmiSPQZ0rx8+fJvURj7nNfM6GD4GRLspXA47PB6vY/qYNW2sGiZcWp2d/78+Wfr6uo2hkKhTSRA/8jISK/P5wsTEf/q6uo6QgTPBAKBzPr163tB4N69e2HF6dOnT7++adOmDzZu3NiBdcmSD9PvnqbHNqoB/7Z27douZuCMBUbmpI+Uzp9Op7uJtm4IjhSwV/yQ6XNQBvuEeG/lypVPkAKEVq1atePAgQN/3L9//4xN+vLS7vf7aylTHjJoKmCPDBSO+OpwuVy1Bs2cgglwsxuOd3d3fx+JFEqeGzdu/JyTArjjulu3br1/5syZH9Hzh9nFhdg6PVLsCzNkKT6PYQ2shTWxNvaQ6sB8tbIZ+hK8XlRyvVX8G5EnhKT3I/xdNcRYpc+iiwZfYqR8LX19fZsNkiesX4USVCC/9fX1NUy37Rislj/ARylGvA/obHBw8MfMtChfJBKqZaSBZ44dO/YME+nScSOK5D5dUpwMMFMTWBvJBvbCnpqSwbA8y0OfT3LZLim7VzTTKXkCt5SIhazQZ5HJ2CNGvPuYs+OggYCDAIhEDkNhp475ZkvAcoZ3ATUYo1BxCcRwCgyVtPtTtpiABfchGOsWGTf2wF7YE3vnWM8sfYpNlMkSfQUIGGVkO3u2kMG1BiBUIeDm5ubH9L5r9fpwYZHh4eHdnL29x5lvlSajvA+zMYP9BcQHYd1YuwZ7YU/szVbiNCjPctJXxE6PafoKEXAe41DYshNCwK2trU8WKuCvuQckHKoKBQIbyC0lNS5PuDpQ7UqlUrMGBAq359apL4WVqGUN9sBeqv/9cu+cMTgXfZRgOZU8B6CUL4eLJr5fbPqKVfK5Ke66dBTcMkjk1KTncydOnPiQJP8fKi+W7dy588TQ0NAPWaPCrEUqQEDlxV0iIq4T35wbNmyooVnNFhCUwATBPLwXxNrYA3thT+zNp0H0TMssfT4SnJcF6BJCF6OE9JkexLt7VMLpNfRBW3VnZ+eTW7duDYk3KaGdlg4AKHa0R8VJ0eFAC1Bq4A8AUeG4sZzm6rt3735y8ODB5zRZNBgTQfzA78fHxw9xcpJgAYhEJi56n4x0pbirEsuRSZulLyll0nGmLVwq+gpMstrQNdJJsrB2HImdDPMCFaTS9JdMY6F7f6UNGEN8RTovGvhiEHEpqi3bUYj39/f/7ujRow1E7AscJ8CoBJ5LP0kjhnG5ERNtMemzFo7lsXx9YzP0QRjIUtHcAP6Nrg1mqegrsEx6B310nTIJXiQKYWquaZJ7xn67AhZM9LC2JJDBgVnI/IApU4KQvX37NgSdJStGSwsWlDUzqHj/PZczMazJ2aGwHrOtxJz0ZW2MQuizyGRYaHRsbOzXqLXZu7i0UCZwexnL505cQkuDHSxarmFDrL1JFNyk6VsuXrz4W3JvF4ghw6Rtn6fT6ZFcjAMkyPVqXIIrBfbrLQCXNqQPAAIx8DewPHRsMMUJk1LQZ5HJ6ikYCBc0Sm1WrRtPyO1WissP69XMxWg2yHWhly8YTKilQv1no6Oj79LzRxndSsgTMQxaSN/5FRMYY8a5dEAHu50jmb6o1PgwnMWir5BmA8IB4rBBs0E9EIB8ArrHp2ViegBQKdqFwnLCTU1Nj5PlfsZJVlQDA+IY6OuNjY2rpVrV4yhBiaG5GFngHilp8mvpQ03LCFHCJExarHahHwoFr2HQLhR5hurKJcVb1Ia/yDQHOfjLBbtAu8C4ap7BUjX6CwA2ZDzb77B5/thGw7+Hs/4qTcNf8C/IhuNzGJysLAToMF3KYX1KbDq2b9/+ooT7fqVLNTAw8BK5ouZSWS8DF5Ym17DoDE2h48V1bcaxeEPlHfGlc926dT+Q8HJhHAEWrpwxL/rdISqMh1Sfj3cKV3PfegHQM6T4V6MTCUv0yI4KpKDZgI6V4+uH7hI4qcpZ/ds5oNuSH5v1IWtFlifdxQDNi4sEAURyQV92h+1sMFmR3fSlS5e2SaVYEoCKyO758HvIVgZv9/A2inIitIs7LTV4xGs+vN3BxPsclYPvWg8YgXBRwjEIUwNUTSBofKQn500DpRawU2SEojmOglyczAcKxHc7RPK556V86wru6aJybQzom4Bf8cgQ6gO9dUVYcZhvVxmW4T9GavLeQLVEBSysOIRSDZ7OAPf2OB7gzWcybBiFxqFuo8TgT9IxF5+Z2LtEBSzKtTByGSSsADUs4PKm9lZMn501brPKsKFAZcSJxHkzJcgS/o8OLTAj3zy/kK88MgVFFkHADh1YL+uw8DcElT9huc83pdh8K9Z/dBTtPyWW6MiWCtCo/MtOmQ8lW/kjtLIe/xVgAOSDS20/pMFNAAAAAElFTkSuQmCC'); + background-image: -webkit-image-set( + url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAAqCAYAAAB4Ip8uAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpGOTA1M0E3QjA4QzdFMzExOTUxQjhCNzcwMDhDQjMwOCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxQjhDODMzNkM3MEIxMUUzQkMzNEJCQzI2OUFGMUNCQSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxQjhDODMzNUM3MEIxMUUzQkMzNEJCQzI2OUFGMUNCQSIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGQTA1M0E3QjA4QzdFMzExOTUxQjhCNzcwMDhDQjMwOCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpGOTA1M0E3QjA4QzdFMzExOTUxQjhCNzcwMDhDQjMwOCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pq6mNcIAAAqiSURBVHja7Fx9aFXnGb/nfn/kfie2SqqpC9ugq/YDnGWF2nasmj8qOP9whemGoxQHlox2KOyv+rEwkO4TJmMQKaTUBqltsOoigRBaWUiNdjFzmdFYjSR3JkZjkpuPe/f8Tp9X3p6ec+8599wbt5v7wsv9ft/nPN/P73nPVbLZrKMyyne4zX5RUZSSEVHuSlYq3pnhm7Oi4xULNq2oWgWrsNcS7xQN77L/KwJW2BO4aHr49RzNeZqZiqDz8k7wTfAOfJulucD8szWcRRKun2bVyZMnH+vr63uxvr4+gtesQEpFjjmFG9i2bVv8+vXrr4yNjb0JHjLvPEUJoQjUZqbBAIEhInDF1NTUsSyP+fn5wba2tqfps6gZIZul4f915uBd+PDhw9+em5vrE7zLZDLTly9ffoU+i9P05uKdqb1tEKkwAfHJycl3INfZ2dleekyD0IWFhau7du16BAqQTxOXoIDBOx94NzMz00m8+oJ42EyGMcBCniRLXgcFYEV4IAJWNbC/v38LEZRqb29/hl5X45EIHgGhd+7c+TO9lyiGJpaZgOHVIlevXt1J1vvPffv2fYNe18AgyEh6wDsS/Cl6L8mKoBQsYBvxwys0cGho6FUWJGJv9ZUrV34i3M2hQ4e+yZpYUDwuQwEL602QcC+cO3eugd0xPF2is7PzOXhD8K+jo+NZ5p1zsQWMDUOwVmggC9fPQgRB1SKupFKpt6CdLHyPVSGXoYDBu6qzZ88+T9b6d4l3Ln5MTk9Pt7EH/At/7llsAasuBsIbHR3dKyVTID6MBAvEiViM+MKCrio3cKUAJoNPsYmJibdv3rz5Biu+Wwp7MSRZzLsv2E379QyjlAJW3TPiRUtLyxp6HmTBOdltn8pqBpUBr+VyN0tIwIJ3vRreCfetViUIb5Kb1jWMUglYdc+bN29GQvBvev4QC87PM06p/+NE4ISc+nNGHVyEulgLvHh5+jRTvO/h7zpLlSNoaEPdu4JDW1wnicLrJNw3eMdWHtPLposlYBlt8XEy8NDx48dfHh8f/4ie17GQ4xwvltFcQRb7CyHge/futXIcDvI6bl5TKZJAZfoCrPERZkyMadOb4nMBzAR4DdP0WWSyahw9PT0vTU1NHee9vZolcR0JVCDgHUpQozhsZm+3SUvwiix49+7diYaGhu+uWbNmq6Ioj1y7du0PyWRypcfjUa+E4sZsY2PjT2tra1tIC7fQ+98jYbfymn5mYFYHksvasNT79O3Zsye6Y8eOp6LR6KpIJPIdp9MZd7vdq/UWACBD3mWcmPkPiolDR44c+aypqWmiSPQZ0rx8+fJvURj7nNfM6GD4GRLspXA47PB6vY/qYNW2sGiZcWp2d/78+Wfr6uo2hkKhTSRA/8jISK/P5wsTEf/q6uo6QgTPBAKBzPr163tB4N69e2HF6dOnT7++adOmDzZu3NiBdcmSD9PvnqbHNqoB/7Z27douZuCMBUbmpI+Uzp9Op7uJtm4IjhSwV/yQ6XNQBvuEeG/lypVPkAKEVq1atePAgQN/3L9//4xN+vLS7vf7aylTHjJoKmCPDBSO+OpwuVy1Bs2cgglwsxuOd3d3fx+JFEqeGzdu/JyTArjjulu3br1/5syZH9Hzh9nFhdg6PVLsCzNkKT6PYQ2shTWxNvaQ6sB8tbIZ+hK8XlRyvVX8G5EnhKT3I/xdNcRYpc+iiwZfYqR8LX19fZsNkiesX4USVCC/9fX1NUy37Rislj/ARylGvA/obHBw8MfMtChfJBKqZaSBZ44dO/YME+nScSOK5D5dUpwMMFMTWBvJBvbCnpqSwbA8y0OfT3LZLim7VzTTKXkCt5SIhazQZ5HJ2CNGvPuYs+OggYCDAIhEDkNhp475ZkvAcoZ3ATUYo1BxCcRwCgyVtPtTtpiABfchGOsWGTf2wF7YE3vnWM8sfYpNlMkSfQUIGGVkO3u2kMG1BiBUIeDm5ubH9L5r9fpwYZHh4eHdnL29x5lvlSajvA+zMYP9BcQHYd1YuwZ7YU/szVbiNCjPctJXxE6PafoKEXAe41DYshNCwK2trU8WKuCvuQckHKoKBQIbyC0lNS5PuDpQ7UqlUrMGBAq359apL4WVqGUN9sBeqv/9cu+cMTgXfZRgOZU8B6CUL4eLJr5fbPqKVfK5Ke66dBTcMkjk1KTncydOnPiQJP8fKi+W7dy588TQ0NAPWaPCrEUqQEDlxV0iIq4T35wbNmyooVnNFhCUwATBPLwXxNrYA3thT+zNp0H0TMssfT4SnJcF6BJCF6OE9JkexLt7VMLpNfRBW3VnZ+eTW7duDYk3KaGdlg4AKHa0R8VJ0eFAC1Bq4A8AUeG4sZzm6rt3735y8ODB5zRZNBgTQfzA78fHxw9xcpJgAYhEJi56n4x0pbirEsuRSZulLyll0nGmLVwq+gpMstrQNdJJsrB2HImdDPMCFaTS9JdMY6F7f6UNGEN8RTovGvhiEHEpqi3bUYj39/f/7ujRow1E7AscJ8CoBJ5LP0kjhnG5ERNtMemzFo7lsXx9YzP0QRjIUtHcAP6Nrg1mqegrsEx6B310nTIJXiQKYWquaZJ7xn67AhZM9LC2JJDBgVnI/IApU4KQvX37NgSdJStGSwsWlDUzqHj/PZczMazJ2aGwHrOtxJz0ZW2MQuizyGRYaHRsbOzXqLXZu7i0UCZwexnL505cQkuDHSxarmFDrL1JFNyk6VsuXrz4W3JvF4ghw6Rtn6fT6ZFcjAMkyPVqXIIrBfbrLQCXNqQPAAIx8DewPHRsMMUJk1LQZ5HJ6ikYCBc0Sm1WrRtPyO1WissP69XMxWg2yHWhly8YTKilQv1no6Oj79LzRxndSsgTMQxaSN/5FRMYY8a5dEAHu50jmb6o1PgwnMWir5BmA8IB4rBBs0E9EIB8ArrHp2ViegBQKdqFwnLCTU1Nj5PlfsZJVlQDA+IY6OuNjY2rpVrV4yhBiaG5GFngHilp8mvpQ03LCFHCJExarHahHwoFr2HQLhR5hurKJcVb1Ia/yDQHOfjLBbtAu8C4ap7BUjX6CwA2ZDzb77B5/thGw7+Hs/4qTcNf8C/IhuNzGJysLAToMF3KYX1KbDq2b9/+ooT7fqVLNTAw8BK5ouZSWS8DF5Ym17DoDE2h48V1bcaxeEPlHfGlc926dT+Q8HJhHAEWrpwxL/rdISqMh1Sfj3cKV3PfegHQM6T4V6MTCUv0yI4KpKDZgI6V4+uH7hI4qcpZ/ds5oNuSH5v1IWtFlifdxQDNi4sEAURyQV92h+1sMFmR3fSlS5e2SaVYEoCKyO758HvIVgZv9/A2inIitIs7LTV4xGs+vN3BxPsclYPvWg8YgXBRwjEIUwNUTSBofKQn500DpRawU2SEojmOglyczAcKxHc7RPK556V86wru6aJybQzom4Bf8cgQ6gO9dUVYcZhvVxmW4T9GavLeQLVEBSysOIRSDZ7OAPf2OB7gzWcybBiFxqFuo8TgT9IxF5+Z2LtEBSzKtTByGSSsADUs4PKm9lZMn501brPKsKFAZcSJxHkzJcgS/o8OLTAj3zy/kK88MgVFFkHADh1YL+uw8DcElT9huc83pdh8K9Z/dBTtPyWW6MiWCtCo/MtOmQ8lW/kjtLIe/xVgAOSDS20/pMFNAAAAAElFTkSuQmCC') 1x, + url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPAAAABUCAYAAAC82LpqAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpGOTA1M0E3QjA4QzdFMzExOTUxQjhCNzcwMDhDQjMwOCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxNTQ2NDdEMUM3MEIxMUUzQjI2QkI2NTZEOUZDMjc2OSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxNTQ2NDdEMEM3MEIxMUUzQjI2QkI2NTZEOUZDMjc2OSIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGQTA1M0E3QjA4QzdFMzExOTUxQjhCNzcwMDhDQjMwOCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpGOTA1M0E3QjA4QzdFMzExOTUxQjhCNzcwMDhDQjMwOCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PjMGTKsAAByHSURBVHja7F0LkFRVej79nO559DyYEUfEASExYJRFC8NKQKgku1vR6GrcDeujykRrTbRiardScawKeWh8sBVdH9EstUQRDbAGjUuxu1hgsGBVlMIHKjDozDA6PGZGZ2BgGKanHzn/9fw9/z19bve93bdfzDlVp3qm+/a95/z9f+f/z/86nmQyyXTTTbfKbF5NAt100wDWTTfdNIB10003J82vSaDb2dQ8Hk/Zj9FNu5N/MhPSbWLqppuWwNI6QLGmfy7disRryrVeA9g+ET0ZAJzUgNatQDznsQBykvSy4j1/GRLRa0FMIFpCIqQGsm758p2H8J3Me0mJ7xLlBmJ/GRLRR159Enhj4jVO3vNoEOuWI98hYJHX/ApMIJ9FBd8lRAf7SbLUth5vmYDXSwgYEj1AVkWf+D/Me5W4zkvG79H8qFsO4KW8VUXB297eHiHX+ghPooDxeMrAUustE/B6BXFCOKY9e/YsGBwc/PGpU6ce46/tGzdubCNaQ0gBYt10y0XjA74Lwv87duy45MyZM+u5YP3q4Ycf7k4kEp8D/z366KPN4noEuU9St0vXwI1SiG6TkD5BvGrem6Bv3rz58mg0uieZ3mJDQ0OPzp49u0Vc2ygkcoAQs2zmr3tpuk3J6xdgrEW+6+vr+wfgMQXfJTmQB7hA+TZey3uN4FtfLnzn6nxLSEiqFgMYm7Zv3/6HQKxkhnb69On/ISCOSNLYowGsAWxTaKT47siRI/ckszTOl6PAn0R4VOcqPCodwPIqCCBs4mrK78bj8S+SNhpIYrIa1or7+DSAdbfJd7DoNwD/bNmy5QoOzlN2+G58fPzA0qVLzxV8Vy8Jj0kF4DTVeXR09DdIKA7kI3zvsYb3/4K/VcT88MMP/8wNVVoz/aQCMPKdoToDGPl27QPcog0MDNy/atWq32tvb59x+PDhuzmwT8h8Nzw8/PN8VelKB3DaKtjZ2XmThYrcBH/De2kb4lisi6yGkVylsGb6SQFgpfTt7+//R8FOY11dXbcSYBp9x44dV6m2dLt27VomrmkgUnhSAJiugjUIUFBNELyEgC2iG/+rQAyGh3z3JJrpJw2ATXwHiz9qdyBtJb6byjtYnpvef//9P1XYYX6ZjxSudACbVsFDhw7djmrzAw88MEtaBacgiEGtkdVp+D/DnsSWiV8z/aQAcJr0RcPVmTNnXiP81ij4qJ7wXxNs5WQFEPbOuUrhSgUw9bulLIB8D/IuUKSnp+eHhJARsU+pFQQyVkO4Rl4NYQEg36sjxPTZkcaa6c96AMuWZ0Pr41uwT4F/QE0mQKwR14SpiwkEi7wfBhsN4Tuq/ZUOwEVwoPuo5Rn2Emjdk0CIEVchQkhjNeTX7qWE5AvAb8XnzQT81QTEBXG2a7BUHIBTfPfJJ59cJ3jnbSJ5a8Q1ARKZVYd8B8Yr2a20fPny8wjP2rbBuDnfYkYxyREwbM6cOdfD68DAwCoSdxoTMae0Y8wz6+/vX0VvGggEFvIVshHjU4mqVFMWkTK6lVvkFWtra7sRXo8ePfqcFO+ckHgOY+8hMvB50009ntDKlSuvEf/a0vbOhlBKLyVkbW3t9bANefLJJ/9XfD5OCImZIKiaGIR88MEHN8F3yD19t99++7UQaskl+rzDhw//YPfu3ZeRQBENYN1SfMfVZ191dfXVnIe+vPfeezeLz2MKvksQELNly5bt49rfe/SmU6dO/XNy/9KEVhZJhaZqTC1GXUkWPbQkB8mK5keLIajbvb29f81Xzb+38g1j279//w1kb+JjWoWerCo05bs6alUGwxTZ+5riCMR90F5TLYVbmtRoYkSlavRZtwem1mfDwgdOcyACANLCiowANqyGYC20Ey3Dwd1H/Mhhpz66fACsW9nF4KfxHUTxAZ90dHQsV4Tjesh90r67bt26S2V+gwVBskZnFRhltQd2QEhTkn5dXd1SeN22bdtW8V7CAvjG/nfDhg0/5vcdyTYevrJu/Oyzz+IsvYrCZNjj5dInE21YOBxeAHvcl156aTdRn634hKrT7KabburlUreXXsD304slNb2yVGibAEY1BgxLzTNnzpwK6gdEUwk/7znEehyULIHVwsLcDNI6mwQmboF6lkeMdJlJYFXlCFr0wG/RkY5Wn/vIdkVVkaLSJbCXkZBd0MyA7yB8kpnDcOEar+JeqEbXEJ/wLyi/cc1wOzMHdWR1J5W1FdojGjOHr/kIQ/lWr159GVjxRkZG3pZUZp/EWMhcIFG9V1555Qvj4+O7rJ7NF4SOJUuWfKSQ6JUkbbJVKPFJAPRnALKd932K933SsytRYqdZn1988cXfB76DdFVJwlqtvklZCp88eXI3vSAYDF5WSj7zugla3lTSAa3B6Ez3cbVjLnyP74MPSJ8FhdREHzC+GlKku7s7sWXLlh+xr8ubpLXjx4+vZ+Z6Rh7J8l06a6E9ZrOin98CuDLNkF6ZOr0Wv+/PsjD4ypx+meia4vPp06cbfHfixAm0JickoFqBOFULq7e39wOJ9yObN2+eSTTNotLGmy/TEdD6LFZ8VONCQl2p4vvf+XCDjo6OzwiAfRLzUmZJLQTXXntt51dfffXvivHEObhfVUhfrwIIvjJgRhm02ehHF7Ww+Dsoqcgy0FTdJ907SH8b8gyV+u0rI/o5pTPYXS6B187Ozo8JgC3Bm5zQyVMS+LnnnusQGmGqzeVNIYGLQhN/HquarKJ4CNi8ZDVK+9Framp+B25w+vTp5KZNm5bNmDGjmasi8ebm5pmhUKgaH8T3K0BED7/uWGtr6+OCoWLXXXfd02+88cZ3/X4/Eo6NjY29deutt/aSRSlMCB+XXuVqg8WscumUfkpGWLp0afCRRx6Z09jYOJUzZiu8x+k62+fz1WR6eDwe5zuXkc+EOnh0aGior729fT+nZ5TQzqtQIykNS0m/XGkN6u5seN2wYUOXBGAK1kyGLM8zzzwz8tRTT/V6vV4s8cQaGhou4i+/KslWw2E1A7ovo6s3gK5OGAVMKVk33HDD+du3b7+WS9t/7erq2sxVkI84EyV4T3JJanTOUEkOQHABqSohGO+/++673+P3m8Y7+N2ad+3a9Se0BMoXX3zxd2jsEtecs3jx4lZ5PGKMdWLMVIo5qnOUYzUIx/SDcD1wVUDqG1/IXgEDjN0EdCcN7gn3hmfAs+CZJFSwKPRz2YhF4+6NsXM+OgRFI8hcLA1YkiErlcXEvnZpbrMRF+0pxtz9DtUQWe3zM6kiAUS68D3B0vPOO++PwuHwYr5SzY3FYmBgYnzi8NAx/p6HMwvH7ldb+b71AJcco8eOHdsbCASifJVM/Qq33HKLoeo8//zzl+zfv39QrIJjwCwLFy58j+9lVkUikbvAGPjEE09souN95513vrlgwYJX+Q+2b3R0dOeRI0dev+aaa94QLiZUDzHSJkZU70IU8M6ZflTLED/+GTDWcfqBKjfKF799fI7jhw8fhoXRpNoh/cB4Y3IJ8DZt2rRL+EuA0x7uH+Z0v4g/6yL+G8zjz72+paWFrV+/nr3wwgvlQL98JbBBV8535xMjqN0xphm6OP17q6qqqCFrdsmMpQ6ToVFi1FJpAdEokBANObtS1sYYX51e51L3J2+++eYd999//7LHH38cJGdycHAQIrAgfRAMALDST0VTvaJPYRPJCjXCRTTlrrvumg6rKkgNcQ1+f+qnn376l2KlHCNS5gSMEcZKImhQqtQSiZK1xlaOyeSO6Qdz4LR6GD6Hgn8W9HGtwzPgWfDMYtPPZQlsyv9ds2bNxUJa/oKZAy8MaZnhfhjQkYrI4rT5N7m4BEvPD/YWY+52Mzn8xCfbgIMFAIG6BdFPJBLqCy4Zf3rgwIHvCRUW/LzwegEA9rXXXrsZruMr+moB3vOFH7iRmdMIaySjTRWxuIYFiJsgbBIqegjwRtDXjGAGRoOxwJhozS0YM4wd5kCI3yDmSMuHevIAcF70k0BCwdIo7tMg5hwRam0doV+teF619B5eh9/D+zSqVPhi0q8AAE6F7u7evfuPYdx8Hk8yRR6vDQCnUmChAIAcUsnMNdrKAsC0cqSpBCfsjfgq9BMiLWJczdoMP7RCck4RAIX96/R9+/bdLfas/yKAfY4AIwVsUArokH2XCOQG6XnUlRJhE4nZqQ5jhLHi/hnmAHOR9nu1xBKrZEIHcbj50A8ZrZ4sbtVsImdV5RqSXUQqV5PscsL7IdiRdg3FpJ+LAE5LIcSyTbDosAwhlBkAnCoGAGGYsg2BLGQYE11SAFvWz4UkBL6P+IRGopDqBLKhA1f8BpTEn3/++Qr4Hldx/0aAl/7g2XyPKv8yMl9A4X5BaV0rMyOMGcZOKg5+QsqGymNKUwezANgt+tUQoFYpFjcrF4+d7le4k2Q/fFiMIc3AVgj6uQxgU9VTSISBccJrDgD2UQCjNKcN4qSZzaSGYgHYJzMfV3t/BOoC7s+kKhpNRJKGJfW3Vkjili+//PIRkTH0A6L2po5SsfEDqYIevMw6xJCq3TWyVBZVPsZQFYI5Mhsla20A2A36ZfPzpsU2O6BfpvBMKz9xQelXSABjJhGp4FJHFhhPlnsigOsZyaSjjSxe9cUEsDeL4QVN6JD8/Fetra2PQSga+AK7u7vvaGtr20gsdWOix0iXk/ITgUAACMei0egpZn3yWyajW1L47Kx6Qur4fBwTjtN4FswB5gLXwNxgjjBXNDBKYHFi/XSbfgYNASekpzW79JO9SNglmsm0Kxb9XA/i4HwXEfECIworsy17L/4xMjIyKn/Y0NAQUVm/SxGJJZ8bAxlDF5177rkP4gXDw8NPXXjhhb8iExsnDBeTQUsB5vP5QiJII54h8oXlAWSmAHNcGltMjNm4HubC5/QM3hvmCnMW/wYcRhy5Sj8ZqEXwSpiAXQL6FaRhgAvnu2g+5BG/37j8QYi3YoM3UyilKQh84cKFf4uSBNp77733MrH0JSSwJiRAeaQVDFQxiFseLpanLIN0TmA0Gp/TS+Q7QTFnxnLLZsqbfsUCrMOFslj0K4gvGNoZCEbI00fd2dmZltbq9XqD2Z5diOa3oQay6urq79APwuFwQBGgYIuQfKIBocpEnRJSPs7RBQb3KOaE/y/NYY6FpF/+nFxZ9HNzAUd1Hvhu1Am4SGZdag5chY7bVd1LJYHlSZjia+fMmXMjBqWwzAkClpMYHBw8Y5eAihRFPJ/VbkA9zUqRjVxGzaO5c+f+hfTcRheB45h+ZM55gzYT/UTP+CzyWUno59IiExWqtM8J3RSGPrvaV8kBTEPHOugHEL7Y29v7ffFvglgrZb+tZQpaa2trxMFKKB8C7lM8w4pwqqwfGgoIKWLfr6uru5N+icw516oertDPLsjcoJ/qGQrgF4t+hVE5/f6gA81PRTfW0tIStAngggPZm2XfmBDS8kX5gmnTpv1Hf38//dECxPVhFYThjcfjY0R9N2XiqBq5Bv2RNWwi6EP5DAXxqFEJAwyMBnOAucjzGxoaWqfYQzvdd7tOP04SnwzqTC0X+knfLwX9CqFCo2pf41BwYICLH39PLnxC8oV8wRqVtqZFkcLZAGyoR4sWLXpOLqkJPzZfiR6KRqP/B+VcCaFozG8VkS6GbzEGWQ0sZdb3K1QyK5+kv729PbJu3brzmTk6JsTMMbgykGniABYdYzBmGDvMgUk+Oz7XD2HORM3NFcBu0E8F6EwBHGcD/VwHMB/rSaFR+Gx+L7VoLV++PATzxU60R5VxDA134aJI4QypWKbwMTh2EYK2rdLR4IQEcOpL8bsYRgkhk5A/OfPYsWM/g+vfeustCOTAOGh4Ri0zhwfS4AHDGY9VASGUD6rrM3XYYQ0zB0Gg1EidxQRjtZoHzBHmytLjZb1WdCsg/eToLIx9ppJUFVpZkfQrUCCHUU4W66mR4BnLQA4CXqCBEfqa7eB5OF0E0jE5jndApJZ4RogVOAotWyQRFgQzwujgjBgYYJa80sFTp06t6+7uvm3lypUXEQDP4H1WV1fXoyJyBZz/kI0ESQ7AtC3MHKSPAfZ4YpxxwJlMNDikSpG3ikH1lJGNz1RnvpKwxh3kgDW5TnUukVh50Q8OPWf2sogaFbSrOPoVKBbaADCeqwXzZVlCKSUAm8rRZmvSsbcFn3smBpSPZEzFwvJ9z312ksohGX9kZOTDvr6+NXxVuu/ZZ5+9/uDBg0Yq1t69e9sFgNvYRFLDlGzMasX0kGVC4lHpSXOY2WTJgDAXmJP0XfnYSKcAzpt+QjJ/AEXIIUQRVnaLJHvbvZzpVyAAG6GskLUGY4V65MxGLDTZ89eiBkVTK60aOWe4nk1EohVs7h7KeLIBUrEHSqVJwXlEd9999x0NDQ13WrkM4N5QFge2vZwRYW8Eyc9wpArUb+7nas0bfr8/OjY2treqqirBrzs2ODh4JJPKf8UVV/xahCOqWpyrh5s6OjpWz58/n1avjOM+jY+nGwqRifENHT9+fNXTTz+9esWKFUPEKhxl6uM2THNTuB5cpZ9Vi8fj3Xwew5ymUIEzOjw8bCTu87n3cQY9Wqn0c8llR/ehqWwwrvHN5ZJxJ0SM1dfXrxBzGhOvMdknLlyUNJsMSjuthmIHVs+GYgGcv6/GbTH7OloNg3QKM3ebR4LS4xkjTCr5AoHieEi3QqUA1Sp58uRJo3wOX+lR3TL+56oJ7MlA0hgS260GpxhC3iY5pSElQWCsMGaFNIuwiTIrGQ+scnikas70K1UrBf0KmdAP2xFxlM8rLP1IFU+WNEJDe9qzZ8+3bdYkb2QZzgwu9tEqVB2kxdbrmZRitnHjxvlQrQDP/EUAQ70rLnFTgDVScfh7+D8UtwMAq2pi5dqg9i8xJqRyWyU1kaqK1Sw9h9Wtihw5069UrRT0K0BNLFw0G8XiMypqQtOi7sosOIUabmzvrH4bqFTC0pP6C54LnUmFVkWzqAqOKysvrFmzpvWqq65awNWVy71e7ze4qjyfg9bwwTU1NRlqNVdnjGdCHDgEyPBrINQyL40C1EsuOR4hmT6gvoyK8WGaF61WiVUW48xBTScbKrQr9OO0uoxvL74BBcTliK5CtFLSz2UVmrrRQBp6uObwFuezcziPzSZqbkyo0AnFvagaHcKglWnTpv2nNJeRtWvX/sFtt912lE3UbRsvyvbB4dEg8okLctJ8vcJwAuVtoN7VeY899ti3tm7deg9fxfr4ajje2dlpVKnk6vWQVVVKB1UVT0C1BckNE2HmGscBll6tIsDMSecep3QrMP1Sfdu2bd8ENw4YtKASIqlSOehCVcqS089lCewhwDMkMN+q/QbmSizlKSt5lmT+lDUb6ENLIIkyPT9l6TWxilJOKNezfTyKMLOgwvfYIFSPqcLSDDWwZh0/ftwoy/nQQw9dJSzR08XnsN+aAgSG40RpR6KLci6mbTZYacmPQousUZVOdURJzsXJ8zwbyQn9HFuaK5V+BQAwSt8IdQWREwVNBQcsAJx2zCgtagdH3ZJyOvVWfu9yA7AdZsSyLFjFoVkAdWZPT8+TMPmdO3f+kPiCbbmS6OFSUDURpBJLr2ohF1bzMpdP53PxcLNs9KsWNKwle9HGXN1I5Uy/AgDYJD3Bty7qYt2nAJzHRk2siOxSIn5l6vcuWkVOvwsqeJLsPZJk34Q/cFwypQe4ygzuDzZr1iwIVPi1+Gxc2lPRUwI8JOZ0mO9lPjpw4MA/XXrppTvJNXFyjxgrvxrFudKPZQGP1XEeSvqB+4nT8KODBw+uuPjii3eS78Wl38BEP6vUQxcSpooRSmnwXkdHx74ZM2ZAeuclFnS14pEEoY/3zjvv7L/55ptfraqqmrNkyZL16EWysAMUnIEKdbyoXJkiJFbCltWrV88HhhgZGdki1OupzFwPSi6shlbbKS+//PICoWpjbyYBByG7VlA36VZg+qnOT5LPTbKqPknpZ0gPqbZ0oyJ80rSfdXicZzlJYNkSjW6wQVLH2SQ1M/wOXjk0E1xGJBy1nmw3spYPKoUVmjm1Jkr3otbWamHt/ACsqlwKz+GqTZxYBOPSCkYzlmqIbw1PBaBgBesfrbVV0IXPDWnkFASKlEJPBqu3vBCEiRUZJUpSCrhIZJK4bkngIlihmbToGckFo6Oj/x0Khb6zfv36eXBgtwg6wZJGCTpvRR40dlo2Fq30ckWaoszd6wbBVF2hxtBDssAPvAsikF555ZXLicqYugbsA9CZ+UCtUWYuqpY6THnRokUolcpWXXZCvwx0zVbET1WUDvuI6KcELWktLlPUlIPxlLv6TPkOIgCNCLOlvElbjGx50LSPC+BHheCxBdxCNG8JiGkQcmBgYCu8trW1LSaRMypiJqU9no8ANdHT0/Ndvhi82tfXN06urbTDqItB94TC1pBQgPdsnj/7+OOPX4fXpqamqyW+UxU1kK3QdHsXZOmRVkVPm/SWipBr164FQsZra2u/pTIoWJQ0CaKk5sC9YXx8/LcXXHDBKgjtE4duxTVws9I+yTIfD3o2zjslOJYtW7aP74N7gsHgEsiPZumHwDNJbUZLtscCP1Ul5Tk3DBIOFgs8ScFwg0Sj0bdhzwF+SpaeISInkhtGGDgRgJ5sAA2OumATfr1AMRYmNw06k3JFKY4Ri0k8ZATKQOCFcAFhEXoaF02TIFLfUZ3GABlObOKYUtvVN8vND2x7u8ekJHeslg+BBJJVsIpYWqsYSWeDa+VUOBJwH9YA1gBW8J3JHwy+b8yHJhb5OmYuaYRekzT/ueC7AcJ3ockC4LQMEQgwh3xSEgmEgQSYTJ7KpYWIFzkflRyujMHp/mKoNBrAFQXgNO0PCyuQo1boweU1FLyg9cm5wBDVRaR3VVkAuMCEpGp0Kj51eHj455IURhDjEZhw3RSV9IUwQOLXrHdKyEIyku6l6Vm0vypUieGURUUoJK1ukjqiFrd6lO+kw8yCkwXAaeqMqNME2SAxkk+JB3pjoIbhOMcjLUkK1y+Z+mBlDWAN4IzaH3TIeQY+4kLkZ4SPgOfw1Ew4kO4eee/LBckL5Ppqp9u2SgdwmjqD+wu+Gh4iK1szghfeUxWEI8Yv02HN5aDK6V5WAFYaszA2WmQUPc2kuHFxkHdMYrsxwqM58V0lA1hWZ1LVEnFvCyoNyRZpgr/hPcUquI45SOHSAJ70AFZKYUjooJVBwbAKBfAUWVtJqaZWY658dzYAOE0KY9VAkqZ1CLpV5T+yb7EsXaoBrAGs4DvTXlgIjwGbVUreJvnSEeItKZnQKAUhLVdD2VRv0cZIqZdGsgfJ6RQ8zfSTBsCU70zCA7S8bFVCudD4lJT5bZRclpMSwGlBGrC6WakueAJ8Z2fnTSw96TznIyw1008qAFsKDyhYZ6XxgWpNitVnrHc9WQAsr4ap4A4m6ibLRivw20nJ57SyvlcDWHcHfEdV6VrkKdiW8T3uP0PhOnHKwnZykoMKvN5SA9hTpLSubMSkMaeps2ugsNu8efPauNQ9euONN/aQ70E2Es2iyTmeVwdgnF3NAd/JVVCyuYKA16JMkblVSp4rBwAzln50pVVCfsaqERrAujlIcVSlC6psKckMPFdyoeEvMb0x/S9B/k8wc3aIh6nzXkt9bKVuFR7NKV4TEn+p0lkpvyWk75e0+cuMkB6JSKpcy7Kvc6VbxYGYChKaC5yUeK/seM5fZsRMsvRyMExBOA1c3QoF4mSW65gGsD2CaqDqVkreq4jm1b+ZbrpVbvNrEuh2VonQSeZV8GtC6qZb5TatQuummwawbrrpVor2/wIMACYrlOo06AbeAAAAAElFTkSuQmCC') 2x + ); + width: 40px; + height: 42px; + display: inline-block; + speak: none; + text-align: center; + vertical-align: middle; + margin-right: 4px; + -webkit-transition: opacity 0.25s ease; + transition: opacity 0.25s ease; +} +.m360-spin-x .m360-hint-message:before { + background-position: -40px; +} +.m360-spin-y .m360-hint-message:before { + background-position: -80px; +} + +.m360-loader { + border-radius: 100%; + font-size: 0; + opacity: 0; + padding: 0; + width: 50px; + height: 50px; + left: 8px; + bottom: 8px; +} +.m360-loader:after { + content: attr(data-progress); + font-size: 12px; + line-height: 1; + display: block; + position: relative; + top: 50%; + -webkit-transform: translateY(-50%); + transform: translateY(-50%); +} +.m360-loader:before { + content: ''; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: 44px; + height: 44px; + margin: auto; + text-indent: -9999em; + border-radius: 50%; + border: 2px solid rgba(255, 255, 255, 1); + border-top-color: transparent; + box-sizing: border-box; +} +.m360-loader.shown { + opacity: 1; + z-index: 1000; + -webkit-transition: opacity 0s; + transition: opacity 0s; +} +.m360-loader.shown:before { + -webkit-animation: spin-loading 2s infinite linear; + animation: spin-loading 2s infinite linear; +} + +@-webkit-keyframes spin-loading { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin-loading { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} + +.lt-ie10-leoimage .m360-loader { + font-size: 14px; + padding: .8em 1.2em; + width: auto; + height: auto; +} +.lt-ie10-leoimage .m360-loader:before { + display: none; +} +.lt-ie10-leoimage .m360-loader:after { + content: 'Loading... ' attr(data-progress); + text-align: center; +} +.lt-ie9-leoimage .m360-hint-message, +.lt-ie9-leoimage .m360-loader.shown { + background: transparent !important; + filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#7c31333D', EndColorStr='#7c31333D'); +} +.lt-ie9-leoimage .m360-hint-hidden { + filter: alpha(opacity=0); +} +.lt-ie9-leoimage .m360-loader { + filter: alpha(opacity=0); + right: 0; + left: 0; + width: 96px; + margin: auto; +} +.lt-ie9-leoimage .LeoImage360-fullscreen .m360-loader { + left: 8px; + right: auto; +} + + +/* Magnifier */ +.LeoImage360-container .m360-magnifier, +.LeoImage360-fullscreen .m360-magnifier { + box-shadow: 0 0 10px #ccc; + border-collapse: separate; + background-color: #fff; + cursor: none; + overflow: hidden; + -webkit-mask-image: -webkit-radial-gradient(circle, white, black); +} +.lt-ie9-leoimage .m360-magnifier { + border: 3px ridge #e7e7e7; +} +.lt-ie9-leoimage .m360-magnifier.m360-magnifier-inner { + border: none !important; +} +.LeoImage360-container.desktop .m360-magnifier.m360-magnifier-inner, +.LeoImage360-fullscreen.desktop .m360-magnifier.m360-magnifier-inner { + cursor: pointer; + cursor: -webkit-zoom-out; + cursor: -moz-zoom-out; + cursor: zoom-out; + box-shadow: none; +} + +.m360-magnifier img { + position: absolute !important; + max-width: none !important; + max-height: none !important; + min-width: 0 !important; + min-height: 0 !important; + border: 0 !important; + padding: 0 !important; + margin: 0 !important; + outline: 0 !important; + box-sizing: border-box; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-touch-callout: none; + -webkit-tap-highlight-color: transparent; +} +.m360-magnifier-loader-holder { + background-color: transparent; + cursor: default; + position: absolute; + top: 0; + z-index: 1; + width: 100%; + height: 100%; +} +.ie9-leoimage .m360-magnifier-loader-holder, +.lt-ie9-leoimage .m360-magnifier-loader-holder { + filter: alpha(opacity=60); +} + +.m360-magnifier-loader-holder .m360-loader { + opacity: 1; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + -webkit-transform: scale(0.8); + transform: scale(0.8); +} +.m360-magnifier-loader-holder .m360-loader:before { + -webkit-animation: spin-loading 2s infinite linear; + animation: spin-loading 2s infinite linear; +} + diff --git a/modules/appagebuilder/css/ApImageHotspot.css b/modules/appagebuilder/css/ApImageHotspot.css new file mode 100644 index 00000000..9915f7c1 --- /dev/null +++ b/modules/appagebuilder/css/ApImageHotspot.css @@ -0,0 +1,692 @@ +.litetooltip-wrapper { + position: absolute; + font: normal 90% Verdana; + z-index: 10000; + display: block; + visibility: visible; + min-width: 100px; +} + +.litetooltip-wrapper.incontainer { + position: relative; +} + +.litetooltip-wrapper.incontainer .tooltip-content { + position: relative; +} + +.litetooltip-wrapper.top, .litetooltip-wrapper.top-left, .litetooltip-wrapper.top-right { + margin-top: -3px; + padding: 5px 0px 10px 0px; +} + +.litetooltip-wrapper.right, .litetooltip-wrapper.right-top, .litetooltip-wrapper.right-bottom { + margin-left: 3px; + padding: 0px 5px 0px 10px; +} + +.litetooltip-wrapper.bottom, .litetooltip-wrapper.bottom-left, .litetooltip-wrapper.bottom-right { + margin-top: 3px; + padding: 10px 0px 5px 0px; +} + +.litetooltip-wrapper.left, .litetooltip-wrapper.left-top, .litetooltip-wrapper.left-bottom { + margin-left: -3px; + padding: 0px 10px 0px 5px; +} + +.litetooltip-wrapper .tooltip-arrow { + border-color: transparent; + border-style: solid; + width: 0px; + height: 0px; + padding: 0px; +} + +.litetooltip-wrapper .tooltip-arrow.top { + margin-left: -8px; + position: absolute; + left: 50%; + bottom: 0px; + border-width: 10px 8px 0px 8px; +} + +.litetooltip-wrapper .tooltip-arrow.top-left { + margin-left: 8px; + left: 0px; + bottom: 0px; + position: absolute; + border-width: 10px 8px 0px 8px; +} + +.litetooltip-wrapper .tooltip-arrow.top-right { + margin-right: 8px; + right: 0px; + bottom: 0px; + position: absolute; + border-width: 10px 8px 0px 8px; +} + +.litetooltip-wrapper .tooltip-arrow.right { + margin-top: -8px; + position: absolute; + top: 50%; + left: 0px; + border-width: 8px 10px 8px 0; +} + +.litetooltip-wrapper .tooltip-arrow.right-top { + margin-bottom: 8px; + position: absolute; + bottom: 0px; + left: 0px; + border-width: 8px 10px 8px 0; +} + +.litetooltip-wrapper .tooltip-arrow.right-bottom { + margin-top: 8px; + position: absolute; + top: 0px; + left: 0px; + border-width: 8px 10px 8px 0; +} + +.litetooltip-wrapper .tooltip-arrow.bottom { + margin-left: -8px; + position: absolute; + left: 50%; + top: 0px; + border-width: 0px 8px 10px 8px; +} + +.litetooltip-wrapper .tooltip-arrow.bottom-left { + margin-left: 8px; + position: absolute; + left: 0px; + top: 0px; + border-width: 0px 8px 10px 8px; +} + +.litetooltip-wrapper .tooltip-arrow.bottom-right { + margin-right: 8px; + position: absolute; + right: 0px; + top: 0px; + border-width: 0px 8px 10px 8px; +} + +.litetooltip-wrapper .tooltip-arrow.left { + margin-top: -8px; + position: absolute; + top: 50%; + right: 0px; + border-width: 8px 0px 8px 10px; +} + +.litetooltip-wrapper .tooltip-arrow.left-top { + margin-bottom: 8px; + position: absolute; + bottom: 0px; + right: 0px; + border-width: 8px 0px 8px 10px; +} + +.litetooltip-wrapper .tooltip-arrow.left-bottom { + margin-top: 8px; + position: absolute; + top: 0px; + right: 0px; + border-width: 8px 0px 8px 10px; +} + +.litetooltip-wrapper .tooltip-content { + padding: 10px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + min-width: 90px; +} + +.litetooltip-wrapper .tooltip-content .clear { + clear: both; +} + +.litetooltip-wrapper .tooltip-content > p { + padding-left: 3px; +} +/******************************************/ +/*************** templates ****************/ +.litetooltip-wrapper .tooltip-menu { + padding: 0px; + margin: 0px; + float: left; +} + +.litetooltip-wrapper .tooltip-menu ul, .litetooltip-wrapper .tooltip-menu ol { + margin: 0px; + padding: 0px; + width: 100%; + float: left; + clear: both; +} + +.litetooltip-wrapper .tooltip-menu li { + padding: 0px; + margin: 0px; + list-style: none; + float: left; + border: solid 1px; + clear: both; + width: 100%; + overflow: hidden; +} + +.litetooltip-wrapper .tooltip-menu a { + display: block; + text-decoration: none; + padding: 5px; + margin: 0px; + clear: both; + min-width: 100%; + width: 100%; + float: left; +} + +.litetooltip-wrapper .tooltip-menu.AlizarinCrimson { + background: #df3030; +} + +.litetooltip-wrapper .tooltip-menu.AlizarinCrimson li { + border-color: #df3030; + border-bottom: solid 1px #d12b2b; +} + +.litetooltip-wrapper .tooltip-menu.AlizarinCrimson a { + color: #fff; +} + +.litetooltip-wrapper .tooltip-menu.AlizarinCrimson a:hover { + color: #000; + background: #f79992; +} + +.litetooltip-wrapper .tooltip-menu.Geradline { + background: #f79992; +} + +.litetooltip-wrapper .tooltip-menu.Geradline li { + border-color: #f79992; + border-bottom: solid 1px #ea8880; +} + +.litetooltip-wrapper .tooltip-menu.Geradline a { + color: #000; +} + +.litetooltip-wrapper .tooltip-menu.Geradline a:hover { + color: #fff; + background: #ee6a60; +} + +.litetooltip-wrapper .tooltip-menu.Conifer { + background: #a2d959; +} + +.litetooltip-wrapper .tooltip-menu.Conifer li { + border-color: #a2d959; + border-bottom: solid 1px #94c652; +} + +.litetooltip-wrapper .tooltip-menu.Conifer a { + color: #000; +} + +.litetooltip-wrapper .tooltip-menu.Conifer a:hover { + color: #fff; + background: #7fba00; +} + +.litetooltip-wrapper .tooltip-menu.Spindle { + background: #bfd9f0; +} + +.litetooltip-wrapper .tooltip-menu.Spindle li { + border-color: #bfd9f0; + border-bottom: solid 1px #d2e0ec; +} + +.litetooltip-wrapper .tooltip-menu.Spindle a { + color: #000; +} + +.litetooltip-wrapper .tooltip-menu.Spindle a:hover { + color: #fff; + background: #6699cc; +} + +.litetooltip-wrapper .tooltip-menu.BostonBlue { + background: #6699cc; +} + +.litetooltip-wrapper .tooltip-menu.BostonBlue li { + border-color: #6699cc; + border-bottom: solid 1px #4f83b7; +} + +.litetooltip-wrapper .tooltip-menu.BostonBlue a { + color: #fff; +} + +.litetooltip-wrapper .tooltip-menu.BostonBlue a:hover { + color: #000; + background: #bfd9f0; +} + +.litetooltip-wrapper .tooltip-menu.CarrotOrange { + background: #ed9122; +} + +.litetooltip-wrapper .tooltip-menu.CarrotOrange li { + border-color: #ed9122; + border-bottom: solid 1px #d47f19; +} + +.litetooltip-wrapper .tooltip-menu.CarrotOrange a { + color: #fff; +} + +.litetooltip-wrapper .tooltip-menu.CarrotOrange a:hover { + color: #000; + background: #fecf3d; +} + +.litetooltip-wrapper .tooltip-menu.Affair { + background: #7c4d94; +} + +.litetooltip-wrapper .tooltip-menu.Affair li { + border-color: #7c4d94; + border-bottom: solid 1px #8d60a4; +} + +.litetooltip-wrapper .tooltip-menu.Affair a { + color: #000; +} + +.litetooltip-wrapper .tooltip-menu.Affair a:hover { + color: #fff; + background: #a778bf; +} + +.litetooltip-wrapper .tooltip-menu.PaleConifer { + background: #bad87a; +} + +.litetooltip-wrapper .tooltip-menu.PaleConifer li { + border-color: #bad87a; + border-bottom: solid 1px #9db963; +} + +.litetooltip-wrapper .tooltip-menu.PaleConifer a { + color: #000; +} + +.litetooltip-wrapper .tooltip-menu.PaleConifer a:hover { + background: #f5ffbe; +} + +.litetooltip-wrapper .tooltip-menu.BrightSun { + background: #fec000; +} + +.litetooltip-wrapper .tooltip-menu.BrightSun li { + border-color: #fec000; + border-bottom: solid 1px #ebb203; +} + +.litetooltip-wrapper .tooltip-menu.BrightSun a { + color: #000; +} + +.litetooltip-wrapper .tooltip-menu.BrightSun a:hover { + background: #fecf3d; +} + +.litetooltip-wrapper .tooltip-menu.AmazonLemon { + background: #7fba00; +} + +.litetooltip-wrapper .tooltip-menu.AmazonLemon li { + border-color: #7fba00; + border-bottom: solid 1px #8ac903; +} + +.litetooltip-wrapper .tooltip-menu.AmazonLemon a { + color: #000; +} + +.litetooltip-wrapper .tooltip-menu.AmazonLemon a:hover { + background: #fde910; +} + +.litetooltip-wrapper .tooltip-menu.CoffeeConfetti { + background: #593737; +} + +.litetooltip-wrapper .tooltip-menu.CoffeeConfetti li { + border-color: #593737; + border-bottom: solid 1px #734f4f; +} + +.litetooltip-wrapper .tooltip-menu.CoffeeConfetti a { + color: #fff; +} + +.litetooltip-wrapper .tooltip-menu.CoffeeConfetti a:hover { + color: #000; + background: #e9d75a; +} + +.litetooltip-wrapper .tooltip-menu.OysterPrim { + background: #988d77; +} + +.litetooltip-wrapper .tooltip-menu.OysterPrim li { + border-color: #988d77; + border-bottom: solid 1px #786e59; +} + +.litetooltip-wrapper .tooltip-menu.OysterPrim a { + color: #000; +} + +.litetooltip-wrapper .tooltip-menu.OysterPrim a:hover { + background: #fdfeb8; +} + +.litetooltip-wrapper .tooltip-menu li.last-child { + border-bottom: 0px; +} + +.litetooltip-wrapper .image-right { + float: right; + margin: 0px 0px 0px 5px; + padding: 2px; +} + +.litetooltip-wrapper .image-left { + float: left; + margin: 0px 5px 0px 0px; + padding: 2px; +} + +.litetooltip-wrapper .video-wrapper { + padding-bottom: 56.26%; + position: relative; + width: 500px; +} + +.litetooltip-wrapper .video-wrapper iframe { + display: block; + width: 100%; + height: 100%; + top: 0; + left: 0px; + position: absolute; +} + +.litetooltip-wrapper .template { + float: left; +} + +.litetooltip-wrapper .template h4 { + margin: 0px; + padding: 2px 4px 4px 4px; + color: #fff; + font-size: 12px; + display: block; +} + +.litetooltip-wrapper .template p { + margin: 0px; + padding: 2px 4px; + display: block; + float: left; +} + +.litetooltip-wrapper .template ul, .litetooltip-wrapper .template ol { + margin: 0px; + padding: 5px 5px 5px 5px; + list-style-position: inside; +} + +.litetooltip-wrapper .template li { + padding: 2px 0px; +} + +.litetooltip-wrapper .template p, .litetooltip-wrapper .template ul, .litetooltip-wrapper .template ol { + background: #fff; + color: #333; +} + +.litetooltip-wrapper .template.AlizarinCrimson, .litetooltip-wrapper .template.AlizarinCrimson h4 { + background: #df3030; +} + +.litetooltip-wrapper .template.RadicalRed, .litetooltip-wrapper .template.RadicalRed h4 { + background: #ff1e53; +} + +.litetooltip-wrapper .template.Geradline, .litetooltip-wrapper .template.Geradline h4 { + background: #f79992; + color: #333333; +} + +.litetooltip-wrapper .template.Conifer, .litetooltip-wrapper .template.Conifer h4 { + background: #a2d959; +} + +.litetooltip-wrapper .template.Limeade, .litetooltip-wrapper .template.Limeade h4 { + background: #7fba00; +} + +.litetooltip-wrapper .template.AppleGreen, .litetooltip-wrapper .template.AppleGreen h4 { + background: #4cc744; +} + +.litetooltip-wrapper .template.Spindle, .litetooltip-wrapper .template.Spindle h4 { + background: #bfd9f0; + color: #333333; +} + +.litetooltip-wrapper .template.Danube, .litetooltip-wrapper .template.Danube h4 { + background: #6699cc; +} + +.litetooltip-wrapper .template.BostonBlue, .litetooltip-wrapper .template.BostonBlue h4 { + background: #4182c2; +} + +.litetooltip-wrapper .template.CarrotOrange, .litetooltip-wrapper .template.CarrotOrange h4 { + background: #ed9122; +} + +.litetooltip-wrapper .template.BrightSun, .litetooltip-wrapper .template.BrightSun h4 { + background: #fecf3d; + color: #333333; +} + +.litetooltip-wrapper .template.Affair, .litetooltip-wrapper .template.Affair h4 { + background: #7c4d94; +} + +.litetooltip-wrapper .template.HotRed, .litetooltip-wrapper .template.HotRed h4 { + background: #df3030; +} + +.litetooltip-wrapper .template.HotRed p, .litetooltip-wrapper .template.HotRed ul, .litetooltip-wrapper .template.HotRed ol { + background: #f79992; + color: #000; +} + +.litetooltip-wrapper .template.HuskyBlue, .litetooltip-wrapper .template.HuskyBlue h4 { + background: #4182c2; +} + +.litetooltip-wrapper .template.HuskyBlue p, .litetooltip-wrapper .template.HuskyBlue ul, .litetooltip-wrapper .template.HuskyBlue ol { + background: #bfd9f0; + color: #000; +} + +.litetooltip-wrapper .template.MoonAffair, .litetooltip-wrapper .template.MoonAffair h4 { + background: #7c4d94; +} + +.litetooltip-wrapper .template.MoonAffair p, .litetooltip-wrapper .template.MoonAffair ul, .litetooltip-wrapper .template.MoonAffair ol { + background: #e8cbf7; + color: #000; +} + +.litetooltip-wrapper .template.PaleMint, .litetooltip-wrapper .template.PaleMint h4 { + background: #7fba00; +} + +.litetooltip-wrapper .template.PaleMint p, .litetooltip-wrapper .template.PaleMint ul, .litetooltip-wrapper .template.PaleMint ol { + background: #f5ffbe; + color: #000; +} + +.litetooltip-wrapper .template.BlueRomance, .litetooltip-wrapper .template.BlueRomance h4 { + background: #0066ff; +} + +.litetooltip-wrapper .template.BlueRomance p, .litetooltip-wrapper .template.BlueRomance ul, .litetooltip-wrapper .template.BlueRomance ol { + background: #d2f6de; + color: #000; +} + +.litetooltip-wrapper .template.AmazonLemon, .litetooltip-wrapper .template.AmazonLemon h4 { + background: #7fba00; +} + +.litetooltip-wrapper .template.AmazonLemon p, .litetooltip-wrapper .template.AmazonLemon ul, .litetooltip-wrapper .template.AmazonLemon ol { + background: #fde910; + color: #000; +} + +.litetooltip-wrapper .template.LimeConfier, .litetooltip-wrapper .template.LimeConfier h4 { + background: #7fba00; +} + +.litetooltip-wrapper .template.LimeConfier p, .litetooltip-wrapper .template.LimeConfier ul, .litetooltip-wrapper .template.LimeConfier ol { + background: #a2d959; + color: #000; +} + +.litetooltip-wrapper .template.MustardSun, .litetooltip-wrapper .template.MustardSun h4 { + background: #ed9122; +} + +.litetooltip-wrapper .template.MustardSun p, .litetooltip-wrapper .template.MustardSun ul, .litetooltip-wrapper .template.MustardSun ol { + background: #fecf3d; + color: #000; +} + +.litetooltip-wrapper .template.AtollSea, .litetooltip-wrapper .template.AtollSea h4 { + background: #0a6f75; +} + +.litetooltip-wrapper .template.AtollSea p, .litetooltip-wrapper .template.AtollSea ul, .litetooltip-wrapper .template.AtollSea ol { + background: #fecf3d; + color: #000; +} + +.litetooltip-wrapper .template.BlazeOrange, .litetooltip-wrapper .template.BlazeOrange h4 { + background: #ff6600; +} + +.litetooltip-wrapper .template.BlazeOrange p, .litetooltip-wrapper .template.BlazeOrange ul, .litetooltip-wrapper .template.BlazeOrange ol { + background: #0a6f75; + color: #fff; +} + +.litetooltip-wrapper .template.CoffeeConfetti, .litetooltip-wrapper .template.CoffeeConfetti h4 { + background: #593737; +} + +.litetooltip-wrapper .template.CoffeeConfetti p, .litetooltip-wrapper .template.CoffeeConfetti ul, .litetooltip-wrapper .template.CoffeeConfetti ol { + background: #e9d75a; + color: #000; +} + +.litetooltip-wrapper .template.OysterPrim, .litetooltip-wrapper .template.OysterPrim h4 { + background: #988d77; +} + +.litetooltip-wrapper .template.OysterPrim p, .litetooltip-wrapper .template.OysterPrim ul, .litetooltip-wrapper .template.OysterPrim ol { + background: #fdfeb8; + color: #000; +} + +.litetooltip-hotspot-wrapper { + position: relative; + width: 100%; + height: auto; + z-index: 1; +} + +.litetooltip-hotspot-container { + position: relative; + height: 0px; +} + +.litetooltip-hotspot-container img { + position: absolute; + top: 0px; + left: 0px; + z-index: 2; +} + +.litetooltip-hotspot-container .hotspot { + position: absolute; + z-index: 3; + cursor: pointer; +} + +.litetooltip-hotspot-container .hotspot .data-container { + display: none; +} + +.litetooltip-hotspot-container .blink { + opacity: 0.8; + -moz-opacity: 0.8; + animation: litetooltip_hotspot_blink .6s ease-in infinite; + -moz-animation: litetooltip_hotspot_blink .6s ease-in infinite; + -ms-animation: litetooltip_hotspot_blink .6s ease-in infinite; + -webkit-animation: litetooltip_hotspot_blink .6s ease-in infinite; +} + +@keyframes litetooltip_hotspot_blink { + to { + opacity: 0.3; + } +} + +@-webkit-keyframes litetooltip_hotspot_blink { + to { + opacity: 0.3; + } +} + +@-moz-keyframes litetooltip_hotspot_blink { + to { + opacity: 0.3; + -moz-opacity: 0.3; + } +} + +@-ms-keyframes litetooltip_hotspot_blink { + to { + opacity: 0.3; + } +} \ No newline at end of file diff --git a/modules/appagebuilder/css/admin/form.css b/modules/appagebuilder/css/admin/form.css new file mode 100644 index 00000000..bbc316ef --- /dev/null +++ b/modules/appagebuilder/css/admin/form.css @@ -0,0 +1,1137 @@ +body{ + /* background-color: #ececec; */ +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + background-color: #ffffff; + background-clip: padding-box; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + white-space: normal; +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + margin: 0; + padding: 8px 14px; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover > .arrow, +.popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover > .arrow { + border-width: 11px; +} +.popover > .arrow:after { + border-width: 10px; + content: ""; +} +.popover.top > .arrow { + left: 50%; + margin-left: -11px; + border-bottom-width: 0; + border-top-color: #999999; + border-top-color: rgba(0, 0, 0, 0.25); + bottom: -11px; +} +.popover.top > .arrow:after { + content: " "; + bottom: 1px; + margin-left: -10px; + border-bottom-width: 0; + border-top-color: #ffffff; +} +.popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-left-width: 0; + border-right-color: #999999; + border-right-color: rgba(0, 0, 0, 0.25); +} +.popover.right > .arrow:after { + content: " "; + left: 1px; + bottom: -10px; + border-left-width: 0; + border-right-color: #ffffff; +} +.popover.bottom > .arrow { + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999999; + border-bottom-color: rgba(0, 0, 0, 0.25); + top: -11px; +} +.popover.bottom > .arrow:after { + content: " "; + top: 1px; + margin-left: -10px; + border-top-width: 0; + border-bottom-color: #ffffff; +} +.popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999999; + border-left-color: rgba(0, 0, 0, 0.25); +} +.popover.left > .arrow:after { + content: " "; + right: 1px; + border-right-width: 0; + border-left-color: #ffffff; + bottom: -10px; +} +.bootstrap .col-lg-2-4, .bootstrap .col-md-2-4, .bootstrap .col-sm-2-4, .bootstrap .col-xs-2-4, .bootstrap .col-sp-2-4, .bootstrap .col-lg-4-8, .bootstrap .col-md-4-8, .bootstrap .col-sm-4-8, .bootstrap .col-xs-4-8, .bootstrap .col-sp-4-8, .bootstrap .col-lg-7-2, .bootstrap .col-md-7-2, .bootstrap .col-sm-7-2, .bootstrap .col-xs-7-2, .bootstrap .col-sp-7-2, .bootstrap .col-lg-9-6, .bootstrap .col-md-9-6, .bootstrap .col-sm-9-6, .bootstrap .col-xs-9-6, .bootstrap .col-sp-9-6 { float: left; min-height: 1px; padding-left: 5px; padding-right: 5px; position: relative; } +@media (min-width:1120px) { + .bootstrap .col-lg-2-4 { width: 20%; } + .bootstrap .col-lg-4-8 { width: 40%; } + .bootstrap .col-lg-7-2 { width: 60%; } + .bootstrap .col-lg-9-6 { width: 80%; } + +} +@media (min-width: 992px) and (max-width: 1200px) { + + .bootstrap .col-md-2-4 {width:20%;} + .bootstrap .col-md-4-8 { width: 40%; } + .bootstrap .col-md-7-2 { width: 60%; } + .bootstrap .col-md-9-6 { width: 80%; } +} + +@media (max-width: 992px) and (min-width: 768px) { + + .bootstrap .col-sm-4-8 { width: 40%; } + .bootstrap .col-sm-7-2 { width: 60%; } + .bootstrap .col-sm-9-6 { width: 80%; } + +} + +@media (max-width: 768px) and (min-width: 481px) { + + .bootstrap .col-xs-4-8 { width: 40%; } + .bootstrap .col-xs-7-2 { width: 60%; } + .bootstrap .col-xs-9-6 { width: 80%; } + +} + +@media (max-width: 480px) { + + .bootstrap .col-sp-1 { width: 8.33333%; } + .bootstrap .col-sp-2 { width: 16.66667%; } + .bootstrap .col-sp-2-4 { width: 20%; } + .bootstrap .col-sp-3 { width: 25%; } + .bootstrap .col-sp-4 { width: 33.33333%; } + .bootstrap .col-sp-4-8 { width: 40%; } + .bootstrap .col-sp-5 { width: 41.66667%; } + .bootstrap .col-sp-6 { width: 50%; } + .bootstrap .col-sp-7 { width: 58.33333%; } + .bootstrap .col-sp-7-2 { width: 60%; } + .bootstrap .col-sp-8 { width: 66.66667%; } + .bootstrap .col-sp-9 { width: 75%; } + .bootstrap .col-sp-9-6 { width: 80%; } + .bootstrap .col-sp-10 { width: 83.33333%; } + .bootstrap .col-sp-11 { width: 91.66667%; } + .bootstrap .col-sp-12 { width: 100%; } + +} +.bootstrap .col-xl-1 { width: 8.33333%; } +.bootstrap .col-xl-2 { width: 16.66667%; } +.bootstrap .col-xl-2-4 { width: 20%; } +.bootstrap .col-xl-3 { width: 25%; } +.bootstrap .col-xl-4 { width: 33.33333%; } +.bootstrap .col-xl-4-8 { width: 40%; } +.bootstrap .col-xl-5 { width: 41.66667%; } +.bootstrap .col-xl-6 { width: 50%; } +.bootstrap .col-xl-7 { width: 58.33333%; } +.bootstrap .col-xl-7-2 { width: 60%; } +.bootstrap .col-xl-8 { width: 66.66667%; } +.bootstrap .col-xl-9 { width: 75%; } +.bootstrap .col-xl-9-6 { width: 80%; } +.bootstrap .col-xl-10 { width: 83.33333%; } +.bootstrap .col-xl-11 { width: 91.66667%; } +.bootstrap .col-xl-12 { width: 100%; } + +.col-lg .col-lg-1 { width: 8.33333%; } +.col-lg .col-lg-2 { width: 16.66667%; } +.col-lg .col-lg-2-4 { width: 20%; } +.col-lg .col-lg-3 { width: 25%; } +.col-lg .col-lg-4 { width: 33.33333%; } +.col-lg .col-lg-4-8 { width: 40%; } +.col-lg .col-lg-5 { width: 41.66667%; } +.col-lg .col-lg-6 { width: 50%; } +.col-lg .col-lg-7 { width: 58.33333%; } +.col-lg .col-lg-7-2 { width: 60%; } +.col-lg .col-lg-8 { width: 66.66667%; } +.col-lg .col-lg-9 { width: 75%; } +.col-lg .col-lg-9-6 { width: 80%; } +.col-lg .col-lg-10 { width: 83.33333%; } +.col-lg .col-lg-11 { width: 91.66667%; } +.col-lg .col-lg-12 { width: 100%; } + +.col-md .col-md-1 { width: 8.33333%; } +.col-md .col-md-2 { width: 16.66667%; } +.col-md .col-md-2-4 { width: 20%; } +.col-md .col-md-3 { width: 25%; } +.col-md .col-md-4 { width: 33.33333%; } +.col-md .col-md-4-8 { width: 40%; } +.col-md .col-md-5 { width: 41.66667%; } +.col-md .col-md-6 { width: 50%; } +.col-md .col-md-7 { width: 58.33333%; } +.col-md .col-md-7-2 { width: 60%; } +.col-md .col-md-8 { width: 66.66667%; } +.col-md .col-md-9 { width: 75%; } +.col-md .col-md-9-6 { width: 80%; } +.col-md .col-md-10 { width: 83.33333%; } +.col-md .col-md-11 { width: 91.66667%; } +.col-md .col-md-12 { width: 100%; } + +.col-sm .col-sm-1 { width: 8.33333%; } +.col-sm .col-sm-2 { width: 16.66667%; } +.col-sm .col-sm-2-4 { width: 20%; } +.col-sm .col-sm-3 { width: 25%; } +.col-sm .col-sm-4 { width: 33.33333%; } +.col-sm .col-sm-4-8 { width: 40%; } +.col-sm .col-sm-5 { width: 41.66667%; } +.col-sm .col-sm-6 { width: 50%; } +.col-sm .col-sm-7 { width: 58.33333%; } +.col-sm .col-sm-7-2 { width: 60%; } +.col-sm .col-sm-8 { width: 66.66667%; } +.col-sm .col-sm-9 { width: 75%; } +.col-sm .col-sm-9-6 { width: 80%; } +.col-sm .col-sm-10 { width: 83.33333%; } +.col-sm .col-sm-11 { width: 91.66667%; } +.col-sm .col-sm-12 { width: 100%; } + +.col-xs .col-xs-1 { width: 8.33333%; } +.col-xs .col-xs-2 { width: 16.66667%; } +.col-xs .col-xs-2-4 { width: 20%; } +.col-xs .col-xs-3 { width: 25%; } +.col-xs .col-xs-4 { width: 33.33333%; } +.col-xs .col-xs-4-8 { width: 40%; } +.col-xs .col-xs-5 { width: 41.66667%; } +.col-xs .col-xs-6 { width: 50%; } +.col-xs .col-xs-7 { width: 58.33333%; } +.col-xs .col-xs-7-2 { width: 60%; } +.col-xs .col-xs-8 { width: 66.66667%; } +.col-xs .col-xs-9 { width: 75%; } +.col-xs .col-xs-9-6 { width: 80%; } +.col-xs .col-xs-10 { width: 83.33333%; } +.col-xs .col-xs-11 { width: 91.66667%; } +.col-xs .col-xs-12 { width: 100%; } + +.col-sp .col-sp-1 { width: 8.33333%; } +.col-sp .col-sp-2 { width: 16.66667%; } +.col-sp .col-sp-2-4 { width: 20%; } +.col-sp .col-sp-3 { width: 25%; } +.col-sp .col-sp-4 { width: 33.33333%; } +.col-sp .col-sp-4-8 { width: 40%; } +.col-sp .col-sp-5 { width: 41.66667%; } +.col-sp .col-sp-6 { width: 50%; } +.col-sp .col-sp-7 { width: 58.33333%; } +.col-sp .col-sp-7-2 { width: 60%; } +.col-sp .col-sp-8 { width: 66.66667%; } +.col-sp .col-sp-9 { width: 75%; } +.col-sp .col-sp-9-6 { width: 80%; } +.col-sp .col-sp-10 { width: 83.33333%; } +.col-sp .col-sp-11 { width: 91.66667%; } +.col-sp .col-sp-12 { width: 100%; } + +#ap_loading{ + background-color: rgba(0, 0, 0, 0.6); + background: rgba(0, 0, 0, 0.6); + height: 100%; + left: 0; + position: fixed; + top: 0; + width: 100%; + z-index: 10000; + display: none; +} + +.spinner { + top: 50%; + left: 50%; + width: 100px; + height: 100px; + z-index: 10001; + position: relative; +} + +.cube1, .cube2 { + background-color: #5ca5bf; + width: 15px; + height: 15px; + position: absolute; + top: 0; + left: 0; + + -webkit-animation: cubemove 0.9s infinite ease-in-out; + animation: cubemove 1.8s infinite ease-in-out; +} + +.cube2 { + -webkit-animation-delay: -0.45s; + animation-delay: -0.45s; +} + +@-webkit-keyframes cubemove { + 25% { -webkit-transform: translateX(42px) rotate(-90deg) scale(0.5) } + 50% { -webkit-transform: translateX(42px) translateY(42px) rotate(-180deg) } + 75% { -webkit-transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5) } + 100% { -webkit-transform: rotate(-360deg) } +} + +@keyframes cubemove { + 25% { + transform: translateX(42px) rotate(-90deg) scale(0.5); + -webkit-transform: translateX(42px) rotate(-90deg) scale(0.5); + } 50% { + transform: translateX(42px) translateY(42px) rotate(-179deg); + -webkit-transform: translateX(42px) translateY(42px) rotate(-179deg); + } 50.1% { + transform: translateX(42px) translateY(42px) rotate(-180deg); + -webkit-transform: translateX(42px) translateY(42px) rotate(-180deg); + } 75% { + transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5); + -webkit-transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5); + } 100% { + transform: rotate(-360deg); + -webkit-transform: rotate(-360deg); + } +} +#top_wrapper{ + margin-bottom: 20px +} +#bottom_wrapper{clear: both;} +#bottom_wrapper .btn, +#top_wrapper .btn{ + background: #ededed; + border: none; + border-radius: 0; +} +#bottom_wrapper .btn:hover i, +#top_wrapper .btn:hover i, +#bottom_wrapper .btn:hover, +#top_wrapper .btn:hover{color: #000;} + +#home_wrapper{ + margin: 20px auto; +} +.hook-wrapper{border: 1px solid #ddd;} +.width-default{} +/*.width-large{width: 1200px;} +.width-medium{width: 992px;} +.width-small{width: 768px;} +.width-extra-small{width: 603px;} +.width-mobile{width: 480px;}*/ + +.hook-desc{ + position: absolute; +} +.hook-toggle{ + +} + +.hook-wrapper{ + background-color: #FFF; + margin-bottom: 10px +} + +.displayFooter{ + margin-top: 10px; +} +.displayLeftColumn, .displayRightColumn{ + min-height: 160px !important +} +.displayHome { + margin-bottom: 5px +} +.hook-top{ + min-height: 50px; + line-height: 50px +} +.hook-content{ + /*display: none;*/ +} +.icon-ok:before { + content: "\f00c"; +} +.group-action{ + margin-left: 5px +} +.group-action i{ + font-size: 15px +} +.group-row{ + background-color: #f5f5f5!important; + margin: 15px 10px!important; + position: relative; + padding: 40px 10px 10px; +} +.group-content{ + min-height: 30px +} +[class^="group-controll-"]{ + position: absolute; + top: 10px;} +.group-controll-right{ + right: 15px;} +.hook-content{ + padding: 0 +} +.hook-footer{ + width: 100% +} +.addnew-group{ + height: 20px; + width: 100%; +} +.addnew-group i{ + font-size: 30px; +} +#myModalLabel{ + padding: 0; + margin: 0; +} +.modal-body{ + min-height: 300px; + overflow: auto; +} +.shortcode{ + height: 40px; +} +.icon{ + font-size: 20px; +} +#modal_form .panel{ + border: 0 !important; + box-shadow:none !important; + padding: 0 !important; + border-radius: none !important; +} +#modal_form .panel-footer{ + margin: 0; +} +.ap-loading{ +/* display: none;*/ +} +.ui-widget-content{ + border: none; + background: transparent; +} +.hook-content-footer{margin-top: 30px; margin-bottom: 10px;} +.column-row{ + min-height: 100px; + margin-top:10px; + background: none; +} +.column-row .cover-column{ + border: 1px solid #fff; + background: #fff; + border-radius: 5px; + padding: 0 10px; +} +.column-content{ + min-height: 80px; + padding: 12px 0px; +} +.column-controll-right { + width: 20px; + position: absolute; + right: 8px; + top: 10px; + width: 60px; +} +.column-controll-right ul{min-width: 180px!important} +.column-controll-right a{ + width: 100%; +} +.column-controll-right button.btn{padding: 0; background: transparent!important;} +.column-row .width-val.ap-w-1, +.column-row .width-val.ap-w-2, +.column-row .width-val.ap-w-2-4, +.column-row .width-val.ap-w-3, +.column-row .width-val.ap-w-4, +.column-row .width-val.ap-w-4-8, +.column-row .width-val.ap-w-5, +.column-row .width-val.ap-w-6, +.column-row .width-val.ap-w-7, +.column-row .width-val.ap-w-7-2, +.column-row .width-val.ap-w-8, +.column-row .width-val.ap-w-9, +.column-row .width-val.ap-w-9-6, +.column-row .width-val.ap-w-10, +.column-row .width-val.ap-w-11, +.column-row .width-val.ap-w-12{background: url(../../img/admin/column.png) no-repeat 0 0;width: 23px;height: 11px;display: inline-block;} + +.column-row .width-val.ap-w-1{background-position: 0 bottom;} +.column-row .width-val.ap-w-2{background-position: 0 -379px;} +.column-row .width-val.ap-w-2-4{background-position: 0 -352px;} +.column-row .width-val.ap-w-3{background-position: 0 -325px;} +.column-row .width-val.ap-w-4{background-position: 0 -298px;} +.column-row .width-val.ap-w-4-8{background-position: 0 -271px;} +.column-row .width-val.ap-w-5{background-position: 0 -244px;} +.column-row .width-val.ap-w-6{background-position: 0 -217px;} +.column-row .width-val.ap-w-7{background-position: 0 -190px;} +.column-row .width-val.ap-w-7-2{background-position: 0 -163px;} +.column-row .width-val.ap-w-8{background-position: 0 -135px;} +.column-row .width-val.ap-w-9{background-position: 0 -108px;} +.column-row .width-val.ap-w-9-6{background-position: 0 -81px;} +.column-row .width-val.ap-w-10{background-position: 0 -54px;} +.column-row .width-val.ap-w-11{background-position: 0 -27px;} + +.column-row ul .width-val.ap-w-1, +.column-row ul .width-val.ap-w-2, +.column-row ul .width-val.ap-w-2-4, +.column-row ul .width-val.ap-w-3, +.column-row ul .width-val.ap-w-4, +.column-row ul .width-val.ap-w-4-8, +.column-row ul .width-val.ap-w-5, +.column-row ul .width-val.ap-w-6, +.column-row ul .width-val.ap-w-7, +.column-row ul .width-val.ap-w-7-2, +.column-row ul .width-val.ap-w-8, +.column-row ul .width-val.ap-w-9, +.column-row ul .width-val.ap-w-9-6, +.column-row ul .width-val.ap-w-10, +.column-row ul .width-val.ap-w-11, +.column-row ul .width-val.ap-w-12{ + padding-left: 30px; + display: block; + line-height: 11px; +} + +.column-add .width-val.ap-w-1, +.column-add .width-val.ap-w-2, +.column-add .width-val.ap-w-2-4, +.column-add .width-val.ap-w-3, +.column-add .width-val.ap-w-4, +.column-add .width-val.ap-w-5, +.column-add .width-val.ap-w-4-8, +.column-add .width-val.ap-w-6, +.column-add .width-val.ap-w-7, +.column-add .width-val.ap-w-7-2, +.column-add .width-val.ap-w-8, +.column-add .width-val.ap-w-9, +.column-add .width-val.ap-w-9-6, +.column-add .width-val.ap-w-10, +.column-add .width-val.ap-w-11, +.column-add .width-val.ap-w-12{ + background: url(../../img/admin/column.png) no-repeat 0 0; + text-indent: 28px; + height: 16px; + color: #333; + display: inline-block; +} + +.column-add .width-val.ap-w-1{background-position: 0 3px;} +.column-add .width-val.ap-w-2{background-position: 0 -160px;} +.column-add .width-val.ap-w-3{background-position: 0 -214px;} +.column-add .width-val.ap-w-4{background-position: 0 -241px;} +.column-add .width-val.ap-w-5{background-position: 0 -268px;} +.column-add .width-val.ap-w-6{background-position: 0 -295px;} +.column-add, .number-column { + padding: 2px 5px!important; + display: block; + text-decoration: none; +} +.column-add:hover, .number-column:hover { + background-color: #00aff0; + color: #fff; + text-decoration: none; +} +.list-group.dropdown-menu { + padding: 0; +} +.list-group li { + list-style-type: none; +} + +.number-column .width-val.ap-w-1, +.number-column .width-val.ap-w-2, +.number-column .width-val.ap-w-2-4, +.number-column .width-val.ap-w-3, +.number-column .width-val.ap-w-4, +.number-column .width-val.ap-w-5, +.number-column .width-val.ap-w-4-8, +.number-column .width-val.ap-w-6, +.number-column .width-val.ap-w-7, +.number-column .width-val.ap-w-7-2, +.number-column .width-val.ap-w-8, +.number-column .width-val.ap-w-9, +.number-column .width-val.ap-w-9-6, +.number-column .width-val.ap-w-10, +.number-column .width-val.ap-w-11, +.number-column .width-val.ap-w-12{ + background: url(../../img/admin/column.png) no-repeat 0 0; + height: 14px; + color: #333; + display: inline-block; +} +.number-column .width-val.ap-w-1{background-position: 0 bottom;} +.number-column .width-val.ap-w-2{background-position: 0 -379px;} +.number-column .width-val.ap-w-2-4{background-position: 0 -352px;} +.number-column .width-val.ap-w-3{background-position: 0 -325px;} +.number-column .width-val.ap-w-4{background-position: 0 -298px;} +.number-column .width-val.ap-w-4-8{background-position: 0 -271px;} +.number-column .width-val.ap-w-5{background-position: 0 -244px;} +.number-column .width-val.ap-w-6{background-position: 0 -217px;} +.number-column .width-val.ap-w-7{background-position: 0 -190px;} +.number-column .width-val.ap-w-7-2{background-position: 0 -163px;} +.number-column .width-val.ap-w-8{background-position: 0 -135px;} +.number-column .width-val.ap-w-9{background-position: 0 -108px;} +.number-column .width-val.ap-w-9-6{background-position: 0 -81px;} +.number-column .width-val.ap-w-10{background-position: 0 -54px;} +.number-column .width-val.ap-w-11{background-position: 0 -27px;} + +.number-column .width-val.ap-w-1, +.number-column .width-val.ap-w-2, +.number-column .width-val.ap-w-2-4, +.number-column .width-val.ap-w-3, +.number-column .width-val.ap-w-4, +.number-column .width-val.ap-w-5, +.number-column .width-val.ap-w-4-8, +.number-column .width-val.ap-w-6, +.number-column .width-val.ap-w-7-2, +.number-column .width-val.ap-w-7, +.number-column .width-val.ap-w-8, +.number-column .width-val.ap-w-9, +.number-column .width-val.ap-w-9-6, +.number-column .width-val.ap-w-10, +.number-column .width-val.ap-w-11, +.number-column .width-val.ap-w-12{ + padding-left: 30px; + display: block; +} +.group-add .width-val.ap-w-0, +.group-add .width-val.ap-w-1, +.group-add .width-val.ap-w-2, +.group-add .width-val.ap-w-2-4, +.group-add .width-val.ap-w-3, +.group-add .width-val.ap-w-4, +.group-add .width-val.ap-w-5, +.group-add .width-val.ap-w-4-8, +.group-add .width-val.ap-w-6, +.group-add .width-val.ap-w-7-2, +.group-add .width-val.ap-w-7, +.group-add .width-val.ap-w-8, +.group-add .width-val.ap-w-9, +.group-add .width-val.ap-w-9-6, +.group-add .width-val.ap-w-10, +.group-add .width-val.ap-w-11, +.group-add .width-val.ap-w-12{ + background: url(../../img/admin/column.png) no-repeat 0 0; + text-indent: 28px; + height: 16px; + color: #333; + display: inline-block; +} + +.group-add .width-val.ap-w-0{background-position: -300px 0px;} +.group-add .width-val.ap-w-1{background-position: 0 3px;} +.group-add .width-val.ap-w-2{background-position: 0 -160px;} +.group-add .width-val.ap-w-3{background-position: 0 -214px;} +.group-add .width-val.ap-w-4{background-position: 0 -241px;} +.group-add .width-val.ap-w-5{background-position: 0 -268px;} +.group-add .width-val.ap-w-6{background-position: 0 -295px;} +.group-add, .number-group { + padding: 2px 5px!important; + display: block; + text-decoration: none; +} +.group-add:hover, .number-group:hover { + background-color: #00aff0; + color: #fff!important; + text-decoration: none; +} +.group-add:hover span, .number-column:hover span, .column-add:hover span { + color: #fff!important; +} +.column-controll-bottom{text-align: center;margin-bottom: 5px;} +.ap_tabs, .ApTabs { + margin-top: 10px +} +a.ui-widget-header{background: none; border: none;} +.column-controll-top{ + margin-top: 10px;} +.widget-row{ + border: 1px solid #ddd; + position: relative; +/* min-height: 42px; */ + margin-bottom: 20px; + padding: 10px; +} +.ui-helper-clearfix:after{ + clear: none +} +.widget-row:hover .widget-controll-top{ + display: block; +} +.float-center-control{ + /* margin-top: -20px; */ + z-index: 100; + padding: 0 0 10px; +} +.tab-content-control{ + /* margin-top: -25px; */ +} +.subwidget-content{ + margin-top: 10px; +} +.tab-pane{ + position: relative +} +.nav-tabs{ + min-height: 70px +} +.tab-button{ + +} +.tab-button a:hover, .tab-button a:active, .tab-button a:focus{ + background:none !important; + border: none !important; + box-shadow:none !important; +} +#default_tabnav, #default_tabcontent{ + display: none; +} +.widget-controll-top{ + display: none; + background: #00aff0!important; + padding: 2px 10px; + position: absolute; + top: 50%; + margin-top: -12px; + left: 50%; + margin-left: -54px; + border: none!important; + border-radius: 3px; +} +.widget-controll-top i{color: #fff;} +.widget-controll-top .ui-widget-header{background: none;border: none;} +.widget-title, .widget-img .w-img, .widget-icon .w-icon{ + display: inline-block; + float: left; + margin-right: 5px; +} +.widget-img .w-icon, .widget-icon .w-img{ + display: none; +} +.form_ap_raw_html .form-wrapper .form-group > label.control-label, .form_ap_raw_html .form-wrapper > .form-group > div{ + width: 100% !important; + text-align: left; +} +#configuration_form .ap_html_raw { + min-height: 200px; +} +.modal-edit .btn-back-to-list{ + display: none; +} +.btn-status.deactive{ + color: #ddd!important; +} +.ap-col-class{ + padding-left: 0 +} +ul.ap-col-class li { +display: inline-block; +padding: 5px 10px; +} +#animationSandbox{ + font-size: 40px +} +#animation, .animate-it{display: inline-block;margin-left: 5px} +.control-right div{display: inline-block} + +/*product style*/ +.product-container{ +margin-right: 0; +margin-left: 0; +border: 1px solid #ddd; +border-radius: 4px 4px 0 0; +-webkit-box-shadow: none; +box-shadow: none; +position: relative; +} +.desc-box { +position: absolute; +top: -1px; +right: -1px; +display: block; +padding: 5px 8px; +font-size: 12px; +color: #777; +cursor: pointer; +border: 1px solid #e1e1e8; +border-radius: 0 4px; +} +.left-block, .right-block { + position: relative; + margin-top: 30px; + display: block +} +.left-block .panel-heading, .right-block .panel-heading{ + text-transform: lowercase !important +} +.content{border: 1px dashed #ddd;padding: 10px} +.plist-element{ + border: 1px solid #ddd; + border-radius:4px; + padding: 3px 3px 3px 10px; + margin-bottom: 5px; + cursor: move; + min-width: 242px +} +/******************DONGND CSS FOR LAYOUT BEGIN ***********************/ +.widget-row.plist-element{ + margin-bottom: 5px; + padding: 5px 10px; +} + +.column-row.plist-element{ + background: none; + border: none; +} + +.column-row.plist-element .content{ + border: none; +} + +.ap_proGrid .group-row .desc-box +{ + background: #fff; +} + +.ap_proGrid .group-button +{ + clear: both; + text-align: center; +} +/******************DONGND CSS FOR LAYOUT END ***********************/ +.adminappagebuilderdetails .plist-element{ + cursor: default; +} +.adminappagebuilderdetails .gaction-drag{ + cursor: move; +} +.plist-eremove, .plist-eedit, .plist-code{cursor: pointer} +.element-list .plist-eremove, .element-list .plist-code, .element-list .btn-edit-group{display: none;} +.product-container .plist-eedit{display: none} +.image_container{ + padding: 20px 10px; +} +.functional_buttons, .code{ + padding: 40px 10px; + position: relative +} +.code{padding: 30px 10px 10px} +.functional_buttons .desc-box, .code .desc-box{ + right: auto; + left: -1px; + border-radius: 4px 0; + font-size: 11px +} +.element-list .content-code{display: none;} +.functional_buttons > .pull-right, .code > .pull-right{ + position: absolute; + top: 1px; + right: 1px; +} +body.ap-hide #nav-sidebar,body.ap-hide #header{ + display: none; +} +.modal-widget-title{ + display: none; +} +.sperator{ + background-color:#eee !important;border-bottom:solid 1px #ccc !important; + width: 100% +} +.hook-info > a:focus{outline: none;} +.hook-info > a{text-transform: uppercase; color: #666666;font-size: 14px;} +.hook-info > a:hover i{} +.hook-info > a i{ + float: right; +} + +.hook-info > a i:before{ + width: 30px; height: 30px; background: #f1f1f1; display: inline-block; + margin-top: 10px; margin-right: 10px;line-height: 30px; +} +.hook-info > a i.icon-circle-arrow-down:before{margin-top: 20px;} +.hook-info > a i.icon-circle-arrow-up:before{ +} +.space{ + border-bottom: solid 1px #eee; + padding: 0 0 0 5px; + color:#00aff0 +} +.field-link { + line-height: 30px; + display: block; +} +.btn-fwidth.active { + background-color: #ccc !important; + color: #000!important; +} +#list-slider { + padding-left: 0; +} +#list-slider li { + background-color: #f5f5f5; + clear: both; + display: inline-block; + list-style-type: decimal !important; + margin-bottom: 1px; + padding: 3px; + width: 100%; + border: 1px solid #bdbdbd; +} +#list-slider li:hover { + background-color: #fbf5f5; + border: 1px solid #cfcfcf; +} +#s-image { + max-width: 100%; +} +.tree-selected .choose-img, .tree-selected .remove-img { + color: #fff; +} +.tree-selected .choose-img:hover, .tree .remove-img:hover { + color: #8bc954; +} +.list-image, .list-image .choose-img, .tree .remove-img { + display: inline; +} +.list-image > img { + max-height: 16px !important; + max-width: 16px !important; +} +#live-edit-iframe { + border: medium none; + width: 100%; +} +.ap-live-tool { + background-color: #cccccc; + color: #33691e; + height: 30px; + line-height: 30px; + padding-left: 10px; + width: 100%; + text-transform: uppercase; +} +#cover-live-iframe { + width: 100%; + background-color:rgba(0, 0, 0, 0.6); + box-shadow: 0 0 5px #bdbdbd; + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + -ms-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} +#cover-live-iframe.full-screen { + height: 100%; + left: 0; + position: fixed; + top: 0; + z-index: 2000; + -webkit-transition: all 0.3s ease-in-out; + -moz-transition: all 0.3s ease-in-out; + -o-transition: all 0.3s ease-in-out; + -ms-transition: all 0.3s ease-in-out; + transition: all 0.3s ease-in-out; +} +#cover-live-iframe.full-screen #live-edit-iframe { + border: medium none; + bottom: 0; + height: 96% !important; + left: 0; + position: relative; + width: 100% !important; + -webkit-transition: all 0.3s ease-in-out; + -moz-transition: all 0.3s ease-in-out; + -o-transition: all 0.3s ease-in-out; + -ms-transition: all 0.3s ease-in-out; + transition: all 0.3s ease-in-out; +} +.ap-live-tool a { + background-color: #fff; + padding: 0 6px; + float: right; +} + +.ApAccordions .panel-body{ + border: none!important; + padding: 0; +} +.ApAccordions .panel-title a{ + display: block; + line-height: 30px; +} +.ApAccordions .panel-heading{border-radius: 3px;} +.export-from.btn-export { + text-align: left!important; +} +.export-from.btn-export:hover { + background-color:#00AFF0!important; + color:#fff!important; +} +#list-imgs { + padding-left: 10px; + list-style: none; +} +#list-imgs li{ + float: left; + width: 20%; + text-align: center; + margin-bottom: 15px; +} +#list-imgs li a{ + display: inline-block; + margin-bottom: 10px; +} + +.modal-dialog{ + width: 900px; +} +textarea.item-add-slide { + min-height: 150px; +} + +#configuration_form #list-slider li img { + max-width: 50px; + padding: 3px; + border: 3px solid #eee; +} + +#configuration_form #list-slider.ul-apimage360 li img{ + max-width: 100px; + border-width: 1px; +} + +/********************DONGND:: fix ApTab BEGIN*************************/ +.ApTabs .nav-tabs a:focus{ + outline: none; +} +/********************DONGND:: fix ApTab END*************************/ + +/********************DONGND:: CSS For Section Select Animation For Group And Column BEGIN*************************/ +.animation-button +{ + border-radius: 3px !important; +} + +.animation-wrapper +{ + display: none; + position: absolute; + top: 100%; + margin: 2px 0 0; + padding: 15px 5px 0; + border: 1px solid rgba(0,0,0,0.15); + background-color: #fff; + -webkit-box-shadow: 0 6px 12px rgba(0,0,0,0.175); + box-shadow: 0 6px 12px rgba(0,0,0,0.175); + background-clip: padding-box; + border-radius: 3px; + z-index: 100; + width: 480px +} + +.animation-wrapper.offset-right +{ + right: 0; +} +.animation-wrapper .animationSandbox +{ + font-size: 40px; +} + +.animation-wrapper .animate_sub +{ + display: none; +} + +.animation-wrapper .btn-save-animation +{ + margin: 0 10px; +} + +.animation-wrapper .animate_loop +{ + margin-bottom: 0; +} + +.animation-wrapper .animationSandbox +{ + z-index: 9; +} +.animation-button.btn-success i.icon-magic +{ + color: #fff; +} +/********************DONGND:: CSS For Section Select Animation For Group And Column END*************************/ + +.temp_description { + min-height: 150px; +} + +/******************* DONGND:: CSS for search image at image manager BEGIN *******************/ +.search-image-group{ + position: absolute !important; + right: 0; + top: 0; + z-index: 999; +} +.search-image +{ + width: 200px !important; + float: left; +} +/******************* DONGND:: CSS for search image at image manager END *******************/ + +/******************* ADD SHORT CODE NOT SHOW MODULES - BEGIN *******************/ +.adminappagebuildershortcode.modal-open #modal_form #popup_list_module +{ + display : none +} +/******************* ADD SHORT CODE NOT SHOW MODULES - END *******************/ \ No newline at end of file diff --git a/modules/appagebuilder/css/admin/images.css b/modules/appagebuilder/css/admin/images.css new file mode 100644 index 00000000..412aeb35 --- /dev/null +++ b/modules/appagebuilder/css/admin/images.css @@ -0,0 +1,46 @@ +/*.adminleosliderlayer #main .bootstrap, .adminleosliderlayer #header, .adminleosliderlayer #footer{display: none} +.adminleosliderlayer #main{margin: 0;padding: 0} +.adminleosliderlayer #content{margin: 0 !important;padding:0 !important} +.adminleosliderlayer .page-head{display: none}*/ +.adminleosliderlayer #header, .adminleosliderlayer #footer, .adminleosliderlayer #nav-sidebar, .page-head{ + display: none; +} +.adminappagebuilderimages #header,.adminappagebuilderimages #footer,.adminappagebuilderimages #nav-sidebar,.adminappagebuilderimages .page-head{ + display: none; +} +.page-sidebar #content, .adminleosliderlayer #main{margin: 0;padding: 0} +#list-imgs { +padding-left: 0; +padding-bottom: 1px; +margin-bottom: 20px; +list-style: none; +overflow: hidden; +} +#list-imgs li a{ + font-size: 11px +} +#list-imgs li { +float: left; +width: 20%; +height: 115px; +padding: 10px 5px; +margin: 0 -1px -1px 0; +font-size: 12px; +line-height: 1.4; +text-align: center; +border: 1px solid #ddd; +} +.img-row{ + overflow: hidden; + height: 80px; +} +.typos{ + padding: 10px +} +.typos-wrap .typo { + position: relative; + min-height: 60px; +} +.typos-wrap .typo-big{ + min-height: 123px +} \ No newline at end of file diff --git a/modules/appagebuilder/css/admin/index.php b/modules/appagebuilder/css/admin/index.php new file mode 100644 index 00000000..6bf70e95 --- /dev/null +++ b/modules/appagebuilder/css/admin/index.php @@ -0,0 +1,36 @@ + +* @copyright 2007-2012 PrestaShop SA +* @version Release: $Revision: 13573 $ +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/modules/appagebuilder/css/admin/style.css b/modules/appagebuilder/css/admin/style.css new file mode 100644 index 00000000..bcd7fae4 --- /dev/null +++ b/modules/appagebuilder/css/admin/style.css @@ -0,0 +1,376 @@ +.fl {float: left!important;} +.fr {float: right!important;} +.list-all-hooks a { + margin-left: 5px; + display: inline-block; +} +.icon-AdminApPageBuilder:before { + content: "\f044"; +} + +#home_wrapper .position-cover { + border: 1px solid #00aff0; + box-shadow: 0 0 5px #eee; + padding: 5px; + margin-bottom: 30px; + transition: all 0.3s ease 0s; +} +#home_wrapper .position-cover:hover { + box-shadow: 0 0 5px #bdbdbd; + transition: all 0.6s ease 0s; +} +.position-area { + min-height: 100px; + clear: both; +} +.bootstrap .tree-panel-heading-controls { + margin: -2px 0 20px!important; +} +.modal-body { + /*overflow: hidden!important;*/ +} +.column-controll-right .btn-group .btn { + background-color: #bbb; + transition: all 0.2s ease 0s; +} +.column-controll-right .btn-group .btn:hover { + transition: all 0.3s ease 0s; + background-color: #333; +} +.position-cover .list-position span { + display: inline-block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: 150px; + line-height: 12px; +} +.box-edit-position { + background-color: #fff; + box-shadow: 0 0 5px; + padding: 20px; + position: absolute; + right: 0; + width: 300px; + z-index: 1; +} +.position-cover .list-position i:hover { + color: #000!important; +} +.position-name i { + color: #fff; +} +.modal.ui-draggable { + top:0!important; +} +.item a { + display: table-cell; + height: 65px !important; + vertical-align: middle; + padding: 0 10px 0 40px; +} +.cover-short-code { + background-color: #f5f5f5; + border: 1px solid transparent; + margin: 5px 0; + cursor: pointer; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + transition: all 0.2s ease 0s; + box-shadow: 0 -2px 0 #e6e6e6 inset; + height: 65px; + overflow: hidden; +} +.cover-short-code:hover { + background-color: #ededed; + transition: all 0.4s ease 0s; + color: #333; + box-shadow: 0 -2px 0 #bdbdbd inset; +} +.cover-short-code .icon { + left: 20px; + position: absolute; + top: 35px; +} +.cover-short-code .label { + position: relative; + font-weight: bold; + color: #0066CC; + white-space:normal; + padding: 0!important; + margin: 0!important; +} +.cover-short-code:hover .label { + color: #333; + text-decoration: underline; +} +.cover-short-code:hover .icon { + color: #333; +} + +#txt-search { + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset; + border: 1px solid #ccc; + background-color: #fff; +} +#txt-search:hover, #txt-search:focus { + box-shadow: 0 -2px 0 #bdbdbd inset!important; + background-color: #fff7d0; +} +.box-search-widget { + opacity: 1; + float: right; + margin-right: 10px; + margin-top: -5px; +} + +#tab-new-widget { + border-bottom: 1px solid #ddd; + min-height: 40px; +} +#modal_form .tab-content { + margin-top: 10px; +} +#modal_form .btn.is-checked { + font-weight: bold; + color: #333; + border: 1px dashed #ddd; +} +img.icon { + max-width: 20px; +} +#list-slider li { + cursor: move; +} +.list-link-block { + list-style-type: none; + padding: 0; +} +.list-link-block > li { + background-color: #f5f5f5; + display: inline-block; + padding: 10px 0; + width: 100%; +} +.list-link-block > li .btn-remove-block-link { + display: block; +} +.list-link-block > li:hover .btn-remove-block-link { + display: block; +} +.link_group{ + background-color: #f5f5f5; +} +.link_group .form-group{ + margin-bottom: 5px; +} +.form-group.link_group{ + margin-bottom: 15px; +} +.link_group > .form-group:first-child{ + margin-top: 10px; +} +.link_group > .form-group .form-group{ + margin-bottom:0px; +} +.link_group > .form-group:last-child{ + margin-bottom: 10px; +} +.latest-blog-category { + background-color: #fefefe; + border: 1px solid #ccc; + padding: 10px 0; +} +.latest-blog-category ol, .latest-blog-category li { + list-style-type: none; +} +.list-font-awesome { + clear: both; + margin: 10px 0 !important; + padding: 0; +} +.list-font-awesome > li, .preview-widget { + border: 1px solid #bdbdbd; + cursor: pointer; + float: left; + list-style-type: none; + margin: 5px; + padding: 5px; + text-align: center; + width: 30px; +} +.list-font-awesome .selected, .list-font-awesome > li:hover { + background-color: #333; + color: #fff; + transition: all 0.3s ease 0s; +} +.preview-widget { + +} +.dropdown-menu-right .selected { + background-color: #bdbdbd; +} +#s-image{margin: 10px 0;} +.open-content i{ + margin-left:7px; +} +span.open-content { + cursor : pointer; +} +.row-actived>a{ + text-align: center; + display: block; +} + +.product-container .row-preactive, .element-list .btn-add-column{ + display: none; +} +.adminappagebuilderdetails #home_wrapper { + margin: 20px auto; +} +.adminappagebuilderdetails .gridLeft-block-content{ + min-height: 300px; + height: auto; + overflow: auto; +} +.adminappagebuilderdetails .column-action a{ + color: #ededed +} +/* +.adminappagebuilderdetails .column-row .cover-column{ + margin-right: -5px; + margin-left: -5px; +} +*/ +.adminappagebuilderdetails .cover-column{ + +} +.adminappagebuilderdetails .column-row .content{ + /* + padding: 20px; + */ + padding: 30px 10px 10px 10px; +} +.adminappagebuilderdetails .plist-eremove{ + color: red +} + + +#product-demo-sample{ + margin-bottom: 30px; +} +#product-demo-sample .item-demo{ + margin: 10px 0; +} +#product-demo-sample .item-demo .block-image{ + height: 290px; + overflow: hidden; + position: relative; + border: 1px solid #c9ccd3; +} +#product-demo-sample .item-demo .block-image::before{ + content: ''; + position: absolute; + z-index: 8; + top: 0px; + left: 0px; + right: 0px; + bottom: 0px; + opacity: 0; + background: #00000082; + -moz-transition: all 0.3s ease; + -o-transition: all 0.3s ease; + -ms-transition: all 0.3s ease; + -webkit-transition: all 0.3s ease; + transition: all 0.3s ease; +} +#product-demo-sample .item-demo .block-image img{ + position: absolute; + top: 0px; + left: 0px; + right: 0px + z-index: 7; +} +#product-demo-sample .item-demo .block-image a{ + position: absolute; + top: 50%; + left: 50%; + z-index: 9; + font-size: 13px; + padding: 5px 10px; + opacity: 0; + -moz-transform: translate(-50%,-50%); + -o-transform: translate(-50%,-50%); + -ms-transform: translate(-50%,-50%); + -webkit-transform: translate(-50%,-50%); + transform: translate(-50%,-50%); + -moz-transition: all 0.3s ease; + -o-transition: all 0.3s ease; + -ms-transition: all 0.3s ease; + -webkit-transition: all 0.3s ease; + transition: all 0.3s ease; +} +#product-demo-sample .item-demo .block-image:hover a, +#product-demo-sample .item-demo .block-image:hover:before{ + opacity: 1; +} +#product-demo-sample .item-demo .block-name{ + text-align: center; + font-size: 13px; + background-color: #4D576E; + color: #fff; + padding: 10px; + border-bottom: solid 1px #fff; + border-radius: 0 0 5px 5px; +} + + +@media (min-width: 575px) and (max-width: 991px){ + #product-demo-sample > [class*="col-"]:nth-child(2n + 1){ + clear: both; + } +} +@media (min-width: 992px) and (max-width: 1199px){ + #product-demo-sample > [class*="col-"]:nth-child(3n + 1){ + clear: both; + } +} +@media (min-width: 1200px) and (max-width: 1399px){ + #product-demo-sample > [class*="col-"]:nth-child(4n + 1){ + clear: both; + } +} +@media (min-width: 1400px) and (max-width: 1699px){ + #product-demo-sample > [class*="col-"]{ + width: 20%; + } + #product-demo-sample > [class*="col-"]:nth-child(5n + 1){ + clear: both; + } +} +@media (min-width: 1700px){ + #product-demo-sample > [class*="col-"]{ + width: 16.66667%; + } + #product-demo-sample > [class*="col-"]:nth-child(6n + 1){ + clear: both; + } +} +@media(max-width: 576px){ + #product-demo-sample > [class*="col-"]{ + width: 100%; + } +} + +.aprow_rtl button{ + min-width: 200px !important; + text-align: left !important; + padding-left: 10px !important; +} +#modal_form .modal-dialog { + width: 1200px; +} +#modal_form .modal-lg { + width: 1200px; +} \ No newline at end of file diff --git a/modules/appagebuilder/css/admin/style_AdminApPageBuilderThemeConfiguration.css b/modules/appagebuilder/css/admin/style_AdminApPageBuilderThemeConfiguration.css new file mode 100644 index 00000000..c3b2e406 --- /dev/null +++ b/modules/appagebuilder/css/admin/style_AdminApPageBuilderThemeConfiguration.css @@ -0,0 +1,49 @@ +.t_span4 { + padding-left: 0 !important; + padding-right: 20px !important; +} +.form-group.aprow_font_option{ + margin-bottom: 20px; +} +.t_span4 .title-item { + font-size: 1.3em; + line-height: 1.5em; +} +.t_span4.col-lg-4 { + margin-bottom: 0px; +} +.t-help-block{ + color: #959595; +} +.t-group-attr{ + color: #333 !important; + font-size: 1.4em !important; + font-weight: 600 !important; + line-height: 1.4em !important; + margin-bottom: 10px !important; + margin-left: 0 !important; + margin-right: 0 !important; + margin-top: 10px !important; +} +.t-group-attr-h3{ + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + float: left; + margin-right: 45px; + padding: 10px 15px; + font-size: 18px; + line-height: 1.2; + margin-bottom: 0; + font-weight: 300; + margin: 0; +} +#modal_form .modal-dialog{ + width: 900px; +} +#modal_form .modal-backdrop.fade.in +{ + opacity: .5; +} +#modal_form .modal-dialog{ + z-index: 1050; +} + diff --git a/modules/appagebuilder/css/admin/style_hook_cpanel.css b/modules/appagebuilder/css/admin/style_hook_cpanel.css new file mode 100644 index 00000000..69dadaf1 --- /dev/null +++ b/modules/appagebuilder/css/admin/style_hook_cpanel.css @@ -0,0 +1,216 @@ +.clearfix:before,.clearfix:after{content:".";display:block;height:0;overflow:hidden}.clearfix:after{clear:both}.clearfix{zoom:1} + .leotheme-layout{ + background:#f2f2f2; + width:800px; + margin:10 auto;padding:14px + } + .leotheme-layout > div, .leotheme-layout > div div{ + position:relative; + } + .leo-container{ background:#dcdcdc; margin:0px 0px; position:relative; } + #leo-displaynav, #leo-header .topbar, #leo-menu, #leo-slideshow, #leo-displayTopColumn,#leo-bottom ,#leo-hfooter{ + min-height:40px; + padding-top:26px; + padding-bottom:9px; + } + + + #leo-content { + clear:both; + display:block; + background:#dcdcdc + } + #leo-content #leo-left,#leo-content #leo-right{ width:25%;float:left; min-height:200px} + #leo-content .leo-container,#leo-hheaderright {margin:0; padding-top:26px; padding-bottom:9px } + #leo-center{ + background: #dcdcdc; + + float: left; + min-height: 200px; + width: 50%; + } + #leo-center .leo-container{ + border-left: 1px solid #CCCCCC; + border-right: 1px solid #CCCCCC; + height:100%; + } + + #leologo{ width:18%;float:left; min-height:60px} + #leo-hheaderright{ + display:block; + float:right; + width:80%; + min-height:60px; + } + .placeholder{ + background:#FFFFBB; + } + .module-pos{ + max-width:299px; + margin:6px; + margin-left: 12px; + cursor:move; + } + .leo-editmodule{ + background:#FFF; + + padding:5px 8px; + border:solid 1px #CCC; + font-size:10px; + } + .leo-editmodule img{width:14px} + .leo-container > div{ + position:relative; + } + + .module-pos .editmod{ + background: url(../../img/admin/edit.png) no-repeat center center #DFF0D8; + padding: 10px; + position: absolute; + right: 4px; + top: 3px; + z-index: 10; + } + + #leo-page .pos{ + font-size: 11px; + font-weight: bold; + left: 0; + padding: 4px 12px; + position: absolute; + top: 0; + background:#FFF; + z-index:10 + } + .leotheme-layout{ + width:72%; + float:left + } + .holdposition{ + width:28%; + float:left; + min-height:600px; + background:#e1e1e1; + padding-top:24px; + margin-top:14px + } +#overidehook{ + background:#EEE; + padding:12px; + position:absolute; + z-index:99; + -webkit-box-shadow: 0 1px 2px #000; + -moz-box-shadow: 0 1px 2px #000; + box-shadow:0 1px 2px #000; + border:solid 1px #666 +} +#overidehook #oh-close{ + font-size:10px; font-weight:bold; + cursor:hand; cursor:pointer +} +#leo-copyright{ + float:left; + width:50%; + margin-top:40px +} +#leo-footnav{ + min-height:50px; + padding-top:24px; + float:right; + width:48% +} +#leo-footer-buider{ + + background:#DCDCDC; + padding: 12px; + font-weight: bold; + text-transform: uppercase; + text-align: center + +} +.form-fonts .group-fields{ + border: solid 1px #EBEDF4; + margin-bottom: 12px; + padding: 12px; +} +.help-context-adminmodules{ + display: none!important; +} +.process-icon-liveedit{ + background-image: url("../../img/admin/live-edit.png"); +} +.process-icon-livethemeeditor { + background-image: url("../../img/admin/theme-editor.png"); +} +.process-icon-controlpanel { + background-image: url("../../img/admin/control-panel.png"); +} + .note, #leo-page .note ul li{ + font-size:10px; font-weight:normal; +} + +.vtab-mode > ul{ + display: block; + width: 220px; + float: left; + +} +.vtab-mode > ul li { + background: #bdc3c7; + display: block; + width: 100%; + padding:10px 0; + margin-bottom: 1px; +} +.vtab-mode > ul li a{ padding: 12px; color: #FFF } +.vtab-mode > ul li.active{ background:#7f8c8d; } +.vtab-mode > div{ + overflow: hidden; + border: #f3f3f3 solid 1px; + padding: 12px; + margin:12px 0; +} + + +/** + * + */ + h2{ color: #F0776C; font-size: 18px } + h3 b{ color:#20AAE5; text-transform: uppercase;} + .custom-form .toolbarBox .pageTitle h3{ + font-size: 12px; + } + + .custom-form .ui-widget-header{ + background: none; + border: none; + margin-top: -39px; + } + .custom-form fieldset{ border: none; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited{ + background-image:none; +} +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active{ + border-color: #E6E6E6 +} +.ui-tabs .ui-tabs-nav li a{ + padding:7px 28px; + font-size: 13px; +} +.ui-widget-content, .custom-form .toolbarBox { + border-color: #E6E6E6 +} +.inner li { + line-height:18px; + } +#leo-form-setting { margin-top: 60px; font-size: 13px } +#leo-form-setting label { font-size: 12px } +#leo-form-setting .separation { border-collapse: #E6E6E6 } + #leo-form-setting .inner {padding: 12px } + #themecontrol-form, #themecontrol-form label, #themecontrol-form input, #themecontrol-form textarea { + font-size:12px; + } + +.leo_top_25{ + margin-top: 25px; +} \ No newline at end of file diff --git a/modules/appagebuilder/css/admin/themeeditor.css b/modules/appagebuilder/css/admin/themeeditor.css new file mode 100644 index 00000000..7fdf6e4b --- /dev/null +++ b/modules/appagebuilder/css/admin/themeeditor.css @@ -0,0 +1,209 @@ +.adminappagebuilderthemeeditor #header,.adminappagebuilderthemeeditor #footer,.adminappagebuilderthemeeditor #nav-sidebar,.adminappagebuilderthemeeditor .page-head{ + display: none; +} + +html,body,#content,#livethemeeditor{ + height: 100%; + width: 100%; +} +.off-customize #main-preview{ + margin-left: 0 +} +.off-customize #leo-customize span{margin-left: 22px} +.off-customize #leo-customize .btn-show{ + right: -56px; + transition:all 0.2s; +} +.page-wrapper{ + margin-left:300px; +} +.off-customize #leo-customize{ + left: -330px; +} + +#customize-form{ + position: relative; +} +#main-preview { + bottom: 0; + height: 100%; + left: 0; + position: absolute; + right: 0; + top: 0; + margin-left: 300px; + transition-duration: 0.2s; + transition-property: left, right, top, bottom, width, margin; +} +#main-preview iframe, #top_container, #container, #main,#content, body { + height: 100%; + width: 100%; + border: none; + padding: 0; + margin: 0; + +} +.colorpicker{ + z-index: 9999 +} +#leo-customize{ + width: 320px; + + position:absolute; + top: 0; + left:0px; + + z-index: 3; + box-shadow: 0 1px 3px #999; + transition-duration: 0.2s; + transition-property: left, right, top, bottom, width, margin; + background: none repeat scroll 0 0 #fff; + border-right: 1px solid rgba(0, 0, 0, 0.2); + +} + +#leo-customize .wrapper{ + + padding: 12px; +} +#customize-body input[type="text"]{ + line-height: 18px; + margin: 0; + width: 50px; + color: #FFF; + font-size: 11px; + border-radius: 3px 3px 3px 3px; + border-style: solid; + border-width: 1px; + border-color: #DFDFDF; + padding: 3px 5px; + margin-right: 6px; + display: inline-block; +} +.form-group { + margin-right: 6px; +} +.form-group select{ + width: 100px +} +.accordion-inner .form-group .clear-bg{ + border-radius: 0; +} + +.accordion-group label, .form-group label{ + display: block; + font-size: 11px; + text-align: left; +} +.accordion-group label{ + float: left; + margin-right:7px; + + font-weight: normal; +} +#leo-customize .btn{ + padding: 4px 12px; + font-size: 11px; + font-weight: bold; +} +#leo-customize .btn-show{ + position: absolute; + top: 39px; + padding:6px 18px; + background:#CCC; + right:11px; + z-index: 99; + transition:all 1.2s; + cursor: hand; + cursor: pointer; + +} +#customize-body .nav-tabs, #customize-body .nav-tabs a{ + border:none; +} +#customize-body .nav-tabs a{ + background: transparent; + font-weight: bold; + font-size: 11px; +} +#customize-body .nav-tabs .active a{ + background: #FFF +} +.accordion-heading .accordion-toggle{ + font-weight: bold; + font-family: arial; +} +.tab-content > .tab-pane, .pill-content > .pill-pane { + background: none repeat scroll 0 0 #FFFFFF; +} +.bi-wrapper > div{ + float: left; + width: 20px; + height: 20px; + margin: 3px 4px; + border: solid 1px #999; + cursor:hand; cursor:pointer; +} +.bi-wrapper > div.active{ + border-color:red; +} + +#content.bootstrap .panel, #content.bootstrap #dash_version, #content.bootstrap .message-item-initial .message-item-initial-body, #content.bootstrap .timeline .timeline-item .timeline-caption .timeline-panel { + padding: 0; +} +#content.bootstrap h3:not(.modal-title), #content.bootstrap .panel-heading { + margin: 0; + text-transform: inherit; +} +#customize-body .tab-content { + margin-top: 20px; +} + +#leo-customize .bootstrap .label-success { + display: inline-block; + width: 92px; +} +#customize-body .bootstrap .label { + border-radius: 0; + color: #FFFFFF; + font-size: 100%; + font-weight: bold; + line-height: 1; + text-align: center; + vertical-align: baseline; + display: inline-block; +} + +.page-sidebar #content { + margin-left: 0; +} +.page-sidebar .bootstrap .row{float: left; width: 100%; height: 100%;} +.page-sidebar .bootstrap .col-lg-12{width: 100%; height: 100%;} + +.page-sidebar #content.bootstrap { + padding-left: 0; + padding-right: 0; + padding-top: 0; +} + +#main-preview .paneltool { + display: none; +} +.page-sidebar #main-preview { + margin-left: 320px; +} +.off-customize.page-sidebar #main-preview { + margin-left:0; +} + +#content.bootstrap .panel, +#content.bootstrap #dash_version, +#content.bootstrap .message-item-initial .message-item-initial-body, +#content.bootstrap .timeline .timeline-item .timeline-caption .timeline-panel { + margin-bottom: 10px; +} +select.input-setting{margin-right: 0!important} +.bg-config{padding: 8px 15px;margin-bottom: 20px; list-style: none;} +.bg-config>li { +display: inline-block; +} diff --git a/modules/appagebuilder/css/animate.css b/modules/appagebuilder/css/animate.css new file mode 100644 index 00000000..421b5b66 --- /dev/null +++ b/modules/appagebuilder/css/animate.css @@ -0,0 +1,3164 @@ +@charset "UTF-8"; +/*! +Animate.css - http://daneden.me/animate +Licensed under the MIT license - http://opensource.org/licenses/MIT + +Copyright (c) 2014 Daniel Eden +*/ + +.animated { + -webkit-animation-duration: 1s; + animation-duration: 1s; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; +} + +.animated.infinite { + -webkit-animation-iteration-count: infinite; + animation-iteration-count: infinite; +} + +.animated.hinge { + -webkit-animation-duration: 2s; + animation-duration: 2s; +} + +@-webkit-keyframes bounce { + 0%, 20%, 53%, 80%, 100% { + -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + -webkit-transform: translate3d(0,0,0); + transform: translate3d(0,0,0); + } + + 40%, 43% { + -webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); + transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); + -webkit-transform: translate3d(0, -30px, 0); + transform: translate3d(0, -30px, 0); + } + + 70% { + -webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); + transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); + -webkit-transform: translate3d(0, -15px, 0); + transform: translate3d(0, -15px, 0); + } + + 90% { + -webkit-transform: translate3d(0,-4px,0); + transform: translate3d(0,-4px,0); + } +} + +@keyframes bounce { + 0%, 20%, 53%, 80%, 100% { + -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + -webkit-transform: translate3d(0,0,0); + transform: translate3d(0,0,0); + } + + 40%, 43% { + -webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); + transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); + -webkit-transform: translate3d(0, -30px, 0); + transform: translate3d(0, -30px, 0); + } + + 70% { + -webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); + transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); + -webkit-transform: translate3d(0, -15px, 0); + transform: translate3d(0, -15px, 0); + } + + 90% { + -webkit-transform: translate3d(0,-4px,0); + transform: translate3d(0,-4px,0); + } +} + +.bounce { + -webkit-animation-name: bounce; + animation-name: bounce; + -webkit-transform-origin: center bottom; + -ms-transform-origin: center bottom; + transform-origin: center bottom; +} + +@-webkit-keyframes flash { + 0%, 50%, 100% { + opacity: 1; + } + + 25%, 75% { + opacity: 0; + } +} + +@keyframes flash { + 0%, 50%, 100% { + opacity: 1; + } + + 25%, 75% { + opacity: 0; + } +} + +.flash { + -webkit-animation-name: flash; + animation-name: flash; +} + +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes pulse { + 0% { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 50% { + -webkit-transform: scale3d(1.05, 1.05, 1.05); + transform: scale3d(1.05, 1.05, 1.05); + } + + 100% { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +@keyframes pulse { + 0% { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 50% { + -webkit-transform: scale3d(1.05, 1.05, 1.05); + transform: scale3d(1.05, 1.05, 1.05); + } + + 100% { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +.pulse { + -webkit-animation-name: pulse; + animation-name: pulse; +} + +@-webkit-keyframes rubberBand { + 0% { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 30% { + -webkit-transform: scale3d(1.25, 0.75, 1); + transform: scale3d(1.25, 0.75, 1); + } + + 40% { + -webkit-transform: scale3d(0.75, 1.25, 1); + transform: scale3d(0.75, 1.25, 1); + } + + 50% { + -webkit-transform: scale3d(1.15, 0.85, 1); + transform: scale3d(1.15, 0.85, 1); + } + + 65% { + -webkit-transform: scale3d(.95, 1.05, 1); + transform: scale3d(.95, 1.05, 1); + } + + 75% { + -webkit-transform: scale3d(1.05, .95, 1); + transform: scale3d(1.05, .95, 1); + } + + 100% { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +@keyframes rubberBand { + 0% { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 30% { + -webkit-transform: scale3d(1.25, 0.75, 1); + transform: scale3d(1.25, 0.75, 1); + } + + 40% { + -webkit-transform: scale3d(0.75, 1.25, 1); + transform: scale3d(0.75, 1.25, 1); + } + + 50% { + -webkit-transform: scale3d(1.15, 0.85, 1); + transform: scale3d(1.15, 0.85, 1); + } + + 65% { + -webkit-transform: scale3d(.95, 1.05, 1); + transform: scale3d(.95, 1.05, 1); + } + + 75% { + -webkit-transform: scale3d(1.05, .95, 1); + transform: scale3d(1.05, .95, 1); + } + + 100% { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +.rubberBand { + -webkit-animation-name: rubberBand; + animation-name: rubberBand; +} + +@-webkit-keyframes shake { + 0%, 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 10%, 30%, 50%, 70%, 90% { + -webkit-transform: translate3d(-10px, 0, 0); + transform: translate3d(-10px, 0, 0); + } + + 20%, 40%, 60%, 80% { + -webkit-transform: translate3d(10px, 0, 0); + transform: translate3d(10px, 0, 0); + } +} + +@keyframes shake { + 0%, 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 10%, 30%, 50%, 70%, 90% { + -webkit-transform: translate3d(-10px, 0, 0); + transform: translate3d(-10px, 0, 0); + } + + 20%, 40%, 60%, 80% { + -webkit-transform: translate3d(10px, 0, 0); + transform: translate3d(10px, 0, 0); + } +} + +.shake { + -webkit-animation-name: shake; + animation-name: shake; +} + +@-webkit-keyframes swing { + 20% { + -webkit-transform: rotate3d(0, 0, 1, 15deg); + transform: rotate3d(0, 0, 1, 15deg); + } + + 40% { + -webkit-transform: rotate3d(0, 0, 1, -10deg); + transform: rotate3d(0, 0, 1, -10deg); + } + + 60% { + -webkit-transform: rotate3d(0, 0, 1, 5deg); + transform: rotate3d(0, 0, 1, 5deg); + } + + 80% { + -webkit-transform: rotate3d(0, 0, 1, -5deg); + transform: rotate3d(0, 0, 1, -5deg); + } + + 100% { + -webkit-transform: rotate3d(0, 0, 1, 0deg); + transform: rotate3d(0, 0, 1, 0deg); + } +} + +@keyframes swing { + 20% { + -webkit-transform: rotate3d(0, 0, 1, 15deg); + transform: rotate3d(0, 0, 1, 15deg); + } + + 40% { + -webkit-transform: rotate3d(0, 0, 1, -10deg); + transform: rotate3d(0, 0, 1, -10deg); + } + + 60% { + -webkit-transform: rotate3d(0, 0, 1, 5deg); + transform: rotate3d(0, 0, 1, 5deg); + } + + 80% { + -webkit-transform: rotate3d(0, 0, 1, -5deg); + transform: rotate3d(0, 0, 1, -5deg); + } + + 100% { + -webkit-transform: rotate3d(0, 0, 1, 0deg); + transform: rotate3d(0, 0, 1, 0deg); + } +} + +.swing { + -webkit-transform-origin: top center; + -ms-transform-origin: top center; + transform-origin: top center; + -webkit-animation-name: swing; + animation-name: swing; +} + +@-webkit-keyframes tada { + 0% { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 10%, 20% { + -webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); + transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); + } + + 30%, 50%, 70%, 90% { + -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); + transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); + } + + 40%, 60%, 80% { + -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); + transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); + } + + 100% { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +@keyframes tada { + 0% { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 10%, 20% { + -webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); + transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); + } + + 30%, 50%, 70%, 90% { + -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); + transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); + } + + 40%, 60%, 80% { + -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); + transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); + } + + 100% { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +.tada { + -webkit-animation-name: tada; + animation-name: tada; +} + +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes wobble { + 0% { + -webkit-transform: none; + transform: none; + } + + 15% { + -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); + transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); + } + + 30% { + -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); + transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); + } + + 45% { + -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); + transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); + } + + 60% { + -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); + transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); + } + + 75% { + -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); + transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); + } + + 100% { + -webkit-transform: none; + transform: none; + } +} + +@keyframes wobble { + 0% { + -webkit-transform: none; + transform: none; + } + + 15% { + -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); + transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); + } + + 30% { + -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); + transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); + } + + 45% { + -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); + transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); + } + + 60% { + -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); + transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); + } + + 75% { + -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); + transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); + } + + 100% { + -webkit-transform: none; + transform: none; + } +} + +.wobble { + -webkit-animation-name: wobble; + animation-name: wobble; +} + +@-webkit-keyframes bounceIn { + 0%, 20%, 40%, 60%, 80%, 100% { + -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + } + + 0% { + opacity: 0; + -webkit-transform: scale3d(.3, .3, .3); + transform: scale3d(.3, .3, .3); + } + + 20% { + -webkit-transform: scale3d(1.1, 1.1, 1.1); + transform: scale3d(1.1, 1.1, 1.1); + } + + 40% { + -webkit-transform: scale3d(.9, .9, .9); + transform: scale3d(.9, .9, .9); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(1.03, 1.03, 1.03); + transform: scale3d(1.03, 1.03, 1.03); + } + + 80% { + -webkit-transform: scale3d(.97, .97, .97); + transform: scale3d(.97, .97, .97); + } + + 100% { + opacity: 1; + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +@keyframes bounceIn { + 0%, 20%, 40%, 60%, 80%, 100% { + -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + } + + 0% { + opacity: 0; + -webkit-transform: scale3d(.3, .3, .3); + transform: scale3d(.3, .3, .3); + } + + 20% { + -webkit-transform: scale3d(1.1, 1.1, 1.1); + transform: scale3d(1.1, 1.1, 1.1); + } + + 40% { + -webkit-transform: scale3d(.9, .9, .9); + transform: scale3d(.9, .9, .9); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(1.03, 1.03, 1.03); + transform: scale3d(1.03, 1.03, 1.03); + } + + 80% { + -webkit-transform: scale3d(.97, .97, .97); + transform: scale3d(.97, .97, .97); + } + + 100% { + opacity: 1; + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +.bounceIn { + -webkit-animation-name: bounceIn; + animation-name: bounceIn; + -webkit-animation-duration: .75s; + animation-duration: .75s; +} + +@-webkit-keyframes bounceInDown { + 0%, 60%, 75%, 90%, 100% { + -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + } + + 0% { + opacity: 0; + -webkit-transform: translate3d(0, -3000px, 0); + transform: translate3d(0, -3000px, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(0, 25px, 0); + transform: translate3d(0, 25px, 0); + } + + 75% { + -webkit-transform: translate3d(0, -10px, 0); + transform: translate3d(0, -10px, 0); + } + + 90% { + -webkit-transform: translate3d(0, 5px, 0); + transform: translate3d(0, 5px, 0); + } + + 100% { + -webkit-transform: none; + transform: none; + } +} + +@keyframes bounceInDown { + 0%, 60%, 75%, 90%, 100% { + -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + } + + 0% { + opacity: 0; + -webkit-transform: translate3d(0, -3000px, 0); + transform: translate3d(0, -3000px, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(0, 25px, 0); + transform: translate3d(0, 25px, 0); + } + + 75% { + -webkit-transform: translate3d(0, -10px, 0); + transform: translate3d(0, -10px, 0); + } + + 90% { + -webkit-transform: translate3d(0, 5px, 0); + transform: translate3d(0, 5px, 0); + } + + 100% { + -webkit-transform: none; + transform: none; + } +} + +.bounceInDown { + -webkit-animation-name: bounceInDown; + animation-name: bounceInDown; +} + +@-webkit-keyframes bounceInLeft { + 0%, 60%, 75%, 90%, 100% { + -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + } + + 0% { + opacity: 0; + -webkit-transform: translate3d(-3000px, 0, 0); + transform: translate3d(-3000px, 0, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(25px, 0, 0); + transform: translate3d(25px, 0, 0); + } + + 75% { + -webkit-transform: translate3d(-10px, 0, 0); + transform: translate3d(-10px, 0, 0); + } + + 90% { + -webkit-transform: translate3d(5px, 0, 0); + transform: translate3d(5px, 0, 0); + } + + 100% { + -webkit-transform: none; + transform: none; + } +} + +@keyframes bounceInLeft { + 0%, 60%, 75%, 90%, 100% { + -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + } + + 0% { + opacity: 0; + -webkit-transform: translate3d(-3000px, 0, 0); + transform: translate3d(-3000px, 0, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(25px, 0, 0); + transform: translate3d(25px, 0, 0); + } + + 75% { + -webkit-transform: translate3d(-10px, 0, 0); + transform: translate3d(-10px, 0, 0); + } + + 90% { + -webkit-transform: translate3d(5px, 0, 0); + transform: translate3d(5px, 0, 0); + } + + 100% { + -webkit-transform: none; + transform: none; + } +} + +.bounceInLeft { + -webkit-animation-name: bounceInLeft; + animation-name: bounceInLeft; +} + +@-webkit-keyframes bounceInRight { + 0%, 60%, 75%, 90%, 100% { + -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + } + + 0% { + opacity: 0; + -webkit-transform: translate3d(3000px, 0, 0); + transform: translate3d(3000px, 0, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(-25px, 0, 0); + transform: translate3d(-25px, 0, 0); + } + + 75% { + -webkit-transform: translate3d(10px, 0, 0); + transform: translate3d(10px, 0, 0); + } + + 90% { + -webkit-transform: translate3d(-5px, 0, 0); + transform: translate3d(-5px, 0, 0); + } + + 100% { + -webkit-transform: none; + transform: none; + } +} + +@keyframes bounceInRight { + 0%, 60%, 75%, 90%, 100% { + -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + } + + 0% { + opacity: 0; + -webkit-transform: translate3d(3000px, 0, 0); + transform: translate3d(3000px, 0, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(-25px, 0, 0); + transform: translate3d(-25px, 0, 0); + } + + 75% { + -webkit-transform: translate3d(10px, 0, 0); + transform: translate3d(10px, 0, 0); + } + + 90% { + -webkit-transform: translate3d(-5px, 0, 0); + transform: translate3d(-5px, 0, 0); + } + + 100% { + -webkit-transform: none; + transform: none; + } +} + +.bounceInRight { + -webkit-animation-name: bounceInRight; + animation-name: bounceInRight; +} + +@-webkit-keyframes bounceInUp { + 0%, 60%, 75%, 90%, 100% { + -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + } + + 0% { + opacity: 0; + -webkit-transform: translate3d(0, 3000px, 0); + transform: translate3d(0, 3000px, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(0, -20px, 0); + transform: translate3d(0, -20px, 0); + } + + 75% { + -webkit-transform: translate3d(0, 10px, 0); + transform: translate3d(0, 10px, 0); + } + + 90% { + -webkit-transform: translate3d(0, -5px, 0); + transform: translate3d(0, -5px, 0); + } + + 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes bounceInUp { + 0%, 60%, 75%, 90%, 100% { + -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + } + + 0% { + opacity: 0; + -webkit-transform: translate3d(0, 3000px, 0); + transform: translate3d(0, 3000px, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(0, -20px, 0); + transform: translate3d(0, -20px, 0); + } + + 75% { + -webkit-transform: translate3d(0, 10px, 0); + transform: translate3d(0, 10px, 0); + } + + 90% { + -webkit-transform: translate3d(0, -5px, 0); + transform: translate3d(0, -5px, 0); + } + + 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.bounceInUp { + -webkit-animation-name: bounceInUp; + animation-name: bounceInUp; +} + +@-webkit-keyframes bounceOut { + 20% { + -webkit-transform: scale3d(.9, .9, .9); + transform: scale3d(.9, .9, .9); + } + + 50%, 55% { + opacity: 1; + -webkit-transform: scale3d(1.1, 1.1, 1.1); + transform: scale3d(1.1, 1.1, 1.1); + } + + 100% { + opacity: 0; + -webkit-transform: scale3d(.3, .3, .3); + transform: scale3d(.3, .3, .3); + } +} + +@keyframes bounceOut { + 20% { + -webkit-transform: scale3d(.9, .9, .9); + transform: scale3d(.9, .9, .9); + } + + 50%, 55% { + opacity: 1; + -webkit-transform: scale3d(1.1, 1.1, 1.1); + transform: scale3d(1.1, 1.1, 1.1); + } + + 100% { + opacity: 0; + -webkit-transform: scale3d(.3, .3, .3); + transform: scale3d(.3, .3, .3); + } +} + +.bounceOut { + -webkit-animation-name: bounceOut; + animation-name: bounceOut; + -webkit-animation-duration: .75s; + animation-duration: .75s; +} + +@-webkit-keyframes bounceOutDown { + 20% { + -webkit-transform: translate3d(0, 10px, 0); + transform: translate3d(0, 10px, 0); + } + + 40%, 45% { + opacity: 1; + -webkit-transform: translate3d(0, -20px, 0); + transform: translate3d(0, -20px, 0); + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } +} + +@keyframes bounceOutDown { + 20% { + -webkit-transform: translate3d(0, 10px, 0); + transform: translate3d(0, 10px, 0); + } + + 40%, 45% { + opacity: 1; + -webkit-transform: translate3d(0, -20px, 0); + transform: translate3d(0, -20px, 0); + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } +} + +.bounceOutDown { + -webkit-animation-name: bounceOutDown; + animation-name: bounceOutDown; +} + +@-webkit-keyframes bounceOutLeft { + 20% { + opacity: 1; + -webkit-transform: translate3d(20px, 0, 0); + transform: translate3d(20px, 0, 0); + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } +} + +@keyframes bounceOutLeft { + 20% { + opacity: 1; + -webkit-transform: translate3d(20px, 0, 0); + transform: translate3d(20px, 0, 0); + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } +} + +.bounceOutLeft { + -webkit-animation-name: bounceOutLeft; + animation-name: bounceOutLeft; +} + +@-webkit-keyframes bounceOutRight { + 20% { + opacity: 1; + -webkit-transform: translate3d(-20px, 0, 0); + transform: translate3d(-20px, 0, 0); + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } +} + +@keyframes bounceOutRight { + 20% { + opacity: 1; + -webkit-transform: translate3d(-20px, 0, 0); + transform: translate3d(-20px, 0, 0); + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } +} + +.bounceOutRight { + -webkit-animation-name: bounceOutRight; + animation-name: bounceOutRight; +} + +@-webkit-keyframes bounceOutUp { + 20% { + -webkit-transform: translate3d(0, -10px, 0); + transform: translate3d(0, -10px, 0); + } + + 40%, 45% { + opacity: 1; + -webkit-transform: translate3d(0, 20px, 0); + transform: translate3d(0, 20px, 0); + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } +} + +@keyframes bounceOutUp { + 20% { + -webkit-transform: translate3d(0, -10px, 0); + transform: translate3d(0, -10px, 0); + } + + 40%, 45% { + opacity: 1; + -webkit-transform: translate3d(0, 20px, 0); + transform: translate3d(0, 20px, 0); + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } +} + +.bounceOutUp { + -webkit-animation-name: bounceOutUp; + animation-name: bounceOutUp; +} + +@-webkit-keyframes fadeIn { + 0% {opacity: 0;} + 100% {opacity: 1;} +} + +@keyframes fadeIn { + 0% {opacity: 0;} + 100% {opacity: 1;} +} + +.fadeIn { + -webkit-animation-name: fadeIn; + animation-name: fadeIn; +} + +@-webkit-keyframes fadeInDown { + 0% { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +@keyframes fadeInDown { + 0% { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +.fadeInDown { + -webkit-animation-name: fadeInDown; + animation-name: fadeInDown; +} + +@-webkit-keyframes fadeInDownBig { + 0% { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +@keyframes fadeInDownBig { + 0% { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +.fadeInDownBig { + -webkit-animation-name: fadeInDownBig; + animation-name: fadeInDownBig; +} + +@-webkit-keyframes fadeInLeft { + 0% { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +@keyframes fadeInLeft { + 0% { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +.fadeInLeft { + -webkit-animation-name: fadeInLeft; + animation-name: fadeInLeft; +} + +@-webkit-keyframes fadeInLeftBig { + 0% { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +@keyframes fadeInLeftBig { + 0% { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +.fadeInLeftBig { + -webkit-animation-name: fadeInLeftBig; + animation-name: fadeInLeftBig; +} + +@-webkit-keyframes fadeInRight { + 0% { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +@keyframes fadeInRight { + 0% { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +.fadeInRight { + -webkit-animation-name: fadeInRight; + animation-name: fadeInRight; +} + +@-webkit-keyframes fadeInRightBig { + 0% { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +@keyframes fadeInRightBig { + 0% { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +.fadeInRightBig { + -webkit-animation-name: fadeInRightBig; + animation-name: fadeInRightBig; +} + +@-webkit-keyframes fadeInUp { + 0% { + opacity: 0; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +@keyframes fadeInUp { + 0% { + opacity: 0; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +.fadeInUp { + -webkit-animation-name: fadeInUp; + animation-name: fadeInUp; +} + +@-webkit-keyframes fadeInUpBig { + 0% { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +@keyframes fadeInUpBig { + 0% { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +.fadeInUpBig { + -webkit-animation-name: fadeInUpBig; + animation-name: fadeInUpBig; +} + +@-webkit-keyframes fadeOut { + 0% {opacity: 1;} + 100% {opacity: 0;} +} + +@keyframes fadeOut { + 0% {opacity: 1;} + 100% {opacity: 0;} +} + +.fadeOut { + -webkit-animation-name: fadeOut; + animation-name: fadeOut; +} + +@-webkit-keyframes fadeOutDown { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + } +} + +@keyframes fadeOutDown { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + } +} + +.fadeOutDown { + -webkit-animation-name: fadeOutDown; + animation-name: fadeOutDown; +} + +@-webkit-keyframes fadeOutDownBig { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } +} + +@keyframes fadeOutDownBig { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } +} + +.fadeOutDownBig { + -webkit-animation-name: fadeOutDownBig; + animation-name: fadeOutDownBig; +} + +@-webkit-keyframes fadeOutLeft { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } +} + +@keyframes fadeOutLeft { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } +} + +.fadeOutLeft { + -webkit-animation-name: fadeOutLeft; + animation-name: fadeOutLeft; +} + +@-webkit-keyframes fadeOutLeftBig { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } +} + +@keyframes fadeOutLeftBig { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } +} + +.fadeOutLeftBig { + -webkit-animation-name: fadeOutLeftBig; + animation-name: fadeOutLeftBig; +} + +@-webkit-keyframes fadeOutRight { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } +} + +@keyframes fadeOutRight { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } +} + +.fadeOutRight { + -webkit-animation-name: fadeOutRight; + animation-name: fadeOutRight; +} + +@-webkit-keyframes fadeOutRightBig { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } +} + +@keyframes fadeOutRightBig { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } +} + +.fadeOutRightBig { + -webkit-animation-name: fadeOutRightBig; + animation-name: fadeOutRightBig; +} + +@-webkit-keyframes fadeOutUp { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } +} + +@keyframes fadeOutUp { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } +} + +.fadeOutUp { + -webkit-animation-name: fadeOutUp; + animation-name: fadeOutUp; +} + +@-webkit-keyframes fadeOutUpBig { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } +} + +@keyframes fadeOutUpBig { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } +} + +.fadeOutUpBig { + -webkit-animation-name: fadeOutUpBig; + animation-name: fadeOutUpBig; +} + +@-webkit-keyframes flip { + 0% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg); + transform: perspective(400px) rotate3d(0, 1, 0, -360deg); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 40% { + -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); + transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 50% { + -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); + transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 80% { + -webkit-transform: perspective(400px) scale3d(.95, .95, .95); + transform: perspective(400px) scale3d(.95, .95, .95); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 100% { + -webkit-transform: perspective(400px); + transform: perspective(400px); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } +} + +@keyframes flip { + 0% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg); + transform: perspective(400px) rotate3d(0, 1, 0, -360deg); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 40% { + -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); + transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 50% { + -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); + transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 80% { + -webkit-transform: perspective(400px) scale3d(.95, .95, .95); + transform: perspective(400px) scale3d(.95, .95, .95); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 100% { + -webkit-transform: perspective(400px); + transform: perspective(400px); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } +} + +.animated.flip { + -webkit-backface-visibility: visible; + backface-visibility: visible; + -webkit-animation-name: flip; + animation-name: flip; +} + +@-webkit-keyframes flipInX { + 0% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + -webkit-transition-timing-function: ease-in; + transition-timing-function: ease-in; + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + -webkit-transition-timing-function: ease-in; + transition-timing-function: ease-in; + } + + 60% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg); + transform: perspective(400px) rotate3d(1, 0, 0, 10deg); + opacity: 1; + } + + 80% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg); + transform: perspective(400px) rotate3d(1, 0, 0, -5deg); + } + + 100% { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } +} + +@keyframes flipInX { + 0% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + -webkit-transition-timing-function: ease-in; + transition-timing-function: ease-in; + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + -webkit-transition-timing-function: ease-in; + transition-timing-function: ease-in; + } + + 60% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg); + transform: perspective(400px) rotate3d(1, 0, 0, 10deg); + opacity: 1; + } + + 80% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg); + transform: perspective(400px) rotate3d(1, 0, 0, -5deg); + } + + 100% { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } +} + +.flipInX { + -webkit-backface-visibility: visible !important; + backface-visibility: visible !important; + -webkit-animation-name: flipInX; + animation-name: flipInX; +} + +@-webkit-keyframes flipInY { + 0% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + -webkit-transition-timing-function: ease-in; + transition-timing-function: ease-in; + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg); + transform: perspective(400px) rotate3d(0, 1, 0, -20deg); + -webkit-transition-timing-function: ease-in; + transition-timing-function: ease-in; + } + + 60% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg); + transform: perspective(400px) rotate3d(0, 1, 0, 10deg); + opacity: 1; + } + + 80% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg); + transform: perspective(400px) rotate3d(0, 1, 0, -5deg); + } + + 100% { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } +} + +@keyframes flipInY { + 0% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + -webkit-transition-timing-function: ease-in; + transition-timing-function: ease-in; + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg); + transform: perspective(400px) rotate3d(0, 1, 0, -20deg); + -webkit-transition-timing-function: ease-in; + transition-timing-function: ease-in; + } + + 60% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg); + transform: perspective(400px) rotate3d(0, 1, 0, 10deg); + opacity: 1; + } + + 80% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg); + transform: perspective(400px) rotate3d(0, 1, 0, -5deg); + } + + 100% { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } +} + +.flipInY { + -webkit-backface-visibility: visible !important; + backface-visibility: visible !important; + -webkit-animation-name: flipInY; + animation-name: flipInY; +} + +@-webkit-keyframes flipOutX { + 0% { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } + + 30% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + opacity: 1; + } + + 100% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + opacity: 0; + } +} + +@keyframes flipOutX { + 0% { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } + + 30% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + opacity: 1; + } + + 100% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + opacity: 0; + } +} + +.flipOutX { + -webkit-animation-name: flipOutX; + animation-name: flipOutX; + -webkit-animation-duration: .75s; + animation-duration: .75s; + -webkit-backface-visibility: visible !important; + backface-visibility: visible !important; +} + +@-webkit-keyframes flipOutY { + 0% { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } + + 30% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg); + transform: perspective(400px) rotate3d(0, 1, 0, -15deg); + opacity: 1; + } + + 100% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + opacity: 0; + } +} + +@keyframes flipOutY { + 0% { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } + + 30% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg); + transform: perspective(400px) rotate3d(0, 1, 0, -15deg); + opacity: 1; + } + + 100% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + opacity: 0; + } +} + +.flipOutY { + -webkit-backface-visibility: visible !important; + backface-visibility: visible !important; + -webkit-animation-name: flipOutY; + animation-name: flipOutY; + -webkit-animation-duration: .75s; + animation-duration: .75s; +} + +@-webkit-keyframes lightSpeedIn { + 0% { + -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg); + transform: translate3d(100%, 0, 0) skewX(-30deg); + opacity: 0; + } + + 60% { + -webkit-transform: skewX(20deg); + transform: skewX(20deg); + opacity: 1; + } + + 80% { + -webkit-transform: skewX(-5deg); + transform: skewX(-5deg); + opacity: 1; + } + + 100% { + -webkit-transform: none; + transform: none; + opacity: 1; + } +} + +@keyframes lightSpeedIn { + 0% { + -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg); + transform: translate3d(100%, 0, 0) skewX(-30deg); + opacity: 0; + } + + 60% { + -webkit-transform: skewX(20deg); + transform: skewX(20deg); + opacity: 1; + } + + 80% { + -webkit-transform: skewX(-5deg); + transform: skewX(-5deg); + opacity: 1; + } + + 100% { + -webkit-transform: none; + transform: none; + opacity: 1; + } +} + +.lightSpeedIn { + -webkit-animation-name: lightSpeedIn; + animation-name: lightSpeedIn; + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; +} + +@-webkit-keyframes lightSpeedOut { + 0% { + opacity: 1; + } + + 100% { + -webkit-transform: translate3d(100%, 0, 0) skewX(30deg); + transform: translate3d(100%, 0, 0) skewX(30deg); + opacity: 0; + } +} + +@keyframes lightSpeedOut { + 0% { + opacity: 1; + } + + 100% { + -webkit-transform: translate3d(100%, 0, 0) skewX(30deg); + transform: translate3d(100%, 0, 0) skewX(30deg); + opacity: 0; + } +} + +.lightSpeedOut { + -webkit-animation-name: lightSpeedOut; + animation-name: lightSpeedOut; + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; +} + +@-webkit-keyframes rotateIn { + 0% { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: rotate3d(0, 0, 1, -200deg); + transform: rotate3d(0, 0, 1, -200deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: none; + transform: none; + opacity: 1; + } +} + +@keyframes rotateIn { + 0% { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: rotate3d(0, 0, 1, -200deg); + transform: rotate3d(0, 0, 1, -200deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: none; + transform: none; + opacity: 1; + } +} + +.rotateIn { + -webkit-animation-name: rotateIn; + animation-name: rotateIn; +} + +@-webkit-keyframes rotateInDownLeft { + 0% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: none; + transform: none; + opacity: 1; + } +} + +@keyframes rotateInDownLeft { + 0% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: none; + transform: none; + opacity: 1; + } +} + +.rotateInDownLeft { + -webkit-animation-name: rotateInDownLeft; + animation-name: rotateInDownLeft; +} + +@-webkit-keyframes rotateInDownRight { + 0% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: none; + transform: none; + opacity: 1; + } +} + +@keyframes rotateInDownRight { + 0% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: none; + transform: none; + opacity: 1; + } +} + +.rotateInDownRight { + -webkit-animation-name: rotateInDownRight; + animation-name: rotateInDownRight; +} + +@-webkit-keyframes rotateInUpLeft { + 0% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: none; + transform: none; + opacity: 1; + } +} + +@keyframes rotateInUpLeft { + 0% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: none; + transform: none; + opacity: 1; + } +} + +.rotateInUpLeft { + -webkit-animation-name: rotateInUpLeft; + animation-name: rotateInUpLeft; +} + +@-webkit-keyframes rotateInUpRight { + 0% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, -90deg); + transform: rotate3d(0, 0, 1, -90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: none; + transform: none; + opacity: 1; + } +} + +@keyframes rotateInUpRight { + 0% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, -90deg); + transform: rotate3d(0, 0, 1, -90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: none; + transform: none; + opacity: 1; + } +} + +.rotateInUpRight { + -webkit-animation-name: rotateInUpRight; + animation-name: rotateInUpRight; +} + +@-webkit-keyframes rotateOut { + 0% { + -webkit-transform-origin: center; + transform-origin: center; + opacity: 1; + } + + 100% { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: rotate3d(0, 0, 1, 200deg); + transform: rotate3d(0, 0, 1, 200deg); + opacity: 0; + } +} + +@keyframes rotateOut { + 0% { + -webkit-transform-origin: center; + transform-origin: center; + opacity: 1; + } + + 100% { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: rotate3d(0, 0, 1, 200deg); + transform: rotate3d(0, 0, 1, 200deg); + opacity: 0; + } +} + +.rotateOut { + -webkit-animation-name: rotateOut; + animation-name: rotateOut; +} + +@-webkit-keyframes rotateOutDownLeft { + 0% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + opacity: 1; + } + + 100% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } +} + +@keyframes rotateOutDownLeft { + 0% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + opacity: 1; + } + + 100% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } +} + +.rotateOutDownLeft { + -webkit-animation-name: rotateOutDownLeft; + animation-name: rotateOutDownLeft; +} + +@-webkit-keyframes rotateOutDownRight { + 0% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + opacity: 1; + } + + 100% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } +} + +@keyframes rotateOutDownRight { + 0% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + opacity: 1; + } + + 100% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } +} + +.rotateOutDownRight { + -webkit-animation-name: rotateOutDownRight; + animation-name: rotateOutDownRight; +} + +@-webkit-keyframes rotateOutUpLeft { + 0% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + opacity: 1; + } + + 100% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } +} + +@keyframes rotateOutUpLeft { + 0% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + opacity: 1; + } + + 100% { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } +} + +.rotateOutUpLeft { + -webkit-animation-name: rotateOutUpLeft; + animation-name: rotateOutUpLeft; +} + +@-webkit-keyframes rotateOutUpRight { + 0% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + opacity: 1; + } + + 100% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, 90deg); + transform: rotate3d(0, 0, 1, 90deg); + opacity: 0; + } +} + +@keyframes rotateOutUpRight { + 0% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + opacity: 1; + } + + 100% { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, 90deg); + transform: rotate3d(0, 0, 1, 90deg); + opacity: 0; + } +} + +.rotateOutUpRight { + -webkit-animation-name: rotateOutUpRight; + animation-name: rotateOutUpRight; +} + +@-webkit-keyframes hinge { + 0% { + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 20%, 60% { + -webkit-transform: rotate3d(0, 0, 1, 80deg); + transform: rotate3d(0, 0, 1, 80deg); + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 40%, 80% { + -webkit-transform: rotate3d(0, 0, 1, 60deg); + transform: rotate3d(0, 0, 1, 60deg); + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + opacity: 1; + } + + 100% { + -webkit-transform: translate3d(0, 700px, 0); + transform: translate3d(0, 700px, 0); + opacity: 0; + } +} + +@keyframes hinge { + 0% { + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 20%, 60% { + -webkit-transform: rotate3d(0, 0, 1, 80deg); + transform: rotate3d(0, 0, 1, 80deg); + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 40%, 80% { + -webkit-transform: rotate3d(0, 0, 1, 60deg); + transform: rotate3d(0, 0, 1, 60deg); + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + opacity: 1; + } + + 100% { + -webkit-transform: translate3d(0, 700px, 0); + transform: translate3d(0, 700px, 0); + opacity: 0; + } +} + +.hinge { + -webkit-animation-name: hinge; + animation-name: hinge; +} + +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes rollIn { + 0% { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); + transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +@keyframes rollIn { + 0% { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); + transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); + } + + 100% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} + +.rollIn { + -webkit-animation-name: rollIn; + animation-name: rollIn; +} + +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes rollOut { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); + transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); + } +} + +@keyframes rollOut { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); + transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); + } +} + +.rollOut { + -webkit-animation-name: rollOut; + animation-name: rollOut; +} + +@-webkit-keyframes zoomIn { + 0% { + opacity: 0; + -webkit-transform: scale3d(.3, .3, .3); + transform: scale3d(.3, .3, .3); + } + + 50% { + opacity: 1; + } +} + +@keyframes zoomIn { + 0% { + opacity: 0; + -webkit-transform: scale3d(.3, .3, .3); + transform: scale3d(.3, .3, .3); + } + + 50% { + opacity: 1; + } +} + +.zoomIn { + -webkit-animation-name: zoomIn; + animation-name: zoomIn; +} + +@-webkit-keyframes zoomInDown { + 0% { + opacity: 0; + -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); + transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); + -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); + transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + } +} + +@keyframes zoomInDown { + 0% { + opacity: 0; + -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); + transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); + -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); + transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + } +} + +.zoomInDown { + -webkit-animation-name: zoomInDown; + animation-name: zoomInDown; +} + +@-webkit-keyframes zoomInLeft { + 0% { + opacity: 0; + -webkit-transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); + transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); + transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + } +} + +@keyframes zoomInLeft { + 0% { + opacity: 0; + -webkit-transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); + transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); + transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + } +} + +.zoomInLeft { + -webkit-animation-name: zoomInLeft; + animation-name: zoomInLeft; +} + +@-webkit-keyframes zoomInRight { + 0% { + opacity: 0; + -webkit-transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); + transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); + transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + } +} + +@keyframes zoomInRight { + 0% { + opacity: 0; + -webkit-transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); + transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); + transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + } +} + +.zoomInRight { + -webkit-animation-name: zoomInRight; + animation-name: zoomInRight; +} + +@-webkit-keyframes zoomInUp { + 0% { + opacity: 0; + -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); + transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); + -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); + transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + } +} + +@keyframes zoomInUp { + 0% { + opacity: 0; + -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); + transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); + -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); + transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + } +} + +.zoomInUp { + -webkit-animation-name: zoomInUp; + animation-name: zoomInUp; +} + +@-webkit-keyframes zoomOut { + 0% { + opacity: 1; + } + + 50% { + opacity: 0; + -webkit-transform: scale3d(.3, .3, .3); + transform: scale3d(.3, .3, .3); + } + + 100% { + opacity: 0; + } +} + +@keyframes zoomOut { + 0% { + opacity: 1; + } + + 50% { + opacity: 0; + -webkit-transform: scale3d(.3, .3, .3); + transform: scale3d(.3, .3, .3); + } + + 100% { + opacity: 0; + } +} + +.zoomOut { + -webkit-animation-name: zoomOut; + animation-name: zoomOut; +} + +@-webkit-keyframes zoomOutDown { + 40% { + opacity: 1; + -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); + transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + } + + 100% { + opacity: 0; + -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); + transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); + -webkit-transform-origin: center bottom; + transform-origin: center bottom; + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + } +} + +@keyframes zoomOutDown { + 40% { + opacity: 1; + -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); + transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + } + + 100% { + opacity: 0; + -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); + transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); + -webkit-transform-origin: center bottom; + transform-origin: center bottom; + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + } +} + +.zoomOutDown { + -webkit-animation-name: zoomOutDown; + animation-name: zoomOutDown; +} + +@-webkit-keyframes zoomOutLeft { + 40% { + opacity: 1; + -webkit-transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); + transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); + } + + 100% { + opacity: 0; + -webkit-transform: scale(.1) translate3d(-2000px, 0, 0); + transform: scale(.1) translate3d(-2000px, 0, 0); + -webkit-transform-origin: left center; + transform-origin: left center; + } +} + +@keyframes zoomOutLeft { + 40% { + opacity: 1; + -webkit-transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); + transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); + } + + 100% { + opacity: 0; + -webkit-transform: scale(.1) translate3d(-2000px, 0, 0); + transform: scale(.1) translate3d(-2000px, 0, 0); + -webkit-transform-origin: left center; + transform-origin: left center; + } +} + +.zoomOutLeft { + -webkit-animation-name: zoomOutLeft; + animation-name: zoomOutLeft; +} + +@-webkit-keyframes zoomOutRight { + 40% { + opacity: 1; + -webkit-transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); + transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); + } + + 100% { + opacity: 0; + -webkit-transform: scale(.1) translate3d(2000px, 0, 0); + transform: scale(.1) translate3d(2000px, 0, 0); + -webkit-transform-origin: right center; + transform-origin: right center; + } +} + +@keyframes zoomOutRight { + 40% { + opacity: 1; + -webkit-transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); + transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); + } + + 100% { + opacity: 0; + -webkit-transform: scale(.1) translate3d(2000px, 0, 0); + transform: scale(.1) translate3d(2000px, 0, 0); + -webkit-transform-origin: right center; + transform-origin: right center; + } +} + +.zoomOutRight { + -webkit-animation-name: zoomOutRight; + animation-name: zoomOutRight; +} + +@-webkit-keyframes zoomOutUp { + 40% { + opacity: 1; + -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); + transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + } + + 100% { + opacity: 0; + -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); + transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); + -webkit-transform-origin: center bottom; + transform-origin: center bottom; + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + } +} + +@keyframes zoomOutUp { + 40% { + opacity: 1; + -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); + transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); + } + + 100% { + opacity: 0; + -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); + transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); + -webkit-transform-origin: center bottom; + transform-origin: center bottom; + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); + } +} + +.zoomOutUp { + -webkit-animation-name: zoomOutUp; + animation-name: zoomOutUp; +} + +@-webkit-keyframes slideInDown { + 0% { + -webkit-transform: translateY(-100%); + transform: translateY(-100%); + visibility: visible; + } + + 100% { + -webkit-transform: translateY(0); + transform: translateY(0); + } +} + +@keyframes slideInDown { + 0% { + -webkit-transform: translateY(-100%); + transform: translateY(-100%); + visibility: visible; + } + + 100% { + -webkit-transform: translateY(0); + transform: translateY(0); + } +} + +.slideInDown { + -webkit-animation-name: slideInDown; + animation-name: slideInDown; +} + +@-webkit-keyframes slideInLeft { + 0% { + -webkit-transform: translateX(-100%); + transform: translateX(-100%); + visibility: visible; + } + + 100% { + -webkit-transform: translateX(0); + transform: translateX(0); + } +} + +@keyframes slideInLeft { + 0% { + -webkit-transform: translateX(-100%); + transform: translateX(-100%); + visibility: visible; + } + + 100% { + -webkit-transform: translateX(0); + transform: translateX(0); + } +} + +.slideInLeft { + -webkit-animation-name: slideInLeft; + animation-name: slideInLeft; +} + +@-webkit-keyframes slideInRight { + 0% { + -webkit-transform: translateX(100%); + transform: translateX(100%); + visibility: visible; + } + + 100% { + -webkit-transform: translateX(0); + transform: translateX(0); + } +} + +@keyframes slideInRight { + 0% { + -webkit-transform: translateX(100%); + transform: translateX(100%); + visibility: visible; + } + + 100% { + -webkit-transform: translateX(0); + transform: translateX(0); + } +} + +.slideInRight { + -webkit-animation-name: slideInRight; + animation-name: slideInRight; +} + +@-webkit-keyframes slideInUp { + 0% { + -webkit-transform: translateY(100%); + transform: translateY(100%); + visibility: visible; + } + + 100% { + -webkit-transform: translateY(0); + transform: translateY(0); + } +} + +@keyframes slideInUp { + 0% { + -webkit-transform: translateY(100%); + transform: translateY(100%); + visibility: visible; + } + + 100% { + -webkit-transform: translateY(0); + transform: translateY(0); + } +} + +.slideInUp { + -webkit-animation-name: slideInUp; + animation-name: slideInUp; +} + +@-webkit-keyframes slideOutDown { + 0% { + -webkit-transform: translateY(0); + transform: translateY(0); + } + + 100% { + visibility: hidden; + -webkit-transform: translateY(100%); + transform: translateY(100%); + } +} + +@keyframes slideOutDown { + 0% { + -webkit-transform: translateY(0); + transform: translateY(0); + } + + 100% { + visibility: hidden; + -webkit-transform: translateY(100%); + transform: translateY(100%); + } +} + +.slideOutDown { + -webkit-animation-name: slideOutDown; + animation-name: slideOutDown; +} + +@-webkit-keyframes slideOutLeft { + 0% { + -webkit-transform: translateX(0); + transform: translateX(0); + } + + 100% { + visibility: hidden; + -webkit-transform: translateX(-100%); + transform: translateX(-100%); + } +} + +@keyframes slideOutLeft { + 0% { + -webkit-transform: translateX(0); + transform: translateX(0); + } + + 100% { + visibility: hidden; + -webkit-transform: translateX(-100%); + transform: translateX(-100%); + } +} + +.slideOutLeft { + -webkit-animation-name: slideOutLeft; + animation-name: slideOutLeft; +} + +@-webkit-keyframes slideOutRight { + 0% { + -webkit-transform: translateX(0); + transform: translateX(0); + } + + 100% { + visibility: hidden; + -webkit-transform: translateX(100%); + transform: translateX(100%); + } +} + +@keyframes slideOutRight { + 0% { + -webkit-transform: translateX(0); + transform: translateX(0); + } + + 100% { + visibility: hidden; + -webkit-transform: translateX(100%); + transform: translateX(100%); + } +} + +.slideOutRight { + -webkit-animation-name: slideOutRight; + animation-name: slideOutRight; +} + +@-webkit-keyframes slideOutUp { + 0% { + -webkit-transform: translateY(0); + transform: translateY(0); + } + + 100% { + visibility: hidden; + -webkit-transform: translateY(-100%); + transform: translateY(-100%); + } +} + +@keyframes slideOutUp { + 0% { + -webkit-transform: translateY(0); + transform: translateY(0); + } + + 100% { + visibility: hidden; + -webkit-transform: translateY(-100%); + transform: translateY(-100%); + } +} + +.slideOutUp { + -webkit-animation-name: slideOutUp; + animation-name: slideOutUp; +} +.has-animation{ + visibility: hidden; +} +.animated{ + visibility: visible; +} diff --git a/modules/appagebuilder/css/colorpicker/css/colorpicker.css b/modules/appagebuilder/css/colorpicker/css/colorpicker.css new file mode 100644 index 00000000..0b3d5d93 --- /dev/null +++ b/modules/appagebuilder/css/colorpicker/css/colorpicker.css @@ -0,0 +1,161 @@ +.colorpicker { + width: 356px; + height: 176px; + overflow: hidden; + position: absolute; + background: url(../images/colorpicker_background.png); + font-family: Arial, Helvetica, sans-serif; + display: none; +} +.colorpicker_color { + width: 150px; + height: 150px; + left: 14px; + top: 13px; + position: absolute; + background: #f00; + overflow: hidden; + cursor: crosshair; +} +.colorpicker_color div { + position: absolute; + top: 0; + left: 0; + width: 150px; + height: 150px; + background: url(../images/colorpicker_overlay.png); +} +.colorpicker_color div div { + position: absolute; + top: 0; + left: 0; + width: 11px; + height: 11px; + overflow: hidden; + background: url(../images/colorpicker_select.gif); + margin: -5px 0 0 -5px; +} +.colorpicker_hue { + position: absolute; + top: 13px; + left: 171px; + width: 35px; + height: 150px; + cursor: n-resize; +} +.colorpicker_hue div { + position: absolute; + width: 35px; + height: 9px; + overflow: hidden; + background: url(../images/colorpicker_indic.gif) left top; + margin: -4px 0 0 0; + left: 0px; +} +.colorpicker_new_color { + position: absolute; + width: 60px; + height: 30px; + left: 213px; + top: 13px; + background: #f00; +} +.colorpicker_current_color { + position: absolute; + width: 60px; + height: 30px; + left: 283px; + top: 13px; + background: #f00; +} +.colorpicker input { + background-color: transparent; + border: 1px solid transparent; + position: absolute; + font-size: 10px; + font-family: Arial, Helvetica, sans-serif; + color: #898989; + top: 4px; + right: 11px; + text-align: right; + margin: 0; + padding: 0; + height: 11px; +} +.colorpicker_hex { + position: absolute; + width: 72px; + height: 22px; + background: url(../images/colorpicker_hex.png) top; + left: 212px; + top: 142px; +} +.colorpicker_hex input { + right: 6px; +} +.colorpicker_field { + height: 22px; + width: 62px; + background-position: top; + position: absolute; +} +.colorpicker_field span { + position: absolute; + width: 12px; + height: 22px; + overflow: hidden; + top: 0; + right: 0; + cursor: n-resize; +} +.colorpicker_rgb_r { + background-image: url(../images/colorpicker_rgb_r.png); + top: 52px; + left: 212px; +} +.colorpicker_rgb_g { + background-image: url(../images/colorpicker_rgb_g.png); + top: 82px; + left: 212px; +} +.colorpicker_rgb_b { + background-image: url(../images/colorpicker_rgb_b.png); + top: 112px; + left: 212px; +} +.colorpicker_hsb_h { + background-image: url(../images/colorpicker_hsb_h.png); + top: 52px; + left: 282px; +} +.colorpicker_hsb_s { + background-image: url(../images/colorpicker_hsb_s.png); + top: 82px; + left: 282px; +} +.colorpicker_hsb_b { + background-image: url(../images/colorpicker_hsb_b.png); + top: 112px; + left: 282px; +} +.colorpicker_submit { + position: absolute; + width: 22px; + height: 22px; + background: url(../images/colorpicker_submit.png) top; + left: 322px; + top: 142px; + overflow: hidden; +} +.colorpicker_focus { + background-position: center; +} +.colorpicker_hex.colorpicker_focus { + background-position: bottom; +} +.colorpicker_submit.colorpicker_focus { + background-position: bottom; +} +.colorpicker_slider { + background-position: bottom; +} diff --git a/modules/appagebuilder/css/colorpicker/css/index.php b/modules/appagebuilder/css/colorpicker/css/index.php new file mode 100644 index 00000000..dfbb709d --- /dev/null +++ b/modules/appagebuilder/css/colorpicker/css/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; \ No newline at end of file diff --git a/modules/appagebuilder/css/colorpicker/css/layout.css b/modules/appagebuilder/css/colorpicker/css/layout.css new file mode 100644 index 00000000..cc5da1d3 --- /dev/null +++ b/modules/appagebuilder/css/colorpicker/css/layout.css @@ -0,0 +1,218 @@ +body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td { + margin:0; + padding:0; +} +table { + border-collapse:collapse; + border-spacing:0; +} +fieldset,img { + border:0; +} +address,caption,cite,code,dfn,em,strong,th,var { + font-style:normal; + font-weight:normal; +} +ol,ul { + list-style:none; +} +caption,th { + text-align:left; +} +h1,h2,h3,h4,h5,h6 { + font-size:100%; + font-weight:normal; +} +q:before,q:after { + content:''; +} +abbr,acronym { border:0; +} +html, body { + background-color: #fff; + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + line-height: 18px; + color: #52697E; +} +body { + text-align: center; + overflow: auto; +} +.wrapper { + width: 700px; + margin: 0 auto; + text-align: left; +} +h1 { + font-size: 21px; + height: 47px; + line-height: 47px; + text-transform: uppercase; +} +.navigationTabs { + height: 23px; + line-height: 23px; + border-bottom: 1px solid #ccc; +} +.navigationTabs li { + float: left; + height: 23px; + line-height: 23px; + padding-right: 3px; +} +.navigationTabs li a{ + float: left; + dispaly: block; + height: 23px; + line-height: 23px; + padding: 0 10px; + overflow: hidden; + color: #52697E; + background-color: #eee; + position: relative; + text-decoration: none; +} +.navigationTabs li a:hover { + background-color: #f0f0f0; +} +.navigationTabs li a.active { + background-color: #fff; + border: 1px solid #ccc; + border-bottom: 0px solid; +} +.tabsContent { + border: 1px solid #ccc; + border-top: 0px solid; + width: 698px; + overflow: hidden; +} +.tab { + padding: 16px; + display: none; +} +.tab h2 { + font-weight: bold; + font-size: 16px; +} +.tab h3 { + font-weight: bold; + font-size: 14px; + margin-top: 20px; +} +.tab p { + margin-top: 16px; + clear: both; +} +.tab ul { + margin-top: 16px; + list-style: disc; +} +.tab li { + margin: 10px 0 0 35px; +} +.tab a { + color: #8FB0CF; +} +.tab strong { + font-weight: bold; +} +.tab pre { + font-size: 11px; + margin-top: 20px; + width: 668px; + overflow: auto; + clear: both; +} +.tab table { + width: 100%; +} +.tab table td { + padding: 6px 10px 6px 0; + vertical-align: top; +} +.tab dt { + margin-top: 16px; +} + +#colorSelector { + position: relative; + width: 36px; + height: 36px; + background: url(../images/select.png); +} +#colorSelector div { + position: absolute; + top: 3px; + left: 3px; + width: 30px; + height: 30px; + background: url(../images/select.png) center; +} +#colorSelector2 { + position: absolute; + top: 0; + left: 0; + width: 36px; + height: 36px; + background: url(../images/select2.png); +} +#colorSelector2 div { + position: absolute; + top: 4px; + left: 4px; + width: 28px; + height: 28px; + background: url(../images/select2.png) center; +} +#colorpickerHolder2 { + top: 32px; + left: 0; + width: 356px; + height: 0; + overflow: hidden; + position: absolute; +} +#colorpickerHolder2 .colorpicker { + background-image: url(../images/custom_background.png); + position: absolute; + bottom: 0; + left: 0; +} +#colorpickerHolder2 .colorpicker_hue div { + background-image: url(../images/custom_indic.gif); +} +#colorpickerHolder2 .colorpicker_hex { + background-image: url(../images/custom_hex.png); +} +#colorpickerHolder2 .colorpicker_rgb_r { + background-image: url(../images/custom_rgb_r.png); +} +#colorpickerHolder2 .colorpicker_rgb_g { + background-image: url(../images/custom_rgb_g.png); +} +#colorpickerHolder2 .colorpicker_rgb_b { + background-image: url(../images/custom_rgb_b.png); +} +#colorpickerHolder2 .colorpicker_hsb_s { + background-image: url(../images/custom_hsb_s.png); + display: none; +} +#colorpickerHolder2 .colorpicker_hsb_h { + background-image: url(../images/custom_hsb_h.png); + display: none; +} +#colorpickerHolder2 .colorpicker_hsb_b { + background-image: url(../images/custom_hsb_b.png); + display: none; +} +#colorpickerHolder2 .colorpicker_submit { + background-image: url(../images/custom_submit.png); +} +#colorpickerHolder2 .colorpicker input { + color: #778398; +} +#customWidget { + position: relative; + height: 36px; +} diff --git a/modules/appagebuilder/css/colorpicker/images/blank.gif b/modules/appagebuilder/css/colorpicker/images/blank.gif new file mode 100644 index 00000000..75b945d2 Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/blank.gif differ diff --git a/modules/appagebuilder/css/colorpicker/images/colorpicker_background.png b/modules/appagebuilder/css/colorpicker/images/colorpicker_background.png new file mode 100644 index 00000000..8401572f Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/colorpicker_background.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/colorpicker_hex.png b/modules/appagebuilder/css/colorpicker/images/colorpicker_hex.png new file mode 100644 index 00000000..4e532d7c Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/colorpicker_hex.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/colorpicker_hsb_b.png b/modules/appagebuilder/css/colorpicker/images/colorpicker_hsb_b.png new file mode 100644 index 00000000..dfac595d Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/colorpicker_hsb_b.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/colorpicker_hsb_h.png b/modules/appagebuilder/css/colorpicker/images/colorpicker_hsb_h.png new file mode 100644 index 00000000..3977ed9f Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/colorpicker_hsb_h.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/colorpicker_hsb_s.png b/modules/appagebuilder/css/colorpicker/images/colorpicker_hsb_s.png new file mode 100644 index 00000000..a2a69973 Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/colorpicker_hsb_s.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/colorpicker_indic.gif b/modules/appagebuilder/css/colorpicker/images/colorpicker_indic.gif new file mode 100644 index 00000000..f9fa95e2 Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/colorpicker_indic.gif differ diff --git a/modules/appagebuilder/css/colorpicker/images/colorpicker_overlay.png b/modules/appagebuilder/css/colorpicker/images/colorpicker_overlay.png new file mode 100644 index 00000000..561cdd9c Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/colorpicker_overlay.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/colorpicker_rgb_b.png b/modules/appagebuilder/css/colorpicker/images/colorpicker_rgb_b.png new file mode 100644 index 00000000..dfac595d Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/colorpicker_rgb_b.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/colorpicker_rgb_g.png b/modules/appagebuilder/css/colorpicker/images/colorpicker_rgb_g.png new file mode 100644 index 00000000..72b32760 Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/colorpicker_rgb_g.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/colorpicker_rgb_r.png b/modules/appagebuilder/css/colorpicker/images/colorpicker_rgb_r.png new file mode 100644 index 00000000..4855fe03 Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/colorpicker_rgb_r.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/colorpicker_select.gif b/modules/appagebuilder/css/colorpicker/images/colorpicker_select.gif new file mode 100644 index 00000000..599f7f13 Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/colorpicker_select.gif differ diff --git a/modules/appagebuilder/css/colorpicker/images/colorpicker_submit.png b/modules/appagebuilder/css/colorpicker/images/colorpicker_submit.png new file mode 100644 index 00000000..7f4c0825 Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/colorpicker_submit.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/custom_background.png b/modules/appagebuilder/css/colorpicker/images/custom_background.png new file mode 100644 index 00000000..cf55ffdd Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/custom_background.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/custom_hex.png b/modules/appagebuilder/css/colorpicker/images/custom_hex.png new file mode 100644 index 00000000..888f4444 Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/custom_hex.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/custom_hsb_b.png b/modules/appagebuilder/css/colorpicker/images/custom_hsb_b.png new file mode 100644 index 00000000..2f99dae8 Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/custom_hsb_b.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/custom_hsb_h.png b/modules/appagebuilder/css/colorpicker/images/custom_hsb_h.png new file mode 100644 index 00000000..a217e921 Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/custom_hsb_h.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/custom_hsb_s.png b/modules/appagebuilder/css/colorpicker/images/custom_hsb_s.png new file mode 100644 index 00000000..7826b415 Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/custom_hsb_s.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/custom_indic.gif b/modules/appagebuilder/css/colorpicker/images/custom_indic.gif new file mode 100644 index 00000000..222fb94c Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/custom_indic.gif differ diff --git a/modules/appagebuilder/css/colorpicker/images/custom_rgb_b.png b/modules/appagebuilder/css/colorpicker/images/custom_rgb_b.png new file mode 100644 index 00000000..80764e5d Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/custom_rgb_b.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/custom_rgb_g.png b/modules/appagebuilder/css/colorpicker/images/custom_rgb_g.png new file mode 100644 index 00000000..fc9778be Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/custom_rgb_g.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/custom_rgb_r.png b/modules/appagebuilder/css/colorpicker/images/custom_rgb_r.png new file mode 100644 index 00000000..91b0cd4c Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/custom_rgb_r.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/custom_submit.png b/modules/appagebuilder/css/colorpicker/images/custom_submit.png new file mode 100644 index 00000000..cd202cd9 Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/custom_submit.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/index.php b/modules/appagebuilder/css/colorpicker/images/index.php new file mode 100644 index 00000000..dfbb709d --- /dev/null +++ b/modules/appagebuilder/css/colorpicker/images/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; \ No newline at end of file diff --git a/modules/appagebuilder/css/colorpicker/images/select.png b/modules/appagebuilder/css/colorpicker/images/select.png new file mode 100644 index 00000000..21213bfd Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/select.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/select2.png b/modules/appagebuilder/css/colorpicker/images/select2.png new file mode 100644 index 00000000..2cd2cabe Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/select2.png differ diff --git a/modules/appagebuilder/css/colorpicker/images/slider.png b/modules/appagebuilder/css/colorpicker/images/slider.png new file mode 100644 index 00000000..8b03da96 Binary files /dev/null and b/modules/appagebuilder/css/colorpicker/images/slider.png differ diff --git a/modules/appagebuilder/css/colorpicker/index.php b/modules/appagebuilder/css/colorpicker/index.php new file mode 100644 index 00000000..dfbb709d --- /dev/null +++ b/modules/appagebuilder/css/colorpicker/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; \ No newline at end of file diff --git a/modules/appagebuilder/css/index.php b/modules/appagebuilder/css/index.php new file mode 100644 index 00000000..e0c4a9c7 --- /dev/null +++ b/modules/appagebuilder/css/index.php @@ -0,0 +1,35 @@ + + * @copyright 2007-2016 PrestaShop SA + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * International Registered Trademark & Property of PrestaShop SA + */ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; diff --git a/modules/appagebuilder/css/jquery.fullPage.css b/modules/appagebuilder/css/jquery.fullPage.css new file mode 100644 index 00000000..3e9e46e9 --- /dev/null +++ b/modules/appagebuilder/css/jquery.fullPage.css @@ -0,0 +1,208 @@ +/** + * fullPage 2.6.6 + * https://github.com/alvarotrigo/fullPage.js + * MIT licensed + * + * Copyright (C) 2013 alvarotrigo.com - A project by Alvaro Trigo + */ +html.fp-enabled, +.fp-enabled body { + margin: 0; + padding: 0; + overflow:hidden; + + /*Avoid flicker on slides transitions for mobile phones #336 */ + -webkit-tap-highlight-color: rgba(0,0,0,0); +} +#superContainer { + height: 100%; + position: relative; + + /* Touch detection for Windows 8 */ + -ms-touch-action: none; + + /* IE 11 on Windows Phone 8.1*/ + touch-action: none; +} +.fp-section { + position: relative; + -webkit-box-sizing: border-box; /* Safari<=5 Android<=3 */ + -moz-box-sizing: border-box; /* <=28 */ + box-sizing: border-box; +} +.fp-slide { + float: left; +} +.fp-slide, .fp-slidesContainer { + height: 100%; + display: block; +} +.fp-slides { + z-index:1; + height: 100%; + overflow: hidden; + position: relative; + -webkit-transition: all 0.3s ease-out; /* Safari<=6 Android<=4.3 */ + transition: all 0.3s ease-out; +} +.fp-section.fp-table, .fp-slide.fp-table { + display: table; + table-layout:fixed; + width: 100%; +} +.fp-tableCell { + display: table-cell; + vertical-align: middle; + width: 100%; + height: 100%; +} +.fp-slidesContainer { + float: left; + position: relative; +} +.fp-controlArrow { + position: absolute; + z-index: 4; + top: 50%; + cursor: pointer; + width: 0; + height: 0; + border-style: solid; + margin-top: -38px; + -webkit-transform: translate3d(0,0,0); + -ms-transform: translate3d(0,0,0); + transform: translate3d(0,0,0); +} +.fp-controlArrow.fp-prev { + left: 15px; + width: 0; + border-width: 38.5px 34px 38.5px 0; + border-color: transparent #fff transparent transparent; +} +.fp-controlArrow.fp-next { + right: 15px; + border-width: 38.5px 0 38.5px 34px; + border-color: transparent transparent transparent #fff; +} +.fp-scrollable { + overflow: scroll; +} +.fp-notransition { + -webkit-transition: none !important; + transition: none !important; +} +#fp-nav { + position: fixed; + z-index: 100; + margin-top: -32px; + top: 50%; + opacity: 1; + -webkit-transform: translate3d(0,0,0); +} +#fp-nav.right { + right: 17px; +} +#fp-nav.left { + left: 17px; +} +.fp-slidesNav{ + position: absolute; + z-index: 4; + left: 50%; + opacity: 1; +} +.fp-slidesNav.bottom { + bottom: 17px; +} +.fp-slidesNav.top { + top: 17px; +} +#fp-nav ul, +.fp-slidesNav ul { + margin: 0; + padding: 0; +} +#fp-nav ul li, +.fp-slidesNav ul li { + display: block; + width: 14px; + height: 13px; + margin: 7px; + position:relative; +} +.fp-slidesNav ul li { + display: inline-block; +} +#fp-nav ul li a, +.fp-slidesNav ul li a { + display: block; + position: relative; + z-index: 1; + width: 100%; + height: 100%; + cursor: pointer; + text-decoration: none; +} +#fp-nav ul li a.active span, +.fp-slidesNav ul li a.active span, +#fp-nav ul li:hover a.active span, +.fp-slidesNav ul li:hover a.active span{ + height: 12px; + width: 12px; + margin: -6px 0 0 -6px; + border-radius: 100%; + } +#fp-nav ul li a span, +.fp-slidesNav ul li a span { + border-radius: 50%; + position: absolute; + z-index: 1; + height: 4px; + width: 4px; + border: 0; + background: #333; + left: 50%; + top: 50%; + margin: -2px 0 0 -2px; + -webkit-transition: all 0.1s ease-in-out; + -moz-transition: all 0.1s ease-in-out; + -o-transition: all 0.1s ease-in-out; + transition: all 0.1s ease-in-out; +} +#fp-nav ul li:hover a span, +.fp-slidesNav ul li:hover a span{ + width: 10px; + height: 10px; + margin: -5px 0px 0px -5px; +} +#fp-nav ul li .fp-tooltip { + position: absolute; + top: -2px; + color: #fff; + font-size: 14px; + font-family: arial, helvetica, sans-serif; + white-space: nowrap; + max-width: 220px; + overflow: hidden; + display: block; + opacity: 0; + width: 0; +} +#fp-nav ul li:hover .fp-tooltip, +#fp-nav.fp-show-active a.active + .fp-tooltip { + -webkit-transition: opacity 0.2s ease-in; + transition: opacity 0.2s ease-in; + width: auto; + opacity: 1; +} +#fp-nav ul li .fp-tooltip.right { + right: 20px; +} +#fp-nav ul li .fp-tooltip.left { + left: 20px; +} +.fp-auto-height.fp-section, +.fp-auto-height .fp-slide, +.fp-auto-height .fp-tableCell{ + height: auto !important; +} \ No newline at end of file diff --git a/modules/appagebuilder/css/owl.carousel.css b/modules/appagebuilder/css/owl.carousel.css new file mode 100644 index 00000000..86e4870d --- /dev/null +++ b/modules/appagebuilder/css/owl.carousel.css @@ -0,0 +1,253 @@ +/* + * Core Owl Carousel CSS File + * v1.3.3 + */ + +/* clearfix */ +.owl-carousel .owl-wrapper:after { + content: "."; + display: block; + clear: both; + visibility: hidden; + line-height: 0; + height: 0; +} +/* display none until init */ +.owl-carousel{ + //display: none; + display: block; + position: relative; + width: 100%; + -ms-touch-action: pan-y; +} +.owl-carousel .owl-wrapper{ + //display: none; + position: relative; + -webkit-transform: translate3d(0px, 0px, 0px); +} +.owl-carousel .owl-wrapper-outer{ + overflow: hidden; + position: relative; + width: 100%; +} +.owl-carousel .owl-wrapper-outer.autoHeight{ + -webkit-transition: height 500ms ease-in-out; + -moz-transition: height 500ms ease-in-out; + -ms-transition: height 500ms ease-in-out; + -o-transition: height 500ms ease-in-out; + transition: height 500ms ease-in-out; +} + +.owl-carousel .owl-item{ + float: left; +} +.owl-controls .owl-page, +.owl-controls .owl-buttons div{ + cursor: pointer; +} +.owl-controls { + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +/* mouse grab icon */ +.grabbing { + cursor:url(../img/grabbing.png) 8 8, move; +} + +/* fix */ +.owl-carousel .owl-wrapper, +.owl-carousel .owl-item{ + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + -ms-backface-visibility: hidden; + -webkit-transform: translate3d(0,0,0); + -moz-transform: translate3d(0,0,0); + -ms-transform: translate3d(0,0,0); +} + +.rtl .owl-carousel .owl-item { + float: right; +} + +/************DONGND:: new loading for owl product carousel**************/ +.owl-carousel.owl-loading .item { + display: none; +} + +.owl-row.hide-loading .timeline-wrapper, .timeline-wrapper.prepare +{ + display: none; +} + +.timeline-item { + background: #fff; + border: 1px solid; + border-color: #e5e6e9 #dfe0e4 #d0d1d5; + border-radius: 3px; + padding: 12px; + + margin: 0 auto 10px auto; + /*max-width: 472px;*/ + width: 100%; + + min-height: 200px; +} + +@-webkit-keyframes placeHolderShimmer{ + 0%{ + background-position: -468px 0 + } + 100%{ + background-position: 468px 0 + } +} + +@keyframes placeHolderShimmer{ + 0%{ + background-position: -468px 0 + } + 100%{ + background-position: 468px 0 + } +} + +.animated-background { + -webkit-animation-duration: 1s; + animation-duration: 1s; + -webkit-animation-fill-mode: forwards; + animation-fill-mode: forwards; + -webkit-animation-iteration-count: infinite; + animation-iteration-count: infinite; + -webkit-animation-name: placeHolderShimmer; + animation-name: placeHolderShimmer; + -webkit-animation-timing-function: linear; + animation-timing-function: linear; + background: #f6f7f8; + background: -webkit-gradient(linear, left top, right top, color-stop(8%, #eeeeee), color-stop(18%, #dddddd), color-stop(33%, #eeeeee)); + background: -webkit-linear-gradient(left, #eeeeee 8%, #dddddd 18%, #eeeeee 33%); + background: linear-gradient(to right, #eeeeee 8%, #dddddd 18%, #eeeeee 33%); + -webkit-background-size: 800px 104px; + background-size: 800px 104px; + /* + height: 96px; + */ + height: 250px; + position: relative; +} +.owl-manu .animated-background +{ + height: 110px; +} + +.owl-manu .timeline-item +{ + min-height: 110px; +} + +.background-masker { + background: #fff; + position: absolute; +} + +/* Every thing below this is just positioning */ + +.background-masker.header-top, +.background-masker.header-bottom, +.background-masker.subheader-bottom { + top: 0; + left: 40px; + right: 0; + height: 10px; +} + +.background-masker.header-left, +.background-masker.subheader-left, +.background-masker.header-right, +.background-masker.subheader-right { + top: 10px; + left: 40px; + height: 8px; + width: 10px; +} + +.background-masker.header-bottom { + top: 18px; + height: 6px; +} + +.background-masker.subheader-left, +.background-masker.subheader-right { + top: 24px; + height: 6px; +} + + +.background-masker.header-right, +.background-masker.subheader-right { + width: auto; + left: 300px; + right: 0; +} + +.background-masker.subheader-right { + left: 230px; +} + +.background-masker.subheader-bottom { + top: 30px; + height: 10px; +} + +.background-masker.content-top, +.background-masker.content-second-line, +.background-masker.content-third-line, +.background-masker.content-fourth-line, +.background-masker.content-second-end, +.background-masker.content-third-end, +.background-masker.content-first-end { + top: 150px; + left: 0; + right: 0; + height: 6px; +} + +.background-masker.content-top { + height:20px; +} + +.background-masker.content-first-end, +.background-masker.content-second-end, +.background-masker.content-third-end{ + + width: auto; + left: 380px; + right: 0; + top: 60px; + height: 8px; +} + +.background-masker.content-second-line { + top: 180px; +} + +.background-masker.content-second-end { + left: 420px; + top: 74px; +} + +.background-masker.content-third-line { + top: 200px; +} + +.background-masker.content-fourth-line{ + top: 225px; +} +.background-masker.content-third-end { + left: 300px; + top: 88px; +} \ No newline at end of file diff --git a/modules/appagebuilder/css/owl.theme.css b/modules/appagebuilder/css/owl.theme.css new file mode 100644 index 00000000..4dc4b22e --- /dev/null +++ b/modules/appagebuilder/css/owl.theme.css @@ -0,0 +1,134 @@ +/* +* Owl Carousel Owl Demo Theme +* v1.3.3 +*/ +.owl-row { + margin: 0 -15px; +} + +.owl-carousel .owl-item { + padding: 0 15px; +} +.owl-theme .owl-controls{ + margin-top: 10px; + text-align: center; + +} + +/* Styling Next and Prev buttons */ + +.owl-theme .owl-controls .owl-buttons div{ + color: #000; + display: inline-block; + zoom: 1; + *display: inline;/*IE7 life-saver */ + margin: 5px; + padding: 8px 15px; + font-size: 20px; + -webkit-border-radius: 30px; + -moz-border-radius: 30px; + border-radius: 30px; + background: #eeeeee; + filter: Alpha(Opacity=50);/*IE7 fix*/ +} +/* Clickable class fix problem with hover on touch devices */ +/* Use it for non-touch hover action */ +.owl-theme .owl-controls.clickable .owl-buttons div:hover{ + filter: Alpha(Opacity=100);/*IE7 fix*/ + opacity: 1; + text-decoration: none; + background: rgba(0, 0, 0, 0.3); + color: #fff; +} + +/* Styling Pagination*/ + +.owl-theme .owl-controls .owl-page{ + display: inline-block; + zoom: 1; + *display: inline;/*IE7 life-saver */ +} + + +.owl-theme .owl-controls .owl-page.active span, +.owl-theme .owl-controls.clickable .owl-page:hover span{ + filter: Alpha(Opacity=100);/*IE7 fix*/ + opacity: 1; +} + +.owl-theme .owl-controls .owl-page span { + display: block; + width: 16px; + height: 16px; + margin: 5px 10px; + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + -ms-border-radius: 100%; + -o-border-radius: 100%; + border-radius: 100%; + border: 2px solid #fff; + background-color: transparent; + position: relative; + -webkit-transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); + transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); +} +.owl-theme .owl-controls .owl-page span:before { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + -webkit-transform: scale(1); + -moz-transform: scale(1); + -ms-transform: scale(1); + -o-transform: scale(1); + -webkit-border-radius: 100%; + -moz-border-radius: 100%; + -ms-border-radius: 100%; + -o-border-radius: 100%; + border-radius: 100%; + -webkit-transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); + transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +.owl-theme .owl-controls.clickable .owl-page:hover span:before { + -webkit-transform: scale(3); + -moz-transform: scale(3); + -ms-transform: scale(3); + -o-transform: scale(3); + background-color: black; + background-color: rgba(244, 244, 244, 0.17); + zoom: 1; + background-color: transparent\9; +} + +.owl-theme .owl-controls .owl-page.active span { + border-color: #fff; +} +.owl-theme .owl-controls .owl-page.active span:before { + -webkit-transform: scale(0.6); + -moz-transform: scale(0.6); + -ms-transform: scale(0.6); + -o-transform: scale(0.6); + background-color: #fff; +} + +/* If PaginationNumbers is true */ + +.owl-theme .owl-controls .owl-page span.owl-numbers{ + height: auto; + width: auto; + color: #FFF; + padding: 2px 10px; + font-size: 12px; + -webkit-border-radius: 30px; + -moz-border-radius: 30px; + border-radius: 30px; +} + +/* preloading images */ +.owl-item.loading{ + min-height: 150px; + background: url(../img/AjaxLoader.gif) no-repeat center center +} \ No newline at end of file diff --git a/modules/appagebuilder/css/paneltool.css b/modules/appagebuilder/css/paneltool.css new file mode 100644 index 00000000..4d9a47c0 --- /dev/null +++ b/modules/appagebuilder/css/paneltool.css @@ -0,0 +1,515 @@ +/** +* Transition-timing-function property@mixin +*/ +/*background RGBA +============================================*/ +/****/ +/* RIGHT TO LEFT */ +/** + * Web Application Prefix Apply For Making Owner Styles + */ +/** + * Blocks Layout Selectors + */ +/***********************************************************************/ +/** CHECKOUT BY STEP */ +/* RIGHT TO LEFT */ +/**********************************/ +.fancybox-skin .leo-paneltool { + display: none; +} + +.paneltool { + position: fixed; + top: 5px; + -webkit-transition: all 0.6s ease 0s; + transition: all 0.6s ease 0s; + width: 235px; + right: -235px; + z-index: 99999; +} +.rtl .paneltool { + left: -235px; + right: auto; +} +.paneltool .leo-dynamic-update-side { + text-transform: uppercase; + display: inline-block; + margin-top: 10px; + border: 1px solid; + padding: 5px; + font-size: 11px; +} +.paneltool .leo-dynamic-update-side.current-sidebar { + color: #a59a4c; +} +.paneltool.themetool { + top: 70px; +} +.paneltool.themetool.active { + z-index: 999999; +} +.paneltool.themetool .panelbutton { + width: 50px; + height: 50px; + left: -50px; +} +.rtl .paneltool.themetool .panelbutton { + right: -50px; + left: auto; +} +.paneltool.themetool .panelcontent { + min-height: 130px; + height: 100%; + overflow-y: auto; +} +.paneltool.themetool .group-input { + margin-bottom: 20px; +} +.paneltool.themetool .group-input.layout .leo-dynamic-update-layout { + display: block; + float: left; + width: 100%; + padding: 10px 0 10px 10px; + position: relative; + font-size: 14px; +} +.paneltool.themetool .group-input.layout .leo-dynamic-update-layout:before { + content: "+"; +} +.paneltool.themetool .group-input span { + cursor: pointer; +} +.paneltool.themetool .panelinner .group-input:last-child { + margin-bottom: 0px; +} +.paneltool.themetool label { + font-size: 14px; + text-transform: uppercase; + font-weight: bold; + text-align: left; +} +.rtl .paneltool.themetool label { + text-align: right; +} +.paneltool.themetool label span { + margin-right: 10px; + vertical-align: middle; +} +.rtl .paneltool.themetool label span { + margin-left: 10px; + margin-right: inherit; +} +.paneltool.themetool .leo-dynamic-update-header { + display: block; + padding: 10px; + font-size: 11px; + text-transform: uppercase; +} +.paneltool.themetool .leo-dynamic-update-header.current-header { + color: #a59a4c; +} +.paneltool.active { + right: 0; + -webkit-transition: all 0.6s; + transition: all 0.6s; +} +.rtl .paneltool.active { + left: 0; + right: auto; +} +.paneltool.active .panelbutton { + color: #FFF; +} +.paneltool .panelcontent { + background: #f2f2f2; + min-height: 340px; +} +.paneltool .panelcontent > div { + padding: 15px; +} +.paneltool.editortool .panelbutton { + top: 290px; +} + +.panelbutton { + background: #000; + position: absolute; + left: -50px; + top: 165px; + border-left: none; + cursor: pointer; + width: 50px; + height: 50px; + line-height: 50px; + text-align: center; + color: #333333; + font-size: 26px; + -webkit-box-shadow: none; + box-shadow: none; +} +.rtl .panelbutton { + right: -50px; + left: auto; +} +.rtl .panelbutton { + border-right: none; + border-left: inherit; +} +.panelbutton.label-customize { + display: none; +} + +#leo-paneltool { + width: 300px; + height: 100%; + top: 0; + left: -320px; + z-index: 9999; + -webkit-box-shadow: 0 1px 3px #999999; + box-shadow: 0 1px 3px #999999; + -webkit-transition-duration: 0.2s; + transition-duration: 0.2s; + -webkit-transition-property: left, right, top, bottom, width, margin; + transition-property: left, right, top, bottom, width, margin; + background: none repeat scroll 0 0 #F5F5F5; + border-right: 1px solid rgba(0, 0, 0, 0.2); +} +.rtl #leo-paneltool { + right: -320px; + left: auto; +} +.rtl #leo-paneltool { + border-left: 1px solid rgba(0, 0, 0, 0.2); + border-right: inherit; +} +#leo-paneltool h4 { + margin-bottom: 20px; + margin-top: 0; + text-transform: uppercase; + font-size: 16px; + font-weight: bold; +} +#leo-paneltool .accordion-group { + margin-bottom: 5px; +} +#leo-paneltool .panel-body { + max-height: 500px; + overflow-y: auto; +} +#leo-paneltool .block-panelcontent { + overflow-x: hidden; + overflow-y: auto; + max-height: 600px; +} +#leo-paneltool form .group-input { + margin-bottom: 10px; +} +#leo-paneltool select { + padding: 5px; +} +#leo-paneltool .nav-tabs > li:after, #leo-paneltool .nav-tabs > li:before { + display: none; +} + +/* Select Skin */ +.leo-dynamic-theme-skin { + float: left; + margin-left: 5px; + width: 20px; + height: 20px; + margin-top: 10px; + cursor: pointer; +} +.leo-dynamic-theme-skin img { + border: 2px solid transparent; +} +.leo-dynamic-theme-skin.skin-default { + background-color: #a59a4c; + text-indent: -99999px; +} +.leo-dynamic-theme-skin.current-theme-skin img { + border-color: black; +} +.leo-dynamic-theme-skin.current-theme-skin.skin-default { + border: 2px solid black; +} + +/* Select Layout*/ +.leo-dynamic-update-layout:hover { + color: #a59a4c; +} +.leo-dynamic-update-layout.current-layout-mod { + color: #a59a4c; +} + +/* Enable Float Header */ +.btn_enable_fheader { + background-color: #25292C; + margin-top: 10px; + margin-left: 10px; + width: 100px; + height: 36px; + -webkit-border-radius: 18px; + -moz-border-radius: 18px; + -ms-border-radius: 18px; + -o-border-radius: 18px; + border-radius: 18px; + position: relative; +} + +.enable_fheader { + display: inline-block; + width: 30px; + height: 30px; + line-height: 30px; + text-align: center; + color: white; + background-color: #504C4C; + margin-top: 3px; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + -ms-border-radius: 50%; + -o-border-radius: 50%; + border-radius: 50%; +} +.enable_fheader i { + position: relative; + z-index: 9; +} +.enable_fheader:first-child { + float: left; + margin-left: 3px; +} +.enable_fheader:last-child { + float: right; + margin-right: 3px; +} +.enable_fheader.btn_no:before { + content: ""; + position: absolute; + width: 30px; + height: 30px; + top: 3px; + left: 4px; + -webkit-border-radius: 18px; + -moz-border-radius: 18px; + -ms-border-radius: 18px; + -o-border-radius: 18px; + border-radius: 18px; + background-color: #a59a4c; + opacity: 0; + filter: alpha(opacity=0); + visibility: hidden; +} +.enable_fheader.btn_yes:after { + content: ""; + position: absolute; + width: 30px; + height: 30px; + top: 3px; + right: 4px; + -webkit-border-radius: 18px; + -moz-border-radius: 18px; + -ms-border-radius: 18px; + -o-border-radius: 18px; + border-radius: 18px; + background-color: #a59a4c; + opacity: 0; + filter: alpha(opacity=0); + visibility: hidden; +} +.enable_fheader.current.btn_no:before { + opacity: 1; + filter: alpha(opacity=100); + visibility: visible; + left: 67px; + -webkit-transition: all 0.7s ease 0s; + transition: all 0.7s ease 0s; +} +.enable_fheader.current.btn_yes:after { + opacity: 1; + filter: alpha(opacity=100); + visibility: visible; + right: 67px; + -webkit-transition: all 0.7s ease 0s; + transition: all 0.7s ease 0s; +} + +/* Box Patterns */ +.box-patterns div { + display: block; + width: 38px; + height: 38px; + float: left; + cursor: pointer; + margin: 6px; + border: 1px solid #ccc; +} +.rtl .box-patterns div { + float: right; +} +.box-patterns div.active { + border-color: red; +} + +.colorpicker { + z-index: 99999; +} + +/* Customize body */ +#customize-body input[type="text"], #customize-body select { + border: 1px solid #E2E2E2; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + -ms-border-radius: 2px; + -o-border-radius: 2px; + border-radius: 2px; + color: #FFFFFF; + font-size: 11px; + margin: 0 5px 0 0; + padding: 2px 3px; + width: 65px; + height: auto; + display: inline-block; +} +#customize-body select { + color: #888; +} +#customize-body .accordion-group label { + color: #888; + font-size: 11px; + font-weight: normal; +} +#customize-body .accordion-group label.subtitle { + font-weight: bold; + font-size: 0.75rem; + color: #333; + border-bottom: 1px solid #eaeaea; + padding-bottom: 4px; + margin-top: 0.625rem; + display: inline-block; + width: 100%; + text-transform: uppercase; } +#customize-body .accordion-group .input-group .input-group-addon { + padding: 0; + background: transparent; + border: none; + float: right; + margin-top: 2px; + width: 20px; +} +.rtl #customize-body .accordion-group .input-group .input-group-addon { + float: left; +} +#customize-body .panel-heading { + padding: 5px 6px; + font-weight: bold; + font-size: 11px; +} +#customize-body .panel-heading a { + display: block; +} + +#customize-body .nav-tabs a { + border: none; + font-weight: bold; + font-size: 11px; + padding: 6px 12px; +} +#customize-body .nav-tabs a.active{ + color: white; +} +#customize-body .form-group { + margin-bottom: 10px; + display: inline-block; + width: 100%; +} +#customize-body .accordion-inner .form-group .input-group { + display: inline-block; + width: 92px; + float: left; +} +.rtl #customize-body .accordion-inner .form-group .input-group { + float: right; +} + +/* wrapper */ +.bi-wrapper > div { + float: left; + width: 25px; + height: 25px; + margin: 3px 4px; + border: solid 1px #999; + cursor: pointer; +} +.rtl .bi-wrapper > div { + float: right; +} +.bi-wrapper > div.active { + border-color: red; +} + +/* Accordion */ +.accordion-group label, +.form-group label { + display: block; + text-align: left; +} +.rtl .accordion-group label, +.rtl .form-group label { + text-align: right; +} +.accordion-group label { + min-width: 130px; +} + +.clear-bg { + padding: 3px 6px; + margin-left: 5px; + font-size: 11px; +} +.rtl .clear-bg { + margin-right: 5px; + margin-left: inherit; +} + +/* Home page version */ +.group-profile a, +.group-header a, +.group-footer a { + display: inline-block; + font-size: 14px; + line-height: 25px; + color: #777777; +} +.group-profile a:before, +.group-header a:before, +.group-footer a:before { + content: "\f067"; + font-family: "FontAwesome"; + padding-right: 5px; + font-size: 10px; +} +.rtl .group-profile a:before, .rtl +.group-header a:before, .rtl +.group-footer a:before { + padding-left: 5px; + padding-right: inherit; +} +.group-profile a.active, +.group-header a.active, +.group-footer a.active { + color: #bfa08b; +} + +.group-profile a, +.group-header a, +.group-footer a { + width: 100%; +} +.rtl .group-profile a, .rtl +.group-header a, .rtl +.group-footer a { + float: right; +} \ No newline at end of file diff --git a/modules/appagebuilder/css/slick-theme.css b/modules/appagebuilder/css/slick-theme.css new file mode 100644 index 00000000..77e58696 --- /dev/null +++ b/modules/appagebuilder/css/slick-theme.css @@ -0,0 +1,144 @@ +@charset "UTF-8"; +/*************************************************** + Mixins Themes +/***************************************************/ +/* Mixin Normal*/ +/* Mixin Clear */ +/* Mixin Border */ +/*background RGBA +============================================*/ +/*************************************************** + Mixins RTL Themes +/***************************************************/ +/************************************ + Override Bootstrap +*************************************/ +/** + * Web Application Prefix Apply For Making Owner Styles + */ +/** + * Blocks Layout Selectors + */ +/***********************************************************************/ +/* Slider */ +.slick-loading .slick-list { + background: #fff url("../img/ajax-loader.gif") center center no-repeat; } + +/* Arrows */ +.slick-arrows .slick-arrow { + position: absolute; + display: block; + height: 20px; + width: 20px; + line-height: 0px; + font-size: 0px; + z-index: 9; + cursor: pointer; + background: transparent; + color: transparent; + top: 50%; + padding: 0; + border: none; + outline: none; + color: black; + -webkit-transition: all 0.3s ease; + -moz-transition: all 0.3s ease; + -ms-transition: all 0.3s ease; + -o-transition: all 0.3s ease; + transition: all 0.3s ease; + -webkit-transform: translate(0, -50%); + -moz-transform: translate(0, -50%); + -ms-transform: translate(0, -50%); + -o-transform: translate(0, -50%); + transform: translate(0, -50%); } + .slick-arrows .slick-arrow:hover, .slick-arrows .slick-arrow:focus { + outline: none; } + .slick-arrows .slick-arrow:hover:before, .slick-arrows .slick-arrow:focus:before { + opacity: 1; + filter: alpha(opacity=100); } + .slick-arrows .slick-arrow.slick-disabled:before { + opacity: 0.25; + filter: alpha(opacity=25); } + .slick-arrows .slick-arrow:before { + font-size: 25px; + display: block; + font-family: 'Material Icons'; + opacity: 0.75; + filter: alpha(opacity=75); } + .slick-arrows .slick-arrow.slick-prev { + left: -25px; } + [dir="rtl"] .slick-arrows .slick-arrow.slick-prev { + left: auto; + right: -25px; } + .slick-arrows .slick-arrow.slick-prev:before { + content: "\E314"; } + [dir="rtl"] .slick-arrows .slick-arrow.slick-prev:before { + content: "\E315"; } + .slick-arrows .slick-arrow.slick-next { + right: -25px; } + [dir="rtl"] .slick-arrows .slick-arrow.slick-next { + left: -25px; + right: auto; } + .slick-arrows .slick-arrow.slick-next:before { + content: "\E315"; } + [dir="rtl"] .slick-arrows .slick-arrow.slick-next:before { + content: "\E314"; } + +/* Dots */ +.slick-dotted.slick-slider { + margin-bottom: 30px; } + +.slick-dots { + position: absolute; + bottom: -25px; + list-style: none; + display: block; + text-align: center; + padding: 0; + margin: 0; + width: 100%; } + .slick-dots li { + position: relative; + display: inline-block; + height: 20px; + width: 20px; + margin: 0 5px; + padding: 0; + cursor: pointer; } + .slick-dots li button { + border: 0; + background: transparent; + display: block; + height: 20px; + width: 20px; + outline: none; + line-height: 0px; + font-size: 0px; + color: transparent; + padding: 5px; + cursor: pointer; } + .slick-dots li button:hover, .slick-dots li button:focus { + outline: none; } + .slick-dots li button:hover:before, .slick-dots li button:focus:before { + opacity: 1; + filter: alpha(opacity=100); } + .slick-dots li button:before { + position: absolute; + top: 0; + left: 0; + content: ""; + width: 20px; + height: 20px; + font-family: "FontAwesome"; + font-size: 10px; + line-height: 20px; + text-align: center; + color: black; + opacity: 0.25; + filter: alpha(opacity=25); } + .slick-dots li.slick-active button:before { + color: black; + opacity: 0.75; + filter: alpha(opacity=75); } + +/*# sourceMappingURL=slick-theme.css.map */ diff --git a/modules/appagebuilder/css/slick.css b/modules/appagebuilder/css/slick.css new file mode 100644 index 00000000..297a58a9 --- /dev/null +++ b/modules/appagebuilder/css/slick.css @@ -0,0 +1,102 @@ +/*************************************************** + Mixins Themes +/***************************************************/ +/* Mixin Normal*/ +/* Mixin Clear */ +/* Mixin Border */ +/*background RGBA +============================================*/ +/*************************************************** + Mixins RTL Themes +/***************************************************/ +/************************************ + Override Bootstrap +*************************************/ +/** + * Web Application Prefix Apply For Making Owner Styles + */ +/** + * Blocks Layout Selectors + */ +/***********************************************************************/ +/* Slider */ +.slick-slider { + position: relative; + display: block; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -ms-touch-action: pan-y; + touch-action: pan-y; + -webkit-tap-highlight-color: transparent; } + +.slick-list { + position: relative; + overflow: hidden; + display: block; + padding: 0; + margin-left: -15px; + margin-right: -15px; } + .slick-list:focus { + outline: none; } + .slick-list.dragging { + cursor: pointer; + cursor: hand; } + +.slick-slider .slick-track, +.slick-slider .slick-list { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + -ms-transform: translate3d(0, 0, 0); + -o-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); } + +.slick-track { + position: relative; + left: 0; + top: 0; + display: block; } + .slick-track:before, .slick-track:after { + content: ""; + display: table; } + .slick-track:after { + clear: both; } + .slick-loading .slick-track { + visibility: hidden; } + +.slick-slide { + outline: 0; + float: left; + height: 100%; + min-height: 1px; + padding-left: 15px; + padding-right: 15px; + display: none; } + [dir="rtl"] .slick-slide { + float: right; } + .slick-slide.slick-loading img { + display: none; } + .slick-slide.dragging img { + pointer-events: none; } + .slick-initialized .slick-slide { + display: block; } + .slick-loading .slick-slide { + visibility: hidden; } + .slick-vertical .slick-slide { + display: block; + height: auto; } + +.slick-arrow.slick-hidden { + display: none; } + +.slick-row.hide-loading .timeline-wrapper { + display: none; } + +.slick-loading { + display: none; } + +.slick-loaded { + display: block; } + +/*# sourceMappingURL=slick.css.map */ diff --git a/modules/appagebuilder/css/styles.css b/modules/appagebuilder/css/styles.css new file mode 100644 index 00000000..9857d66c --- /dev/null +++ b/modules/appagebuilder/css/styles.css @@ -0,0 +1,2623 @@ +/** +* Transition-timing-function property@mixin +*/ +/*background RGBA +============================================*/ +/****/ +/* RIGHT TO LEFT */ +.tabs-below .nav-tabs, +.tabs-right .nav-tabs, +.tabs-left .nav-tabs { + border-bottom: 0; +} + +.tab-content .tab-pane, +.pill-content .pill-pane { + display: none; +} + +.tab-content .active, +.pill-content .active { + display: block; +} + +.tabs-below .nav-tabs { + border-top: 1px solid #ddd; +} + +.tabs-below .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} + +.tabs-below .nav-tabs > li > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.tabs-below .nav-tabs > li > a:hover, +.tabs-below .nav-tabs > li > a:focus { + border-top-color: #ddd; + border-bottom-color: transparent; +} + +.tabs-below .nav-tabs > .active > a, +.tabs-below .nav-tabs > .active > a:hover, +.tabs-below .nav-tabs > .active > a:focus { + border-color: transparent #ddd #ddd #ddd; +} + +.tabs-left .nav-tabs > li, +.tabs-right .nav-tabs > li { + float: none; +} + +.tabs-left .nav-tabs > li > a, +.tabs-right .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} + +.tabs-left .nav-tabs { + float: left; + border-right: 1px solid #ddd; +} + +.tabs-left .nav-tabs > li > a { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.tabs-left .nav-tabs > li > a:hover, +.tabs-left .nav-tabs > li > a:focus { + border-color: #eeeeee #dddddd #eeeeee #eeeeee; +} + +.tabs-left .nav-tabs .active > a, +.tabs-left .nav-tabs .active > a:hover, +.tabs-left .nav-tabs .active > a:focus { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #ffffff; +} + +.tabs-right .nav-tabs { + float: right; + border-left: 1px solid #ddd; +} + +.tabs-right .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.tabs-right .nav-tabs > li > a:hover, +.tabs-right .nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #eeeeee #dddddd; +} + +.tabs-right .nav-tabs .active > a, +.tabs-right .nav-tabs .active > a:hover, +.tabs-right .nav-tabs .active > a:focus { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} + +.owl-theme .owl-controls .owl-buttons{ + position: absolute; + top: -78px; + right: 0; +} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + overflow: hidden; + /*width: 100%;*/ +} +.carousel-inner > .item { + display: none; + position: relative; + -webkit-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + max-width: 100%; + height: auto; + line-height: 1; +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-inner:hover{ overflow:inherit} +#index .carousel-inner:hover{overflow: hidden;} +.carousel-control{ + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: 15%; + opacity: 0.5; + filter: alpha(opacity=50); + font-size: 20px; + color: white; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); +} + +.carousel-control.right{ + left: auto; + right: 0; +} +.carousel-control:hover, .carousel-control:focus { + outline: none; + color: white; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; +} +.carousel-control .icon-prev{ + left: 50%; +} +.carousel-control .icon-next { + right: 50%; +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + margin-top: -10px; + margin-left: -10px; + font-family: serif; +} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + margin-left: -30%; + padding-left: 0; + list-style: none; + text-align: center; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + border: 1px solid white; + border-radius: 10px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); +} +.carousel-indicators .active { + margin: 0; + width: 12px; + height: 12px; + background-color: white; +} +.carousel-caption { + position: absolute; + left: 15%; + right: 15%; + bottom: 20px; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: white; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width: 768px) { + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + margin-left: -15px; + font-size: 30px; + } + .carousel-caption { + left: 20%; + right: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} +.carousel-control { + z-index: 99; + top: -50px ; + right: 20px; + position: absolute; + background: #eeeeee; + font-size: 14px; + width: 30px; + height: 30px; + left: inherit; + line-height: 29px; + border-radius: 100%; + color: #3a3d41; + text-shadow: none; + opacity: 1; +} +.carousel-control:hover, .carousel-control:focus{ + color:#000; +} +.carousel-control.left { + right: 32px; +} +.carousel-control.right { + right: 0px; +} + +.custom_slide a:first-child img { + margin-bottom: 20px; +} +/* Eff */ +.view-fifth { + position: relative; + overflow: hidden; +} +.view-fifth .mask { + position: absolute; + background-color: #333333; + top: 0; + height: 100%; + color: #fff; + width: 100%; + text-align: center; + -webkit-transform: translateX(-100%); + -moz-transform: translateX(-100%); + -o-transform: translateX(-100%); + -ms-transform: translateX(-100%); + transform: translateX(-100%); + -ms-filter: "progid: DXImageTransform.Microsoft.Alpha(Opacity=100)"; + filter: alpha(opacity=100); + opacity: 1; + -webkit-transition: all 0.5s ease-in-out; + -moz-transition: all 0.5s ease-in-out; + -o-transition: all 0.5s ease-in-out; + -ms-transition: all 0.5s ease-in-out; + transition: all 0.5s ease-in-out; +} +.view-fifth .mask > div { + padding: 0 10px; +} +.view a.info { + background: #000; + border-radius: 4px; + color: #fff; + display: inline-block; + padding: 4px 15px; + text-decoration: none; + text-transform: uppercase; + margin-top: 10px; +} +.view a.info:hover { + background-color: #57AFDA; +} +.view-fifth img { + -webkit-transition: all 0.5s ease-in-out; + -moz-transition: all 0.5s ease-in-out; + -o-transition: all 0.5s ease-in-out; + -ms-transition: all 0.5s ease-in-out; + transition: all 0.5s ease-in-out; +} +.view-fifth:hover img { + -webkit-transform: translateX(100%); + -moz-transform: translateX(100%); + -o-transform: translateX(100%); + -ms-transform: translateX(100%); + transform: translateX(100%); +} +.view-fifth:hover .mask { + -webkit-transform: translateX(0); + -moz-transform: translateX(0); + -o-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); +} +.block_content .contact-us li { + line-height: 35px; +} +.block_content .contact-us li em { + background: #4A4A4A; + border-radius: 2px; + color: #D4D4D4; + display: inline-block; + font-size: 18px; + margin-right: 10px; + text-align: center; + width: 28px; + padding: 3px 0 3px 4px; +} +.rtl .block_content .contact-us li em { + margin-left: 10px; + margin-right: inherit; +} +.rtl .block_content .contact-us li em { + padding: 3px 4px 3px 0; +} +.block_content .contact-us li:hover em { + background-color: #434a54; + color: white; +} +.block .nav-pills > li.active > a { + position: relative; +} +.block .nav-pills > li.active > a:before { + content: "\f0d7"; + position: absolute; + bottom: -7px; + height: 10px; + line-height: 10px; + right: 50%; + margin-right: -4px; + font-family: "FontAwesome"; + color: #428bca; + font-size: 19px; + z-index: 9; +} +.block .panel-group { + margin-bottom: 0; +} +.effect { + margin-bottom: 10px; +} +.widget-tabs li { + padding: 5px 8px; + border: 1px solid transparent; + text-transform: uppercase; +} +.widget-tabs li.active { + border: 1px solid #aaa; +} +.widget-tabs li.active a { + color: #333; +} +.widget-tabs li a { + color: #999; +} + +/** +* Start for module ap_gmap +*/ +.gmap { +} +div[id^="google-maps"] { + position: relative; +} +div[id^="gmap-stores-list"] { + overflow: auto!important; +} +div[id^="gmap-stores-list"] > ul { + margin: 30px; +} +.display-list-store { + background-color: #6cabd5; + float: left; +} +.gmap-stores-content, .gmap-content { + display: inline-block; + margin: 0; + padding: 0; + position: relative; +} +.not-display-list-store .gmap-stores-content, .not-display-list-store .gmap-content { + width: 100%; +} +.gmap-cover { + width: 100%; +} + +.item-gmap-store { + cursor:pointer; + border-bottom: 1px solid rgba(0, 0, 0, 0.2); + padding: 10px 15px; + text-transform: uppercase; + color: #fff; + -webkit-transition: all 0.1s ease-in-out; + -moz-transition: all 0.1s ease-in-out; + -o-transition: all 0.1s ease-in-out; + -ms-transition: all 0.1s ease-in-out; + transition: all 0.1s ease-in-out; +} +.item-gmap-store:hover { + color: #000; + border-bottom: 1px solid rgba(0, 0, 0, 0.4); + -webkit-transition: all 0.3s ease-in-out; + -moz-transition: all 0.3s ease-in-out; + -o-transition: all 0.3s ease-in-out; + -ms-transition: all 0.3s ease-in-out; + transition: all 0.3s ease-in-out; +} +.item-gmap-store .icon-map-marker { + margin-right: 6px; + font-size: 120%; +} +.item-gmap-store text { + font-size: 85%; +} + +/** +* End for module ap_gmap +*/ +/** +* Start for module ap_product_list +*/ +.box-show-more { + border-bottom: 1px solid #d6d4d4; + padding-bottom: 5px; + text-align: center; + display: none; +} +.box-show-more.open { + display: block; +} +/** +* End for module ap_product_list +*/ + +/** +* Start for module ap_image +*/ +.ap_image .has-animation { + opacity: 0; + -moz-opacity: 0; + -khtml-opacity: 0; + filter: alpha(opacity=0); + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +} +.ap_image .has-animation.animated { + opacity: 1; + -moz-opacity: 1; + -khtml-opacity: 1; + filter: alpha(opacity=100); + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +} + +/** +* End for module ap_image +*/ +/** +* End for module ApFullSlider +*/ + #block_top_menu{ + padding-bottom: 10px!important; + } + .full-slider .carousel-inner { + position: relative; + overflow: hidden; + width: 100%; + height: 100%; + background: transparent; +} + .full-slider .carousel-inner .item { + /*padding: 15px 20px;*/ + width: 100%; + height: 100%; +} + .full-slider .carousel-control{ + top: 50%; + width: 40px; + height: 40px; + background: rgba(18, 18, 18, 0.52); + } +.full-slider .content-slider{ + position: absolute; + top: 35%; + color: #fff; + left: 0; + right: 0; + text-align: center; +} +.full-slider .content-slider h3{ + font-size: 60px; + text-transform: uppercase; + font-weight: 600; +} +.full-slider .content-slider p{ + margin-top: 30px; + background: #c70005; + padding: 10px 20px; + display: inline-block; + text-transform: uppercase; + font-size: 14px; + +} + +.full-slider .carousel-control.left{ + left: 10px; +} +.full-slider .carousel-control.right{ + right: 10px; +} +.full-slider .carousel-control .glyphicon{ + color: #B0B0B0; +} +.full-slider .right.carousel-control .glyphicon{ + right: 4px; +} + +.carousel-control .glyphicon { + top: 18px; + color: #fff; +} +.right.carousel-control .glyphicon { + + right: 0; + +} +/** +* End for module ApFullSlider +*/ +/** +* Start for module ApFullSlider +*/ +.cover-live-edit { + width: 100%; + border-top: 1px dashed #bdbdbd; +} +.cover-live-edit .link-to-back-end { + text-decoration: none; + color: #fff; + z-index: 9999; + background-color: rgba(204, 153, 0, 0.5); + box-shadow: 0 0 5px #bdbdbd; + padding: 5px; + position: relative; + -webkit-transition: all 0.4s ease-in-out; + -moz-transition: all 0.4s ease-in-out; + -o-transition: all 0.4s ease-in-out; + -ms-transition: all 0.4s ease-in-out; + transition: all 0.4s ease-in-out; +} +.cover-live-edit .link-to-back-end:hover { + background-color: #00e676; + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + -ms-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} +.ap-cover-hook { + border: 1px dashed #bdbdbd; + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + -ms-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} +.ap-cover-hook:hover { + border: 1px dashed #333; + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + -ms-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} +/** +* End for module ApFullSlider +*/ +.manufacturers_block { + clear: both!important; +} +.embed-responsive +{ position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; } +.embed-responsive iframe, .embed-responsive object, .embed-responsive embed +{ position: absolute; top: 0; left: 0; width: 100%; height: 100%; } +.lnk-hook { + background-color: #e5e5e5; + left: 0; + padding: 2px 5px; + position: absolute; + top: 0; + z-index: 1; +} +.block { + margin-bottom: 20px; + clear: both!important; +} +/***************************************************** + Css top column +*****************************************************/ +#top_column .wrapper { + color: #fff; + text-align: center; + line-height: 22px; +} +/* +#top_column .wrapper{ + padding-top: 50px; + padding-bottom: 52px; + margin-bottom: 20px; +} +*/ +#top_column .wrapper .icon_holder{ + padding-bottom: 15px; +} +#top_column .wrapper .title_top_column{ + padding-bottom: 12px; +} + +#top_column .wrapper .title_top_column a{ + text-transform: uppercase; + color: #fff; + font-size: 18px; +} +#top_column .wrapper .ApImage{ + text-align: center; + padding: 30px 0px; +} +#top_column .wrapper .ApImage img{ + margin-bottom: 20px; +} +.ApColumn .normal{ + border: 1px solid #ccc; + padding: 15px 20px 15px 20px; + cursor: pointer; + margin-bottom: 5px; + width: 62px; + text-align: center; +} +.ApColumn .normal:hover { + color: red; +} + +.block-carousel-container .text-centered { + padding-top: 20px; +} +#top_column .wrapper .banner-home-3{ + padding: 0px; +} +/******************************************************************* + Css Manufacturers +******************************************************************/ +.manufacturers_block img { + padding: 20px; + margin-bottom: 10px; + margin: 10px; + +} +.manufacturers_block img:hover{ + box-shadow: 0px 0px 6px #ccc; + border-radius: 5px; +} +.widget-category_image .cover-img { + float: left; + padding-right: 20px; +} +.widget-category_image .cover-img img { + width: 100px; + height: 100px; +} + +/******************************************************* + Css Images of category +********************************************************/ +#image_single .ApImage :hover{ + transform: scale(1)!important; +} +.widget-category_image .cate_content:hover label{ + color: #3276b1; + cursor: pointer; +} +.widget-images .image-item img { + border: 1px solid #ddd; + padding: 3px; +} + +/******************************************************* +home page footer +********************************************************/ +.footer-container{ + margin-top: 30px; +} +#home_page{ + position: relative; +} +#home_page:before{ + padding: 0 2000px; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + position: absolute; + content: ""; + width: 100%; + height: 100%; + background-color: #f2f2f2; + z-index: 0; + display: inline-block !important; + top: 0; + left: -2000px; +} +#page{ + overflow:hidden; +} +#home_page .title_home_page{ + padding-top: 20px; + color: #000; + text-transform: uppercase; + font-weight: 800; +} +#home_page .ApImage{ + border: 1px solid #dbdbdb; + padding: 4px; +} +#home_page .ApHtml{ + color: #000; + border-bottom: 1px solid #ddd; + position: relative; + padding: 30px 0px; + margin-top: 20px; +} + +/********************************************************* +Css Title +*********************************************************/ +.title_block { + background: transparent!important; + border-top: none!important; + padding: 20px 0px; + font-weight: 800; + text-transform: uppercase; + color: #000; +} + + + +/******************************************************* + + Css Alert + +********************************************************/ + +.alert.alert-success:before { + float:left; +} +.alert.alert-success:before { + font-family: 'Material Icons'; + content: "check"; + font-size: 20px; + vertical-align: -2px; + padding-right: 7px; + float: left; +} +.alert.alert-warning { + text-shadow: 1px 1px rgba(0, 0, 0, 0.1); +} +.alert.alert-warning:before { + font-family: 'Material Icons'; + content: "warning"; + font-size: 20px; + vertical-align: -2px; + padding-right: 7px; + float: left; +} +.alert.alert-info { + text-shadow: 1px 1px rgba(0, 0, 0, 0.1); +} +.alert.alert-info:before { + font-family: 'Material Icons'; + content: "info"; + font-size: 16px; + vertical-align: -2px; + padding-right: 7px; + float: left; +} +.alert.alert-danger { + text-shadow: 1px 1px rgba(0, 0, 0, 0.1); +} +.alert.alert-danger:before { + font-family: 'Material Icons'; + content: "close"; + font-size: 16px; + vertical-align: -2px; + padding-right: 7px; + float: left; +} +/******************************************************* +Css block links +********************************************************/ +#block_links .ApBlockLink a { + display: block; + line-height: 24px; +} +#block_links .ApBlockLink{ + padding-bottom: 20px; +} +#block_links{ + background: #f7f7f9; + padding: 0px; + margin: 0px; +} +#block_links .title-demo{ + border: none!important; + color: #428bca!important; +} + +#block_links .title_links{ + text-transform: uppercase; + padding-bottom: 10px; + padding-top: 10px; +} +/******************************************************* + Css Button +********************************************************/ +.ApRawHtml .title_button { + color: #3276b1; + text-transform: none; + font-weight: bold; + padding-bottom: 10px; +} + +/******************************************************* +title block +********************************************************/ +#center_column .ApRow .ApColumn .ApRawHtml .title-demo { + font-size: 20px; + border-bottom: 1px solid #eee; + padding-bottom: 10px; + padding-top: 10px; + color: #333; + position: relative; + border-radius: 4px; + font-weight: 800; + text-transform: uppercase; +} +.block .title_block, .block h4{ + padding: 0px 5px 17px 0px; + margin-bottom: 0px; +} + +/******************************************************* +images +********************************************************/ +#image_single .ApImage{ + border: 1px solid #eee; + padding: 8px; +} +/******************************************************* +tabs +********************************************************/ +.tabs-top .tab-content{ + border: 1px solid #ddd; + margin-top: -1px!important; + padding: 10px 0px 0px 0px; +} + + +/* ********************************************************* +animation +******************************************************* */ +.effect a { + position: relative; + display: inline-block; + max-width: 100%; +} +.effect a:before { + position: absolute; + content: ""; + top: 0; + left: 0; + width: 0; + height: 0; + margin: auto; + background-color: rgba(255, 255, 255, 0.1); + -webkit-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; +} +.effect a:after { + content: ""; + position: absolute; + right: 0; + bottom: 0; + width: 0; + height: 0; + background-color: rgba(255, 255, 255, 0.1); + -webkit-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; +} +.effect a:hover:before, .effect a:hover:after { + width: 100%; + height: 100%; +} +/* ********************************************************* + Css Accordion +******************************************************* */ +.ap-accordion .panel-group .panel-default .panel-title{ + border-top: 1px solid transparent; + padding: 0px; + margin-bottom: 0px; + font-size: 13px; + +} +.ap-accordion .panel-default{ + border: 1px solid transparent; + box-shadow: none; +} +.ap-accordion .panel-default .panel-title{ + text-transform: none; + background: #f0f0f0; + position: relative; + font-weight: normal; +} +.ap-accordion .panel-default .panel-title .collapsed{ + display:block; + font-weight: normal; +} +.ap-accordion .panel-default .panel-title a:before{ + background: none; + content: "arrow_drop_up"; + cursor: pointer; + display: block; + font-family: 'Material Icons'; + font-size: 25px; + left: auto; + position: absolute; + right: 0px; + top: 0px; + width: auto; + +} +.ap-accordion .panel-default .panel-title .collapsed:before{ + background: none; + content: "arrow_drop_down"; + cursor: pointer; + display: block; + font-family: 'Material Icons'; + font-size: 25px; + left: auto; + position: absolute; + right: 0px; + top: 0px; + width: auto; + +} +.ap-accordion .panel-default .panel-heading{ + background: #f0f0f0; + border: 1px solid #f0f0f0; +} +.ap-accordion .panel-default > .panel-heading + .panel-collapse .panel-body{ + border: 1px solid #f0f0f0; +} +.ap-accordion .in{ + display: block; +} +/* ********************************************************* + Css Lastest blogs +******************************************************* */ +.latest-blogs .left-block .blog-image-container img :hover{ + background: rgba(255,255,255,0.6); + opacity: 0.6; + transition: all 250ms ease-in-out 0s; + top: 0; + left:0; + width: 100%; + height: 100%; + -webkit-transition: all 250ms ease-in-out 0s; + position: absolute; + z-index: 9999; +} + +.latest-blogs .left-block .blog-image-container{ + float:left; + overflow:hidden; + position: relative; + padding-right: 10px; + margin-bottom: 15px; +} +.latest-blogs .right-block{ + text-align:left; +} +.latest-blogs .right-block .blog-title{ + text-transform: uppercase; + font-size: 14px; + line-height: 20px; +} +.latest-blogs .right-block .blog-title a{ + color: #000; +} +.latest-blogs .right-block .blog-desc{ + padding-top: 15px; + text-align: justify; +} + .latest-blogs{ + border-bottom: 1px solid #eee; + margin-bottom: 0px; + padding-bottom: 40px; +} +.latest-blogs .created ,.cat ,.author ,.nbcomment ,.hits{ + color: #999999; +} + +/* ********************************************************* + + Css block carousel + +******************************************************* */ +.Clients_say .title_block{ + padding-top: 65px; + color: #fff; +} +.block_carousel .owl-carousel{ + padding: 48px 0px; +} +.block_carousel .block-carousel-image-container { + position: relative; + min-height: 135px; +} +.block_carousel .block-carousel-image-container img{ + position: absolute; + bottom: 0; +} +.block_carousel .block-carousel-image-container .descript{ + color: #bcbbbd; +} +.block_carousel .owl-carousel .content_name{ + position: absolute; + left: 72px; + bottom: -100px; + color: #fff; +} +.block_carousel .owl-carousel h5{ + font-weight: bold; +} + +.block_carousel .owl-theme .owl-controls{ + padding-top: 20px; +} + +/********************************************************* +Block carousel 2 + +**********************************************************/ +.block_carousel_2 .owl-carousel .content_name{ + bottom: 0; + color:#cdcdcd; +} +.block_carousel_2 .owl-carousel .content_name h5{ + color: #000; +} +.block_carousel_2 .owl-carousel .content-slider{ + color: #858585; +} +.block_carousel_2 .owl-carousel{ + padding: 20px 0; +} +/* +.block_carousel_2 .owl-theme .owl-controls{ + position: absolute; + top:-90px; + right:0; +} +*/ +.block_carousel_1 .title-demo{ + color: #fff!important; + border: 1px solid transparent!important; + padding: 25px 0px 0px 30px!important; +} +/* ********************************************************* + +custome bottom home page 1 + +******************************************************* */ +.Custome_bottom{ + position: relative; + padding: 40px 0px; +} +.Custome_bottom:before { +padding: 0 2000px; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + position: absolute; + content: ""; + width: 100%; + height: 100%; + background: #eeeeee; + z-index: 0; + display: inline-block !important; + top: 0; + left: -2000px; +} + +.Custome_bottom .icon_custom { + background: #fafafa; + border: 1px solid #ddd; + text-align: center; + padding: 20px; + height: 137px; + color: #202020; + text-transform: uppercase; + margin-bottom: 37px; + box-shadow: 0px 0px 6px #ccc; +} +.Custome_bottom .icon_custom:hover{ + box-shadow: 6px 10px 6px 0px #ccc; + height: 137px; + padding: 20px; + background: #d02c2c; + color:#fff; + cursor: pointer; +} +.Custome_bottom .icon_custom .icon-name{ + font-size: 24px; + line-height: 47px; +} + +/* ******************************************************* + + Css Product item + +*********************************************************/ + + +.ApProductCarousel .products_block .ajax_block_product .product-container{ + position: relative; + overflow: hidden; + box-shadow: 0px 0px 5px 0px transparent; + -webkit-box-shadow: 0px 0px 5px 0px transparent; +} +.ApProductCarousel .products_block .ajax_block_product:hover .product-container{ + box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.16); + -webkit-box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.16); +} +.ApProductCarousel .product-container:hover .functional-buttons{ + opacity: 1; + top: 60%; + visibility: visible; +} +.ApProductCarousel .product-container .functional-buttons{ + padding: 5px 0px 10px 0px; + font-size: 16px; + line-height: 31px; + position: absolute; + transition: all 550ms ease 0s; + -webkit-transition: all 550ms ease 0s; + top: 84%; + opacity: 0; + visibility: hidden; + left:0; + box-shadow: 0 5px 4px -1px transparent; + -webkit-box-shadow: 0 5px 4px -1px transparent; + text-align: center; + right:0; +} +.ApProductCarousel .product-container .functional-buttons .wishlist,.compare{ + width: 54px; + height: 22px; + line-height: 38px; + position: relative; +} +.ApProductCarousel .product-container .functional-buttons .wishlist a:before{ + position: absolute; + content: "\f08a"; + font-family: FontAwesome; + + font-size: 16px +} +.ApProductCarousel .product-container .functional-buttons .wishlist a{ + font-size: 0px; + width: 59px; + height: 22px; +} +.ApProductCarousel .product-container .functional-buttons div{ + display: inline-block; + text-align: center; +} +.ApProductCarousel .product-container .functional-buttons .cart .ajax_add_to_cart_button{ + text-transform: uppercase; + background: #f0f0f0; + border: 1px solid transparent; +} +.ApProductCarousel .owl-item .product-container{ + position: relative; + margin: 0 0 5px; +} +.ApProductCarousel .ajax_block_product:hover .product-container{ + box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.16); + -webkit-box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.16); + min-height: 340px; +} +.ApProductCarousel .ajax_block_product .product-container{ + position: relative; + margin: 0 0 5px; +} +.ApProductCarousel .owl-item:hover .product-container{ + box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.16); + -webkit-box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.16); + min-height: 340px; +} +.ApProductCarousel .product-container .functional-buttons .cart .ajax_add_to_cart_button i{ + padding-right: 4px; +} +.ApProductCarousel .product-container .right-block .product-name{ + font-family:"museo_sans300", sans-serif; + font-size: 14px; + text-align: center; + display: inline-block; + width: 100%; +} +.ApProductCarousel .product-container .comments_note { + display: block; + padding-right: 10px; +} + +.ApProductCarousel .product-container.tabs-top .tab-content{ + border: none!important; +} +.producttabs ul.product_list.grid > li.hovered .product-container.left-block{ + background: #fff; + opacity: 0.5; + +} + .ApProductCarousel .product-container .content_price{ + float:left; + display: block; + padding-left: 10px; +} +.ApProductCarousel .product-container .button.ajax_add_to_cart_button span{ + background: #f0f0f0; + border: none; + color: #424242; + text-shadow: none; + font-size: 12px; + text-transform: uppercase; +} +.ApProductCarousel .product-container .button.ajax_add_to_cart_button:hover{ + border-color: transparent; +} +.ApProductCarousel .product-container .button.ajax_add_to_cart_button{ + border: none; +} +.ApProductCarousel .product-container .button.ajax_add_to_cart_button .icon-shopping-cart:before{ + padding-right: 4px; +} +.ApProductCarousel .product-container .left-block{ + position: relative; +} +.ApProductCarousel .old-price.product-price{ + font-size: 13px; +} +.ApProductCarousel .product-container .left-block .quick-view{ + position: absolute; + top: 50%; + text-align: center; + left: 0; + right: 0; + opacity: 0; +} +.ApProductCarousel .product-container .left-block:hover .quick-view{ + opacity: 1; + transition: all 250ms ease-in-out 0s; +} +.ApProductCarousel .product-container .left-block .quick-view span{ + background: #000; + color: #fff; + padding: 10px 20px; +} +.ApProductCarousel .product-container .price.product-price{ + font-family: "Gotham-Bold", sans-serif!important; + font-weight: 800; + font-size: 15px; + color: #8f1f1f; +} +.ApProductCarousel .product-container .product-image-container{ + border: 1px solid transparent; + padding: 0px; + position: relative; + background: #e3e3e3; +} +.ApProductCarousel .product-container .product-image-container:hover img{ + background: rgba(255,255,255,0.6); + opacity: 1; + transition: all 250ms ease-in-out 0s; + top: 0; + left:0; + -webkit-transition: all 250ms ease-in-out 0s; + +} + +.producttabs .tabs-top .tab-content{ + border: 1px solid transparent; +} +ul.product_list.grid > li .product-container h5{ + min-height: 38px; + display: inline-block; + width: 100%; +} + +.ApProductCarousel .product-container .comments_note .nb-comments{ + display: none; +} +.ApProductCarousel .product-container .comments_note .star_content{ + float: right; + margin: 8px 0px 12px 0px!important; +} +.ApProductCarousel .product-container .right-block{ + padding: 8px 0px 6px 0px; + min-height: 140px; + position: relative; +} +.ApProductCarousel .product-container .tab-pane .block{ + margin-bottom: 0px; +} +.ApProductCarousel .product-container .price-percent-reduction{ + font-size: 13px; +} +.producttabs .tabs-top .tab-content{ + border: 1px solid transparent; +} +.star{ + font-size: 12px; +} +/********************************************************** +Css title nav-tabs +************************************************************/ +.nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus{ + border: 1px solid transparent; + background: #eeeeee; + border-bottom: 2px solid #c0c700; + color: #000; +} + .nav-tabs { + border-bottom: 1px solid transparent; + padding-bottom: 20px; +} + .nav-tabs > li > a{ + font-family: "Gotham-Bold", sans-serif; + font-weight: 800; + color: #767676; + border-bottom: 2px solid transparent; + font-size: 14px; + text-transform: uppercase; +} + +/****************************************************** +Css New and Sale + +*****************************************************/ +.new-label, +.sale-label{ + border-radius: 100%; + width: 50px; + height: 50px; + left: 10px; + top: 10px; + transform: none; + padding: 20px 0 7px; + text-shadow: none; +} + .sale-label{ + right: 10px; +} +.sale-label:before{ + display: none; +} +.sale-label:after{ + display: none; +} +.new-label:before{ + display: none; +} +.new-label:after{ + display: none; +} + + +.bg-fullwidth{position: relative;} +.bg-fullwidth:before{ + padding: 0px 1000px; + margin-left: -1000px; + width: 100%; + overflow: hidden; + box-sizing: content-box; + position:absolute; + height:100%; + display:inherit; + top: 0; +} +.leo-more-info { + position: absolute; + z-index: 4000; + top: 0; + left: 0; + min-height:380px; + display: none; + /*overflow: hidden;*/ + float: left; + text-align: left; + padding: 5px 5px 10px 5px; + border-radius: 8px; + background-color: #fff; + box-shadow: 0 0 46px 12px rgba(0, 0, 0, 0.1); +} +.leo-more-over{ + position: relative; + z-index: 0; +} +.leo-more-image{ + opacity: 0; + left:0; + top:0; + position: absolute; +} +.leo-preview { + position: absolute; + z-index: 4000; + top: 0; + left: 0; + display: none; + /*overflow: hidden;*/ + float: left; + text-align: left; + padding: 5px 5px 10px 5px; + border-radius: 8px; + background-color: #fff; + box-shadow: 0 0 46px 12px rgba(0, 0, 0, 0.1); +} + +.leo-preview .col-1 { + width: 75px; +} +.leo-preview .col-2 { + width: 260px; +} +.leo-preview .big_image { + text-align: center; +} +.leo-preview .big_image { + padding-bottom: 5px; +} +.leo-preview .wrapper-hover { + padding: 3px 9px 12px; +} +.leo-preview li{ + list-style-type: none; +} +.thumbs_list { + float: left; + margin-left: 13px; + overflow: hidden; + width: 85px; + height: 256px; +} +.thumbs_list li { + cursor: pointer; + float: left; + height: 85px; + width: 85px; +} +.thumbs_list li a { + border: 1px solid #EDEDED !important; + display: block; + margin: 0 1px; + text-align: center; +} +.thumbs_list ul.thumbs_list_frame { + list-style-type: none; + padding-left: 0; +} +.view_scroll_spacer{ + +} +.view_scroll_left{ + +} + +/* Effect */ + +.product-additional { + left: 0; + position: absolute; + bottom: -500px; + width: 100%; + transition: all ease 0.6s; + -moz-transition: all ease 0.6s; + -webkit-transition: all ease 0.6s; + -ms-transition: all ease 0.6s; + -o-transition: all ease 0.6s; + +} +.product-container .center_block:hover .product-additional{ + bottom: 0; + transition: all ease 0.6s; + -moz-transition: all ease 0.6s; + -webkit-transition: all ease 0.6s; + -ms-transition: all ease 0.6s; + -o-transition: all ease 0.6s; +} + +/********************************************** +Homepage2 +***********************************************/ +.custom_home_2{ + background: #f0f0f0; + padding: 30px 10px; + line-height: 23px; + text-align:center; +} +.custom_home_2 .title_custom{ + color: #424242; + font-family: "Gotham-Bold", sans-serif; + font-weight: 600; + text-transform: uppercase; + font-size: 15px; + padding-bottom: 10px; +} +.custom_home_2 .icon-name{ + font-size: 30px; + padding: 20px 0px; +} +.custom_home_2 .description{ + color: #767676; +} + + +/************************************************************* +Module Newletter +*************************************************************/ + +.content_bottom_home2 #newsletter_block_left .form-group { + margin-bottom: 0; +} +.content_bottom_home2 #newsletter_block_left .form-group .form-control { + max-width: 222px; + display: inline-block; + margin-right: 6px; +} +@media (min-width: 768px) and (max-width: 1199px) { + .content_bottom_home2 #newsletter_block_left .form-group .form-control { + margin-bottom: 10px; + margin-right: 0; + } +} +.content_bottom_home2 #newsletter_block_left .success_inline, #columns #newsletter_block_left .warning_inline { + text-align: left; + padding: 1px 0 0 0; + margin-bottom: -19px; +} +.content_bottom_home2 #newsletter_block_left .success_inline { + color: #418B19; +} +.content_bottom_home2 #newsletter_block_left .warning_inline { + color: #f13340; +} + +/* block newsletter */ +.content_bottom_home2 #newsletter_block_left { + background: #eeeeee; + text-align: center; + padding: 65px 20px; + letter-spacing: 2px; + margin-top: 18px; +} +.content_bottom_home2 #newsletter_block_left h4 { + background: none; + border: 1px solid transparent; +} +.content_bottom_home2 #newsletter_block_left p { + font-size: 14px; + line-height: 24px; +} +.content_bottom_home2 #newsletter_block_left .button-small { + text-shadow: none; + border: 1px solid transparent; +} +.content_bottom_home2 #newsletter_block_left .button-small span { + background: #222222; + border: 1px solid transparent; + padding: 6px 16px; +} +.content_bottom_home2#newsletter_block_left .form-group { + padding-top: 20px; +} +.content_bottom_home2 #newsletter_block_left .form-group .form-control { + min-width: 296px; + height: 34px; + background: #fff; + border: 1px solid transparent; +} +/******************************************************** + Css Custome Ajax + *******************************************************/ + .product-block .product-additional { + display: inline-block; + width: 100%; + height: 100%; + position: absolute; + top: 0px; + visibility: hidden; + left: 0px; + opacity: 0; + filter: alpha(opacity=0); +} +.product-block:hover .product-additional { + visibility: visible; + -webkit-transition: all 0.5s ease 0s; + transition: all 0.5s ease 0s; + opacity: 1; + filter: alpha(opacity=100); +} +.product-block .image { + position: relative; + overflow: hidden; + text-align: center; + -webkit-border-radius: 0px; + -moz-border-radius: 0px; + -ms-border-radius: 0px; + -o-border-radius: 0px; + border-radius: 0px; + margin: 10px 0; + border: 1px solid #f2f2f2; +} +/******************************************************* +home page +********************************************************/ +#group_page { + padding-top: 40px; +} +#group_page .ApColumn .ApImage { + border: 1px solid #ccc; + box-shadow: 0px 0px 6px #ccc; + padding: 15px; + margin-bottom: 15px; + transition: all 0.3s ease; +} +#group_page .ApColumn .ApImage:hover { + box-shadow: 0px 0px 6px 2px #ccc; + transform: scale(1.02); +} +#group_page .ApColumn .ApRawHtml { + margin-bottom: 40px; + text-transform: uppercase; + font-size: 14px; + color: #000; + font-weight: 600; +} +#group_page .ApColumn .ApRawHtml a{ + color: #000; + font-weight: 600; +} +#group_page .ApColumn .ApRawHtml a:hover{ + color: #1E49CF; +} +.text_description .ApHtml{ + border-bottom: 3px solid #ddd; + padding-bottom: 26px; + color: #000; +} +.text_description { + line-height: 30px; + padding-top: 20px; +} +/******************************************Grid layout**************************************/ +.col-xs-2-4, +.col-xs-4-8, +.col-xs-7-2, +.col-xs-9-6, +.col-sm-2-4, +.col-sm-4-8, +.col-sm-7-2, +.col-sm-9-6, +.col-md-2-4, +.col-md-4-8, +.col-md-7-2, +.col-md-9-6, +.col-lg-2-4, +.col-lg-4-8, +.col-lg-7-2, +.col-lg-9-6 { + position: relative; + min-height: 1px; + padding-left: 15px; + padding-right: 15px; +} +@media (max-width: 480px) { + .col-sp-2-4, .col-sp-4-8, + .col-sp-7-2, .col-sp-9-6 { + float: left; + } + + .hidden-sp { + display: none !important; + } + + .col-sp-1, .col-sp-2, .col-sp-3, .col-sp-4, .col-sp-5, .col-sp-6, .col-sp-7, .col-sp-8, .col-sp-9, .col-sp-10, .col-sp-11, .col-sp-12 { + float: left; + } + + .col-sp-1 { + width: 8.33333%; + } + + .col-sp-2 { + width: 16.66667%; + } + + .col-sp-3 { + width: 25%; + } + + .col-sp-4 { + width: 33.33333%; + } + + .col-sp-5 { + width: 41.66667%; + } + + .col-sp-6 { + width: 50%; + } + + .col-sp-7 { + width: 58.33333%; + } + + .col-sp-8 { + width: 66.66667%; + } + + .col-sp-9 { + width: 75%; + } + + .col-sp-10 { + width: 83.33333%; + } + + .col-sp-11 { + width: 91.66667%; + } + + .col-sp-12 { + width: 100%; + } + + .col-sp-2-4 { + width: 20%; + } + + .col-sp-7-2 { + width: 60%; + } + + .col-sp-4-8 { + width: 40%; + } + + .col-sp-9-6 { + width: 80%; + } +} +@media (max-width: 768px) and (min-width: 481px) { + .col-xs-2-4, .col-xs-4-8, + .col-xs-7-2, .col-xs-9-6 { + float: left; + } + + .col-xs-2-4 { + width: 20%; + } + + .col-xs-4-8 { + width: 40%; + } + + .col-xs-7-2 { + width: 60%; + } + + .col-xs-9-6 { + width: 80%; + } +} +@media (min-width: 768px) { + .col-sm-2-4, .col-sm-4-8, + .col-sm-7-2, .col-sm-9-6 { + float: left; + } + + .col-sm-2-4 { + width: 20%; + } + + .col-sm-4-8 { + width: 40%; + } + + .col-sm-7-2 { + width: 60%; + } + + .col-sm-9-6 { + width: 80%; + } +} +@media (min-width: 992px) { + .col-md-2-4, .col-md-4-8, + .col-md-7-2, .col-md-9-6 { + float: left; + } + + .col-md-2-4 { + width: 20%; + } + + .col-md-4-8 { + width: 40%; + } + + .col-md-7-2 { + width: 60%; + } + + .col-md-9-6 { + width: 80%; + } +} +@media (min-width: 1200px) { + .col-lg-2-4, .col-lg-4-8, + .col-lg-7-2, .col-lg-9-6 { + float: left; + } + + .col-lg-2-4 { + width: 20%; + } + + .col-lg-4-8 { + width: 40%; + } + + .col-lg-7-2 { + width: 60%; + } + + .col-lg-9-6 { + width: 80%; + } +} +.ap-popup{display:none} + +/* DONGND: css for owl loading*/ +.owl-carousel.owl-loading .item +{ + display: none; +} + +.owl-carousel.owl-loading .item.first +{ + display: block; +} + +.owl-carousel.owl-loading::before +{ + animation: 0.5s linear 0s normal none infinite running progress-bar-stripes; + background-color: #fbfbfb; + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent); + background-repeat: repeat; + background-size: 40px 40px; + content: ""; + height: 100%; + overflow: hidden; + position: absolute; + transition: width 0.6s ease 0s; + width: 100%; + z-index: 1; +} +/* Block toggler */ +.block-toggler .title, .footer-container .links .title { + cursor: pointer; } + .block-toggler .title .collapse-icons .remove, .footer-container .links .title .collapse-icons .remove { + display: none; } +.block-toggler .title[aria-expanded="true"] .collapse-icons .add, .footer-container .links .title[aria-expanded="true"] .collapse-icons .add { + display: none; } +.block-toggler .title[aria-expanded="true"] .collapse-icons .remove, .footer-container .links .title[aria-expanded="true"] .collapse-icons .remove { + display: block; } +.block-toggler .navbar-toggler, .footer-container .links .navbar-toggler { + display: block; + padding: 0; + margin-top: 0.3125rem; + width: 1.25rem; + height: 1.25rem; } +.block-toggler.ApBlockLink ul li, .footer-container .links.ApBlockLink ul li { + margin-bottom: 1.25rem; } +@media (min-width: 768px) { + .block-toggler.accordion_small_screen .collapse-icons, .footer-container .links.accordion_small_screen .collapse-icons { + display: none; } } +.block-toggler.accordion_small_screen .collapse, .footer-container .links.accordion_small_screen .collapse { + display: block; } + @media (min-width: 768px) { + .block-toggler.accordion_small_screen .collapse, .footer-container .links.accordion_small_screen .collapse { + height: 100% !important; } } + @media (max-width: 767px) { + .block-toggler.accordion_small_screen .collapse, .footer-container .links.accordion_small_screen .collapse { + display: none; } + .block-toggler.accordion_small_screen .collapse.in, .footer-container .links.accordion_small_screen .collapse.in { + display: block; } } + + + +/* Style for multi product layout */ +.product-thumb-images { + display: none; +} + +.product-thumb-images .thumb { + max-width: 100%; + cursor: pointer; +} + +.product-thumb-images .thumb.selected, +.product-thumb-images .thumb:hover { + border: 1px solid #414141; +} + +.product-detail .arrows-product-fake { + display: none; +} + +.product-detail .arrows-product-fake .slick-arrow { + width: 40px; + height: 40px; + line-height: 40px; + text-align: center; + color: #000000; + z-index: 999; + background: rgba(255, 255, 255, 0.8); + border-radius: 50%; +} + +.product-detail .arrows-product-fake .slick-arrow:hover { + color: #FFFFFF; + background: #3387f2; +} + +.product-detail .arrows-product-fake .slick-arrow.slick-next { + right: -20px; +} + +.product-detail .arrows-product-fake .slick-arrow.slick-prev { + left: -20px; +} + +.product-detail.product-thumbs-bottom .product-thumb-images { + padding-left: 20px; + padding-right: 20px; +} + +.product-detail.product-thumbs-bottom .product-thumb-images .slick-list { + margin-left: -5px; + margin-right: -5px; +} + +.product-detail.product-thumbs-bottom .product-thumb-images .slick-list .slick-slide { + padding-right: 5px; + padding-left: 5px; +} + +.product-detail.product-thumbs-bottom .product-thumb-images .slick-arrow.slick-next { + right: -5px; +} + +.product-detail.product-thumbs-bottom .product-thumb-images .slick-arrow.slick-prev { + left: -5px; +} + +.product-detail.product-thumbs-left .images-container, +.product-detail.product-thumbs-right .images-container { + position: relative; +} + +.product-detail.product-thumbs-left .images-container .product-cover .product-flags, +.product-detail.product-thumbs-right .images-container .product-cover .product-flags { + left: 10px; +} + +.rtl .product-detail.product-thumbs-left .images-container .product-cover .product-flags, +.rtl .product-detail.product-thumbs-right .images-container .product-cover .product-flags { + right: 10px; + left: auto; +} + +.product-detail.product-thumbs-left .images-container .product-thumb-images, +.product-detail.product-thumbs-right .images-container .product-thumb-images { + position: absolute; + top: 20px; + z-index: 9; + width: 80px; +} + +.product-detail.product-thumbs-left .product-thumb-images .slick-list, +.product-detail.product-thumbs-right .product-thumb-images .slick-list { + margin-top: -5px; + margin-bottom: -5px; + margin-left: 0px; + margin-right: 0px; +} + +.product-detail.product-thumbs-left .product-thumb-images .slick-list .slick-slide, +.product-detail.product-thumbs-right .product-thumb-images .slick-list .slick-slide { + padding-top: 5px; + padding-bottom: 5px; + padding-right: 0px; + padding-left: 0px; +} + +.product-detail.product-thumbs-left .product-thumb-images .slick-arrow, +.product-detail.product-thumbs-right .product-thumb-images .slick-arrow { + left: 0; + right: 0; + width: 100%; + margin: auto; + color: #FFFFFF; + background: #3387f2; +} + +.product-detail.product-thumbs-left .product-thumb-images .slick-arrow:hover, +.product-detail.product-thumbs-right .product-thumb-images .slick-arrow:hover { + color: #FFFFFF; + background: #000000; +} + +.product-detail.product-thumbs-left .product-thumb-images .slick-arrow.slick-next, +.product-detail.product-thumbs-right .product-thumb-images .slick-arrow.slick-next { + top: -10px; + bottom: auto; +} + +.product-detail.product-thumbs-left .product-thumb-images .slick-arrow.slick-next:before, +.product-detail.product-thumbs-right .product-thumb-images .slick-arrow.slick-next:before { + content: "\f077"; +} + +.product-detail.product-thumbs-left .product-thumb-images .slick-arrow.slick-prev, +.product-detail.product-thumbs-right .product-thumb-images .slick-arrow.slick-prev { + top: auto; + bottom: -30px; +} + +.product-detail.product-thumbs-left .product-thumb-images .slick-arrow.slick-prev:before, +.product-detail.product-thumbs-right .product-thumb-images .slick-arrow.slick-prev:before { + content: "\f078"; +} + +.product-detail.product-thumbs-left .images-container { + position: relative; +} + +.product-detail.product-thumbs-left .images-container .product-cover { + padding-left: 90px; +} + +.rtl .product-detail.product-thumbs-left .images-container .product-cover { + padding-right: 90px; + padding-left: inherit; +} + +.product-detail.product-thumbs-left .images-container .product-cover .product-flags { + right: 10px; +} + +.rtl .product-detail.product-thumbs-left .images-container .product-cover .product-flags { + left: 10px; + right: auto; +} + +.product-detail.product-thumbs-left .images-container .product-thumb-images { + left: 0; +} + +.rtl .product-detail.product-thumbs-left .images-container .product-thumb-images { + right: 0; + left: auto; +} + +.product-detail.product-thumbs-right .images-container { + position: relative; +} + +.product-detail.product-thumbs-right .images-container .product-cover { + padding-right: 90px; +} + +.rtl .product-detail.product-thumbs-right .images-container .product-cover { + padding-left: 90px; + padding-right: inherit; +} + +.product-detail.product-thumbs-right .images-container .product-cover .layer { + left: 20px; + right: auto; +} + +.product-detail.product-thumbs-right .images-container .product-thumb-images { + right: 0; +} + +.rtl .product-detail.product-thumbs-right .images-container .product-thumb-images { + left: 0; + right: auto; +} + +.product-detail.no-thumbs .images-container { + position: relative; +} + +.product-detail.no-thumbs .product-thumb-images .slick-arrows, +.product-detail.no-thumbs .product-thumb-images .slick-list { + display: none; +} + +.product-detail.no-thumbs .arrows-product-fake { + display: block; +} + +.product-detail.product-image-gallery .product-cover { + display: none; +} + +.product-detail.product-image-gallery .product-thumb-images { + display: block; + margin-left: -15px; + margin-right: -15px; +} + +.product-detail.product-image-gallery .product-thumb-images::after { + content: ""; + display: table; + clear: both; +} + +.product-detail.product-image-gallery .product-thumb-images .thumb-container { + display: block; + text-align: center; + padding-left: 15px; + padding-right: 15px; + margin-bottom: 30px; + float: left; +} + +.rtl .product-detail.product-image-gallery .product-thumb-images .thumb-container { + float: right; +} + +@media (min-width: 576px) { + .product-detail.product-image-gallery .product-thumb-images .thumb-container { + width: 50%; + } +} + +@media (max-width: 575px) { + .product-detail.product-image-gallery .product-thumb-images .thumb-container { + width: 100%; + } +} + +@media (min-width: 576px) { + .product-detail.product-image-gallery .product-thumb-images .thumb-container:nth-child(2n + 1) { + clear: both; + } +} + +.product-detail .images-container .product-cover .product-flags{ + width: auto; + left: 10px; + top: 10px; + bottom: auto; + right: auto; + z-index: 99; + position: absolute; +} + +.product-detail .images-container .product-cover .product-flags .product-flag{ + position: static; +} + +.product-detail .product-cover .layer { + display: block; + z-index: 999; + background: #FFFFFF; + position: absolute; + bottom: 20px; + right: 20px; + left: auto; + top: auto; + width: auto; + height: auto; + opacity: 1; + padding: 3px; + border-radius: 3px; + -webkit-transition: all 0.3s ease-in-out; + -moz-transition: all 0.3s ease-in-out; + -ms-transition: all 0.3s ease-in-out; + -o-transition: all 0.3s ease-in-out; + transition: all 0.3s ease-in-out; + -moz-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.175); + -webkit-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.175); + -o-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.175); + -ms-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.175); + box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.175); +} + +.product-detail .product-cover .layer .zoom-in{ + font-size: 25px; +} +.product-detail .product-cover .layer:hover{ + background: #2fb5d2; +} +.product-detail .product-cover .layer:hover .zoom-in{ + color: white; +} + + + +#product-modal.leo-product-modal .modal-dialog { + max-width: 1000px; +} + +@media (max-width: 1199px) { + #product-modal.leo-product-modal .modal-dialog { + max-width: 80%; + } +} + +#product-modal.leo-product-modal .modal-content { + background: transparent; + border: none; + padding: 0; + -moz-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + -o-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + -ms-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); +} + +#product-modal.leo-product-modal .modal-content .modal-body { + position: relative; + margin-left: auto; +} + +#product-modal.leo-product-modal .modal-content .modal-body figure { + margin-bottom: 0px; + padding-right: 170px; +} + +.rtl #product-modal.leo-product-modal .modal-content .modal-body figure { + padding-left: 170px; + padding-right: inherit; +} + +#product-modal.leo-product-modal .modal-content .modal-body .product-cover-modal { + background: white; + max-width: 100%; +} + +#product-modal.leo-product-modal .modal-content .modal-body .image-caption { + background: white; + padding: 10px 20px; + border-top: #ebebeb 1px solid; +} + +#product-modal.leo-product-modal .modal-content .modal-body .image-caption p { + margin-bottom: 0; +} + +#product-modal.leo-product-modal .modal-content .modal-body .thumbnails { + position: absolute; + top: 35px; + width: 150px; + right: 15px; +} + +.rtl #product-modal.leo-product-modal .modal-content .modal-body .thumbnails { + left: 15px; + right: auto; +} + +#product-modal.leo-product-modal .modal-content .modal-body .js-modal-product-images { + padding: 0; +} + +#product-modal.leo-product-modal .modal-content .modal-body .mask { + position: relative; + overflow: hidden; + z-index: 1; + height: 833px; +} + +@media (max-width: 1199px) { + #product-modal.leo-product-modal .modal-content .modal-body .mask { + height: 500px; + } +} + +#product-modal.leo-product-modal .modal-content .modal-body .mask.nomargin { + margin-top: 0; +} + +#product-modal.leo-product-modal .modal-content .modal-body .product-images { + width: 150px; + display: none; + margin-left: 0px; +} + +#product-modal.leo-product-modal .modal-content .modal-body .product-images li.thumb-container { + border: none; + display: block; +} + +#product-modal.leo-product-modal .modal-content .modal-body .product-images img { + cursor: pointer; + -webkit-transition: all 0.3s ease; + -moz-transition: all 0.3s ease; + -ms-transition: all 0.3s ease; + -o-transition: all 0.3s ease; + transition: all 0.3s ease; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; +} + +#product-modal.leo-product-modal .modal-content .modal-body .product-images img:hover, +#product-modal.leo-product-modal .modal-content .modal-body .product-images img.selected { + border: 2px solid #414141; +} + +#product-modal.leo-product-modal .modal-content .modal-body .arrows { + display: none; + position: relative; + cursor: pointer; +} + +#product-modal.leo-product-modal .modal-content .modal-body .arrows.scroll { + display: block; +} + +#product-modal.leo-product-modal .modal-content .modal-body .arrows .arrow-up { + top: 0; +} + +#product-modal.leo-product-modal .modal-content .modal-body .arrows .arrow-down { + bottom: 0; +} + +#product-modal.leo-product-modal .modal-content .modal-body .arrows i { + font-size: 24px; + width: 50%; + float: left; + text-align: center; + color: #999999; + z-index: 9; + background: #FFFFFF; + border: 1px solid #f1f1f1; + cursor: pointer; + opacity: 0.5; + filter: alpha(opacity=50); + -webkit-transition: all 0.3s ease; + -moz-transition: all 0.3s ease; + -ms-transition: all 0.3s ease; + -o-transition: all 0.3s ease; + transition: all 0.3s ease; +} + +.rtl #product-modal.leo-product-modal .modal-content .modal-body .arrows i { + float: right; +} + +#product-modal.leo-product-modal .modal-content .modal-body .arrows i:hover { + background: #3387f2; + border-color: #3387f2; + color: #FFFFFF; + opacity: 1; + filter: alpha(opacity=100); +} + +#product-modal.leo-product-modal .modal-content .modal-body .slick-list { + margin-top: -10px; + margin-bottom: -10px; + margin-left: 0px; + margin-right: 0px; +} + +#product-modal.leo-product-modal .modal-content .modal-body .slick-list .slick-slide { + padding-top: 10px; + padding-bottom: 10px; + padding-right: 0px; + padding-left: 0px; +} + +#product-modal.leo-product-modal .modal-content .modal-body .slick-arrow { + left: 0; + right: 0; + width: 100%; + color: #FFFFFF; + background: #3387f2; +} + +#product-modal.leo-product-modal .modal-content .modal-body .slick-arrow:hover { + background: #000000; +} + +#product-modal.leo-product-modal .modal-content .modal-body .slick-arrow.slick-next { + top: 0px; + bottom: auto; +} + +#product-modal.leo-product-modal .modal-content .modal-body .slick-arrow.slick-next:before { + content: "\E316"; +} + +#product-modal.leo-product-modal .modal-content .modal-body .slick-arrow.slick-prev { + top: auto; + bottom: -20px; +} + +#product-modal.leo-product-modal .modal-content .modal-body .slick-arrow.slick-prev:before { + content: "\E313"; +} + + +.quickview.leo-quickview .modal-dialog { + width: calc(100% - 30px); + max-width: 64rem; +} + +.quickview.leo-quickview .modal-content { + min-height: 31.25rem; +} + +.quickview.leo-quickview .modal-header { + border: none; + padding: 0.625rem; +} + +.quickview.leo-quickview .modal-body { + min-height: 28.88rem; +} + +.quickview.leo-quickview .modal-footer { + border-top: 1px solid rgba(172, 170, 166, 0.3); +} + +.quickview.leo-quickview .layer { + display: none; +} + +.quickview.leo-quickview .product-cover img { + width: 95%; +} + +.quickview.leo-quickview .images-container { + position: relative; + z-index: 1; + text-align: center; +} + +.quickview.leo-quickview .images-container .product-cover { + padding-right: 90px; +} + +.rtl .quickview.leo-quickview .images-container .product-cover { + padding-left: 90px; + padding-right: inherit; +} + +.quickview.leo-quickview .images-container .product-thumb-images { + position: absolute; + top: 20px; + right: 0px; + width: 80px; + z-index: 9; +} + +.quickview.leo-quickview .product-thumb-images { + position: relative; +} + +.quickview.leo-quickview .product-thumb-images .slick-list { + margin-left: 0px; + margin-right: 0px; +} + +.quickview.leo-quickview .product-thumb-images .slick-list .slick-slide { + padding-left: 0px; + padding-right: 0px; +} + +.quickview.leo-quickview .slick-arrows .slick-arrow { + width: 100%; + margin: auto; + color: #FFFFFF; + background: #3387f2; +} + +.quickview.leo-quickview .slick-arrows .slick-arrow:hover { + color: #FFFFFF; + background: #000000; +} + +.quickview.leo-quickview .slick-arrows .slick-arrow.slick-next { + top: -10px; + left: 0; + right: 0; + bottom: auto; +} + +.quickview.leo-quickview .slick-arrows .slick-arrow.slick-next:before { + content: "\E316"; +} + +.quickview.leo-quickview .slick-arrows .slick-arrow.slick-prev { + top: auto; + left: 0; + right: 0; + bottom: -30px; +} + +.quickview.leo-quickview .slick-arrows .slick-arrow.slick-prev:before { + content: "\E313"; +} + +.quickview.leo-quickview .social-sharing { + margin: 0.625rem 1.25rem 0px 0.625rem; +} + +.rtl .quickview.leo-quickview .social-sharing { + margin: 0.625rem 0.625rem 0px 1.25rem; +} + + +/* End Style for multi product layout */ \ No newline at end of file diff --git a/modules/appagebuilder/css/unique.css b/modules/appagebuilder/css/unique.css new file mode 100644 index 00000000..29d6df22 --- /dev/null +++ b/modules/appagebuilder/css/unique.css @@ -0,0 +1,11 @@ +/*************************************************************/ +/************ CSS of module for all theme ********************/ +/************ Do not override this file **********************/ +/*************************************************************/ + +/**************DONGND update for panel tool BEGIN***********************/ +.paneltool.active .panelbutton > .fa:before +{ + content: "\f00d"; +} +/**************DONGND update for panel tool END***********************/ \ No newline at end of file diff --git a/modules/appagebuilder/errors.log b/modules/appagebuilder/errors.log new file mode 100644 index 00000000..cfc84b76 --- /dev/null +++ b/modules/appagebuilder/errors.log @@ -0,0 +1,32 @@ +[25-Apr-2023 00:50:54 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 01:18:20 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 01:27:54 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 01:32:15 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 01:40:23 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 02:49:43 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 02:54:58 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 02:55:03 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 02:57:58 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 02:58:46 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 02:59:26 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 04:26:22 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 04:32:39 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 04:37:24 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 05:18:29 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 06:22:33 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 06:33:35 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 06:35:10 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 07:13:49 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 07:14:28 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 07:41:43 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 08:34:02 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 08:45:46 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[25-Apr-2023 09:16:23 Europe/Warsaw] PHP Warning: PHP Startup: Compilation failed: invalid UTF-8 string at offset 5 in /classes/Dispatcher.php on line 1039 +[14-Jun-2023 20:10:13 Europe/Warsaw] PHP Warning: PHP Startup: Only 0 of 68925 bytes written, possibly out of free disk space in /vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php on line 254 +[14-Jun-2023 20:10:53 Europe/Warsaw] PHP Warning: PHP Startup: Only 0 of 68925 bytes written, possibly out of free disk sp[18-Jul-2023 13:03:37 Europe/Warsaw] PHP Fatal error: Uncaught Symfony\Component\Filesystem\Exception\IOException: Failed to remove directory "/var/cache/prod/smarty": PHP Startup: Directory not empty. in /vendor/symfony/symfony/src/Symfony/Component/Filesystem/Filesystem.php:180 +Stack trace: +#0 /vendor/symfony/symfony/src/Symfony/Component/Filesystem/Filesystem.php(177): Symfony\Component\Filesystem\Filesystem->remove(Array) +#1 /classes/Tools.php(3295): Symfony\Component\Filesystem\Filesystem->remove(Array) +#2 [internal function]: ToolsCore::{closure}() +#3 {main} + thrown in /vendor/symfony/symfony/src/Symfony/Component/Filesystem/Filesystem.php on line 180 diff --git a/modules/appagebuilder/img/AjaxLoader.gif b/modules/appagebuilder/img/AjaxLoader.gif new file mode 100644 index 00000000..3c329ffe Binary files /dev/null and b/modules/appagebuilder/img/AjaxLoader.gif differ diff --git a/modules/appagebuilder/img/admin/column.png b/modules/appagebuilder/img/admin/column.png new file mode 100644 index 00000000..14803fa0 Binary files /dev/null and b/modules/appagebuilder/img/admin/column.png differ diff --git a/modules/appagebuilder/img/admin/config.png b/modules/appagebuilder/img/admin/config.png new file mode 100644 index 00000000..21330ea2 Binary files /dev/null and b/modules/appagebuilder/img/admin/config.png differ diff --git a/modules/appagebuilder/img/admin/device.png b/modules/appagebuilder/img/admin/device.png new file mode 100644 index 00000000..27ec6954 Binary files /dev/null and b/modules/appagebuilder/img/admin/device.png differ diff --git a/modules/appagebuilder/img/admin/edit.png b/modules/appagebuilder/img/admin/edit.png new file mode 100644 index 00000000..47c3c7f9 Binary files /dev/null and b/modules/appagebuilder/img/admin/edit.png differ diff --git a/modules/appagebuilder/img/admin/edit.webp b/modules/appagebuilder/img/admin/edit.webp new file mode 100644 index 00000000..bfa0d310 Binary files /dev/null and b/modules/appagebuilder/img/admin/edit.webp differ diff --git a/modules/appagebuilder/img/admin/index.php b/modules/appagebuilder/img/admin/index.php new file mode 100644 index 00000000..a41987df --- /dev/null +++ b/modules/appagebuilder/img/admin/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/modules/appagebuilder/img/admin/layout.png b/modules/appagebuilder/img/admin/layout.png new file mode 100644 index 00000000..31e26fd0 Binary files /dev/null and b/modules/appagebuilder/img/admin/layout.png differ diff --git a/modules/appagebuilder/img/ajax-loader.gif b/modules/appagebuilder/img/ajax-loader.gif new file mode 100644 index 00000000..e0e6e976 Binary files /dev/null and b/modules/appagebuilder/img/ajax-loader.gif differ diff --git a/modules/appagebuilder/img/grabbing.png b/modules/appagebuilder/img/grabbing.png new file mode 100644 index 00000000..85491df0 Binary files /dev/null and b/modules/appagebuilder/img/grabbing.png differ diff --git a/modules/appagebuilder/img/graphics/buttons01.png b/modules/appagebuilder/img/graphics/buttons01.png new file mode 100644 index 00000000..72af69ff Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons01.png differ diff --git a/modules/appagebuilder/img/graphics/buttons02.png b/modules/appagebuilder/img/graphics/buttons02.png new file mode 100644 index 00000000..24deef78 Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons02.png differ diff --git a/modules/appagebuilder/img/graphics/buttons03.png b/modules/appagebuilder/img/graphics/buttons03.png new file mode 100644 index 00000000..9752c30c Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons03.png differ diff --git a/modules/appagebuilder/img/graphics/buttons04.png b/modules/appagebuilder/img/graphics/buttons04.png new file mode 100644 index 00000000..d89cce77 Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons04.png differ diff --git a/modules/appagebuilder/img/graphics/buttons05.png b/modules/appagebuilder/img/graphics/buttons05.png new file mode 100644 index 00000000..8a1fa4ab Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons05.png differ diff --git a/modules/appagebuilder/img/graphics/buttons06.png b/modules/appagebuilder/img/graphics/buttons06.png new file mode 100644 index 00000000..01db62be Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons06.png differ diff --git a/modules/appagebuilder/img/graphics/buttons07.png b/modules/appagebuilder/img/graphics/buttons07.png new file mode 100644 index 00000000..f35a58ae Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons07.png differ diff --git a/modules/appagebuilder/img/graphics/buttons08.png b/modules/appagebuilder/img/graphics/buttons08.png new file mode 100644 index 00000000..a57b2297 Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons08.png differ diff --git a/modules/appagebuilder/img/graphics/buttons09.png b/modules/appagebuilder/img/graphics/buttons09.png new file mode 100644 index 00000000..cbe79397 Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons09.png differ diff --git a/modules/appagebuilder/img/graphics/buttons10.png b/modules/appagebuilder/img/graphics/buttons10.png new file mode 100644 index 00000000..12c555a3 Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons10.png differ diff --git a/modules/appagebuilder/img/graphics/buttons11.png b/modules/appagebuilder/img/graphics/buttons11.png new file mode 100644 index 00000000..aabc62c3 Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons11.png differ diff --git a/modules/appagebuilder/img/graphics/buttons12.png b/modules/appagebuilder/img/graphics/buttons12.png new file mode 100644 index 00000000..87089e0d Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons12.png differ diff --git a/modules/appagebuilder/img/graphics/buttons13.png b/modules/appagebuilder/img/graphics/buttons13.png new file mode 100644 index 00000000..5bc6a108 Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons13.png differ diff --git a/modules/appagebuilder/img/graphics/buttons14.png b/modules/appagebuilder/img/graphics/buttons14.png new file mode 100644 index 00000000..4bfb7d34 Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons14.png differ diff --git a/modules/appagebuilder/img/graphics/buttons15.png b/modules/appagebuilder/img/graphics/buttons15.png new file mode 100644 index 00000000..c9b666f2 Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons15.png differ diff --git a/modules/appagebuilder/img/graphics/buttons16.png b/modules/appagebuilder/img/graphics/buttons16.png new file mode 100644 index 00000000..f4748373 Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons16.png differ diff --git a/modules/appagebuilder/img/graphics/buttons17.png b/modules/appagebuilder/img/graphics/buttons17.png new file mode 100644 index 00000000..8fafcd6d Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons17.png differ diff --git a/modules/appagebuilder/img/graphics/buttons18.png b/modules/appagebuilder/img/graphics/buttons18.png new file mode 100644 index 00000000..35dea7a0 Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons18.png differ diff --git a/modules/appagebuilder/img/graphics/buttons19.png b/modules/appagebuilder/img/graphics/buttons19.png new file mode 100644 index 00000000..35ba59d7 Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons19.png differ diff --git a/modules/appagebuilder/img/graphics/buttons20.png b/modules/appagebuilder/img/graphics/buttons20.png new file mode 100644 index 00000000..5676870f Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons20.png differ diff --git a/modules/appagebuilder/img/graphics/buttons21.png b/modules/appagebuilder/img/graphics/buttons21.png new file mode 100644 index 00000000..2743c0d9 Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons21.png differ diff --git a/modules/appagebuilder/img/graphics/buttons22.png b/modules/appagebuilder/img/graphics/buttons22.png new file mode 100644 index 00000000..56ade03f Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons22.png differ diff --git a/modules/appagebuilder/img/graphics/buttons23.png b/modules/appagebuilder/img/graphics/buttons23.png new file mode 100644 index 00000000..67b48a2f Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons23.png differ diff --git a/modules/appagebuilder/img/graphics/buttons24.png b/modules/appagebuilder/img/graphics/buttons24.png new file mode 100644 index 00000000..1be60517 Binary files /dev/null and b/modules/appagebuilder/img/graphics/buttons24.png differ diff --git a/modules/appagebuilder/img/graphics/hint-01.png b/modules/appagebuilder/img/graphics/hint-01.png new file mode 100644 index 00000000..11875657 Binary files /dev/null and b/modules/appagebuilder/img/graphics/hint-01.png differ diff --git a/modules/appagebuilder/img/graphics/hint-02.png b/modules/appagebuilder/img/graphics/hint-02.png new file mode 100644 index 00000000..7ab9b25b Binary files /dev/null and b/modules/appagebuilder/img/graphics/hint-02.png differ diff --git a/modules/appagebuilder/img/graphics/hint-03.png b/modules/appagebuilder/img/graphics/hint-03.png new file mode 100644 index 00000000..c44f503a Binary files /dev/null and b/modules/appagebuilder/img/graphics/hint-03.png differ diff --git a/modules/appagebuilder/img/graphics/hint-04.png b/modules/appagebuilder/img/graphics/hint-04.png new file mode 100644 index 00000000..877dd2e7 Binary files /dev/null and b/modules/appagebuilder/img/graphics/hint-04.png differ diff --git a/modules/appagebuilder/img/graphics/hint-05.png b/modules/appagebuilder/img/graphics/hint-05.png new file mode 100644 index 00000000..bbbc30ca Binary files /dev/null and b/modules/appagebuilder/img/graphics/hint-05.png differ diff --git a/modules/appagebuilder/img/graphics/hotspot-close.png b/modules/appagebuilder/img/graphics/hotspot-close.png new file mode 100644 index 00000000..955f3806 Binary files /dev/null and b/modules/appagebuilder/img/graphics/hotspot-close.png differ diff --git a/modules/appagebuilder/img/graphics/hotspot1.png b/modules/appagebuilder/img/graphics/hotspot1.png new file mode 100644 index 00000000..77cfa689 Binary files /dev/null and b/modules/appagebuilder/img/graphics/hotspot1.png differ diff --git a/modules/appagebuilder/img/graphics/hotspot2.png b/modules/appagebuilder/img/graphics/hotspot2.png new file mode 100644 index 00000000..6c3258f0 Binary files /dev/null and b/modules/appagebuilder/img/graphics/hotspot2.png differ diff --git a/modules/appagebuilder/img/graphics/hotspot3.png b/modules/appagebuilder/img/graphics/hotspot3.png new file mode 100644 index 00000000..4a2f7254 Binary files /dev/null and b/modules/appagebuilder/img/graphics/hotspot3.png differ diff --git a/modules/appagebuilder/img/graphics/index.php b/modules/appagebuilder/img/graphics/index.php new file mode 100644 index 00000000..6bf70e95 --- /dev/null +++ b/modules/appagebuilder/img/graphics/index.php @@ -0,0 +1,36 @@ + +* @copyright 2007-2012 PrestaShop SA +* @version Release: $Revision: 13573 $ +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/modules/appagebuilder/img/graphics/loader.gif b/modules/appagebuilder/img/graphics/loader.gif new file mode 100644 index 00000000..8bbcc6a6 Binary files /dev/null and b/modules/appagebuilder/img/graphics/loader.gif differ diff --git a/modules/appagebuilder/img/graphics/zoomin.cur b/modules/appagebuilder/img/graphics/zoomin.cur new file mode 100644 index 00000000..ca3c61d5 Binary files /dev/null and b/modules/appagebuilder/img/graphics/zoomin.cur differ diff --git a/modules/appagebuilder/img/graphics/zoomout.cur b/modules/appagebuilder/img/graphics/zoomout.cur new file mode 100644 index 00000000..5a7f7fed Binary files /dev/null and b/modules/appagebuilder/img/graphics/zoomout.cur differ diff --git a/modules/appagebuilder/img/index.php b/modules/appagebuilder/img/index.php new file mode 100644 index 00000000..6bf70e95 --- /dev/null +++ b/modules/appagebuilder/img/index.php @@ -0,0 +1,36 @@ + +* @copyright 2007-2012 PrestaShop SA +* @version Release: $Revision: 13573 $ +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/modules/appagebuilder/index.php b/modules/appagebuilder/index.php new file mode 100644 index 00000000..a41987df --- /dev/null +++ b/modules/appagebuilder/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/modules/appagebuilder/js/ApImage360.js b/modules/appagebuilder/js/ApImage360.js new file mode 100644 index 00000000..fee055ad --- /dev/null +++ b/modules/appagebuilder/js/ApImage360.js @@ -0,0 +1,5547 @@ +/** + * @Website: apollotheme.com - prestashop template provider + * @author Apollotheme + * @copyright 2007-2018 Apollotheme + * @description: + */ + +var LeoImage360 = (function() { + var s, u; + s = u = (function() { + var N = { + version: "v3.3-b5", + UUID: 0, + storage: {}, + $uuid: function(R) { + return (R.$J_UUID || (R.$J_UUID = ++H.UUID)) + }, + getStorage: function(R) { + return (H.storage[R] || (H.storage[R] = {})) + }, + $F: function() {}, + leofalse: function() { + return false + }, + leotrue: function() { + return true + }, + stylesId: "mjs-" + Math.floor(Math.random() * new Date().getTime()), + defined: function(R) { + return (undefined != R) + }, + ifndef: function(S, R) { + return (undefined != S) ? S : R + }, + exists: function(R) { + return !!(R) + }, + jTypeOf: function(R) { + if (!H.defined(R)) { + return false + } + if (R.$J_TYPE) { + return R.$J_TYPE + } + if (!!R.nodeType) { + if (1 == R.nodeType) { + return "element" + } + if (3 == R.nodeType) { + return "textnode" + } + } + if (R.length && R.item) { + return "collection" + } + if (R.length && R.callee) { + return "arguments" + } + if ((R instanceof window.Object || R instanceof window.Function) && R.constructor === H.Class) { + return "class" + } + if (R instanceof window.Array) { + return "array" + } + if (R instanceof window.Function) { + return "function" + } + if (R instanceof window.String) { + return "string" + } + if (H.browser.trident) { + if (H.defined(R.cancelBubble)) { + return "event" + } + } else { + if (R === window.event || R.constructor == window.Event || R.constructor == window.MouseEvent || R.constructor == window.UIEvent || R.constructor == window.KeyboardEvent || R.constructor == window.KeyEvent) { + return "event" + } + } + if (R instanceof window.Date) { + return "date" + } + if (R instanceof window.RegExp) { + return "regexp" + } + if (R === window) { + return "window" + } + if (R === document) { + return "document" + } + return typeof(R) + }, + extend: function(W, V) { + if (!(W instanceof window.Array)) { + W = [W] + } + if (!V) { + return W[0] + } + for (var U = 0, S = W.length; U < S; U++) { + if (!H.defined(W)) { + continue + } + for (var T in V) { + if (!Object.prototype.hasOwnProperty.call(V, T)) { + continue + } + try { + W[U][T] = V[T] + } catch (R) {} + } + } + return W[0] + }, + implement: function(V, U) { + if (!(V instanceof window.Array)) { + V = [V] + } + for (var T = 0, R = V.length; T < R; T++) { + if (!H.defined(V[T])) { + continue + } + if (!V[T].prototype) { + continue + } + for (var S in (U || {})) { + if (!V[T].prototype[S]) { + V[T].prototype[S] = U[S] + } + } + } + return V[0] + }, + nativize: function(T, S) { + if (!H.defined(T)) { + return T + } + for (var R in (S || {})) { + if (!T[R]) { + T[R] = S[R] + } + } + return T + }, + $try: function() { + for (var S = 0, R = arguments.length; S < R; S++) { + try { + return arguments[S]() + } catch (T) {} + } + return null + }, + $A: function(T) { + if (!H.defined(T)) { + return H.$([]) + } + if (T.toArray) { + return H.$(T.toArray()) + } + if (T.item) { + var S = T.length || 0, + R = new Array(S); + while (S--) { + R[S] = T[S] + } + return H.$(R) + } + return H.$(Array.prototype.slice.call(T)) + }, + now: function() { + return new Date().getTime() + }, + detach: function(V) { + var T; + switch (H.jTypeOf(V)) { + case "object": + T = {}; + for (var U in V) { + T[U] = H.detach(V[U]) + } + break; + case "array": + T = []; + for (var S = 0, R = V.length; S < R; S++) { + T[S] = H.detach(V[S]) + } + break; + default: + return V + } + return H.$(T) + }, + $: function(T) { + var R = true; + if (!H.defined(T)) { + return null + } + if (T.$J_EXT) { + return T + } + switch (H.jTypeOf(T)) { + case "array": + T = H.nativize(T, H.extend(H.Array, { + $J_EXT: H.$F + })); + T.jEach = T.forEach; + return T; + break; + case "string": + var S = document.getElementById(T); + if (H.defined(S)) { + return H.$(S) + } + return null; + break; + case "window": + case "document": + H.$uuid(T); + T = H.extend(T, H.Doc); + break; + case "element": + H.$uuid(T); + T = H.extend(T, H.Element); + break; + case "event": + T = H.extend(T, H.Event); + break; + case "textnode": + case "function": + case "array": + case "date": + default: + R = false; + break + } + if (R) { + return H.extend(T, { + $J_EXT: H.$F + }) + } else { + return T + } + }, + $new: function(R, T, S) { + return H.$(H.doc.createElement(R)).setProps(T || {}).jSetCss(S || {}) + }, + addCSS: function(S, U, Y) { + var V, T, W, X = [], + R = -1; + Y || (Y = H.stylesId); + V = H.$(Y) || H.$new("style", { + id: Y, + type: "text/css" + }).jAppendTo((document.head || document.body), "top"); + T = V.sheet || V.styleSheet; + if ("string" != H.jTypeOf(U)) { + for (var W in U) { + X.push(W + ":" + U[W]) + } + U = X.join(";") + } + if (T.insertRule) { + R = T.insertRule(S + " {" + U + "}", T.cssRules.length) + } else { + R = T.addRule(S, U) + } + return R + }, + removeCSS: function(U, R) { + var T, S; + T = H.$(U); + if ("element" !== H.jTypeOf(T)) { + return + } + S = T.sheet || T.styleSheet; + if (S.deleteRule) { + S.deleteRule(R) + } else { + if (S.removeRule) { + S.removeRule(R) + } + } + }, + generateUUID: function() { + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(T) { + var S = Math.random() * 16 | 0, + R = T == "x" ? S : (S & 3 | 8); + return R.toString(16) + }).toUpperCase() + }, + getAbsoluteURL: (function() { + var R; + return function(S) { + if (!R) { + R = document.createElement("a") + } + R.setAttribute("href", S); + return ("!!" + R.href).replace("!!", "") + } + })(), + getHashCode: function(T) { + var U = 0, + R = T.length; + for (var S = 0; S < R; ++S) { + U = 31 * U + T.charCodeAt(S); + U %= 4294967296 + } + return U + } + }; + var H = N; + var I = N.$; + if (!window.leoimageJS) { + window.leoimageJS = N; + window.$mjs = N.$ + } + H.Array = { + $J_TYPE: "array", + indexOf: function(U, V) { + var R = this.length; + for (var S = this.length, T = (V < 0) ? Math.max(0, S + V) : V || 0; T < S; T++) { + if (this[T] === U) { + return T + } + } + return -1 + }, + contains: function(R, S) { + return this.indexOf(R, S) != -1 + }, + forEach: function(R, U) { + for (var T = 0, S = this.length; T < S; T++) { + if (T in this) { + R.call(U, this[T], T, this) + } + } + }, + filter: function(R, W) { + var V = []; + for (var U = 0, S = this.length; U < S; U++) { + if (U in this) { + var T = this[U]; + if (R.call(W, this[U], U, this)) { + V.push(T) + } + } + } + return V + }, + map: function(R, V) { + var U = []; + for (var T = 0, S = this.length; T < S; T++) { + if (T in this) { + U[T] = R.call(V, this[T], T, this) + } + } + return U + } + }; + H.implement(String, { + $J_TYPE: "string", + jTrim: function() { + return this.replace(/^\s+|\s+$/g, "") + }, + eq: function(R, S) { + return (S || false) ? (this.toString() === R.toString()) : (this.toLowerCase().toString() === R.toLowerCase().toString()) + }, + jCamelize: function() { + return this.replace(/-\D/g, function(R) { + return R.charAt(1).toUpperCase() + }) + }, + dashize: function() { + return this.replace(/[A-Z]/g, function(R) { + return ("-" + R.charAt(0).toLowerCase()) + }) + }, + jToInt: function(R) { + return parseInt(this, R || 10) + }, + toFloat: function() { + return parseFloat(this) + }, + jToBool: function() { + return !this.replace(/true/i, "").jTrim() + }, + has: function(S, R) { + R = R || ""; + return (R + this + R).indexOf(R + S + R) > -1 + } + }); + N.implement(Function, { + $J_TYPE: "function", + jBind: function() { + var S = H.$A(arguments), + R = this, + T = S.shift(); + return function() { + return R.apply(T || null, S.concat(H.$A(arguments))) + } + }, + jBindAsEvent: function() { + var S = H.$A(arguments), + R = this, + T = S.shift(); + return function(U) { + return R.apply(T || null, H.$([U || (H.browser.ieMode ? window.event : null)]).concat(S)) + } + }, + jDelay: function() { + var S = H.$A(arguments), + R = this, + T = S.shift(); + return window.setTimeout(function() { + return R.apply(R, S) + }, T || 0) + }, + jDefer: function() { + var S = H.$A(arguments), + R = this; + return function() { + return R.jDelay.apply(R, S) + } + }, + interval: function() { + var S = H.$A(arguments), + R = this, + T = S.shift(); + return window.setInterval(function() { + return R.apply(R, S) + }, T || 0) + } + }); + var O = {}, + G = navigator.userAgent.toLowerCase(), + F = G.match(/(webkit|gecko|trident|presto)\/(\d+\.?\d*)/i), + K = G.match(/(edge|opr)\/(\d+\.?\d*)/i) || G.match(/(crios|chrome|safari|firefox|opera|opr)\/(\d+\.?\d*)/i), + M = G.match(/version\/(\d+\.?\d*)/i), + B = document.documentElement.style; + + function C(S) { + var R = S.charAt(0).toUpperCase() + S.slice(1); + return S in B || ("Webkit" + R) in B || ("Moz" + R) in B || ("ms" + R) in B || ("O" + R) in B + } + H.browser = { + features: { + xpath: !!(document.evaluate), + air: !!(window.runtime), + query: !!(document.querySelector), + fullScreen: !!(document.fullscreenEnabled || document.msFullscreenEnabled || document.exitFullscreen || document.cancelFullScreen || document.webkitexitFullscreen || document.webkitCancelFullScreen || document.mozCancelFullScreen || document.oCancelFullScreen || document.msCancelFullScreen), + xhr2: !!(window.ProgressEvent) && !!(window.FormData) && (window.XMLHttpRequest && "withCredentials" in new XMLHttpRequest), + transition: C("transition"), + transform: C("transform"), + perspective: C("perspective"), + animation: C("animation"), + requestAnimationFrame: false, + multibackground: false, + cssFilters: false, + canvas: false, + svg: (function() { + return document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1") + })() + }, + touchScreen: function() { + return "ontouchstart" in window || (window.DocumentTouch && document instanceof DocumentTouch) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0) + }(), + mobile: G.match(/(android|bb\d+|meego).+|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/) ? true : false, + engine: (F && F[1]) ? F[1].toLowerCase() : (window.opera) ? "presto" : !!(window.ActiveXObject) ? "trident" : (undefined !== document.getBoxObjectFor || null != window.mozInnerScreenY) ? "gecko" : (null !== window.WebKitPoint || !navigator.taintEnabled) ? "webkit" : "unknown", + version: (F && F[2]) ? parseFloat(F[2]) : 0, + uaName: (K && K[1]) ? K[1].toLowerCase() : "", + uaVersion: (K && K[2]) ? parseFloat(K[2]) : 0, + cssPrefix: "", + cssDomPrefix: "", + domPrefix: "", + ieMode: 0, + platform: G.match(/ip(?:ad|od|hone)/) ? "ios" : (G.match(/(?:webos|android)/) || navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase(), + backCompat: document.compatMode && "backcompat" == document.compatMode.toLowerCase(), + scrollbarsWidth: 0, + getDoc: function() { + return (document.compatMode && "backcompat" == document.compatMode.toLowerCase()) ? document.body : document.documentElement + }, + requestAnimationFrame: window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || undefined, + cancelAnimationFrame: window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame || window.webkitCancelRequestAnimationFrame || undefined, + ready: false, + onready: function() { + if (H.browser.ready) { + return + } + var U, T; + H.browser.ready = true; + H.body = H.$(document.body); + H.win = H.$(window); + try { + var S = H.$new("div").jSetCss({ + width: 100, + height: 100, + overflow: "scroll", + position: "absolute", + top: -9999 + }).jAppendTo(document.body); + H.browser.scrollbarsWidth = S.offsetWidth - S.clientWidth; + S.jRemove() + } catch (R) {} + try { + U = H.$new("div"); + T = U.style; + T.cssText = "background:url(https://),url(https://),red url(https://)"; + H.browser.features.multibackground = (/(url\s*\(.*?){3}/).test(T.background); + T = null; + U = null + } catch (R) {} + if (!H.browser.cssTransformProp) { + H.browser.cssTransformProp = H.normalizeCSS("transform").dashize() + } + try { + U = H.$new("div"); + U.style.cssText = H.normalizeCSS("filter").dashize() + ":blur(2px);"; + H.browser.features.cssFilters = !!U.style.length && (!H.browser.ieMode || H.browser.ieMode > 9); + U = null + } catch (R) {} + if (!H.browser.features.cssFilters) { + H.$(document.documentElement).jAddClass("no-cssfilters-leoimage") + } + try { + H.browser.features.canvas = (function() { + var V = H.$new("canvas"); + return !!(V.getContext && V.getContext("2d")) + })() + } catch (R) {} + if (undefined === window.TransitionEvent && undefined !== window.WebKitTransitionEvent) { + O.transitionend = "webkitTransitionEnd" + } + H.Doc.jCallEvent.call(H.$(document), "domready") + } + }; + (function() { + var W = [], + V, U, S; + + function R() { + return !!(arguments.callee.caller) + } + switch (H.browser.engine) { + case "trident": + if (!H.browser.version) { + H.browser.version = !!(window.XMLHttpRequest) ? 3 : 2 + } + break; + case "gecko": + H.browser.version = (K && K[2]) ? parseFloat(K[2]) : 0; + break + } + H.browser[H.browser.engine] = true; + if (K && "crios" === K[1]) { + H.browser.uaName = "chrome" + } + if (!!window.chrome) { + H.browser.chrome = true + } + if (K && "opr" === K[1]) { + H.browser.uaName = "opera"; + H.browser.opera = true + } + if ("safari" === H.browser.uaName && (M && M[1])) { + H.browser.uaVersion = parseFloat(M[1]) + } + if ("android" == H.browser.platform && H.browser.webkit && (M && M[1])) { + H.browser.androidBrowser = true + } + V = ({ + gecko: ["-moz-", "Moz", "moz"], + webkit: ["-webkit-", "Webkit", "webkit"], + trident: ["-ms-", "ms", "ms"], + presto: ["-o-", "O", "o"] + })[H.browser.engine] || ["", "", ""]; + H.browser.cssPrefix = V[0]; + H.browser.cssDomPrefix = V[1]; + H.browser.domPrefix = V[2]; + H.browser.ieMode = (!H.browser.trident) ? undefined : (document.documentMode) ? document.documentMode : function() { + var X = 0; + if (H.browser.backCompat) { + return 5 + } + switch (H.browser.version) { + case 2: + X = 6; + break; + case 3: + X = 7; + break + } + return X + }(); + W.push(H.browser.platform + "-leoimage"); + if (H.browser.mobile) { + W.push("mobile-leoimage") + } + if (H.browser.androidBrowser) { + W.push("android-browser-leoimage") + } + if (H.browser.ieMode) { + H.browser.uaName = "ie"; + H.browser.uaVersion = H.browser.ieMode; + W.push("ie" + H.browser.ieMode + "-leoimage"); + for (U = 11; U > H.browser.ieMode; U--) { + W.push("lt-ie" + U + "-leoimage") + } + } + if (H.browser.webkit && H.browser.version < 536) { + H.browser.features.fullScreen = false + } + if (H.browser.requestAnimationFrame) { + H.browser.requestAnimationFrame.call(window, function() { + H.browser.features.requestAnimationFrame = true + }) + } + if (H.browser.features.svg) { + W.push("svg-leoimage") + } else { + W.push("no-svg-leoimage") + } + S = (document.documentElement.className || "").match(/\S+/g) || []; + document.documentElement.className = H.$(S).concat(W).join(" "); + try { + document.documentElement.setAttribute("data-leoimage-ua", H.browser.uaName); + document.documentElement.setAttribute("data-leoimage-ua-ver", H.browser.uaVersion) + } catch (T) {} + if (H.browser.ieMode && H.browser.ieMode < 9) { + document.createElement("figure"); + document.createElement("figcaption") + } + })(); + (function() { + H.browser.fullScreen = { + capable: H.browser.features.fullScreen, + enabled: function() { + return !!(document.fullscreenElement || document[H.browser.domPrefix + "FullscreenElement"] || document.fullScreen || document.webkitIsFullScreen || document[H.browser.domPrefix + "FullScreen"]) + }, + request: function(R, S) { + S || (S = {}); + if (this.capable) { + H.$(document).jAddEvent(this.changeEventName, this.onchange = function(T) { + if (this.enabled()) { + S.onEnter && S.onEnter() + } else { + H.$(document).jRemoveEvent(this.changeEventName, this.onchange); + S.onExit && S.onExit() + } + }.jBindAsEvent(this)); + H.$(document).jAddEvent(this.errorEventName, this.onerror = function(T) { + S.fallback && S.fallback(); + H.$(document).jRemoveEvent(this.errorEventName, this.onerror) + }.jBindAsEvent(this)); + (R[H.browser.domPrefix + "RequestFullscreen"] || R[H.browser.domPrefix + "RequestFullScreen"] || R.requestFullscreen || function() {}).call(R) + } else { + if (S.fallback) { + S.fallback() + } + } + }, + cancel: (document.exitFullscreen || document.cancelFullScreen || document[H.browser.domPrefix + "ExitFullscreen"] || document[H.browser.domPrefix + "CancelFullScreen"] || function() {}).jBind(document), + changeEventName: document.msExitFullscreen ? "MSFullscreenChange" : (document.exitFullscreen ? "" : H.browser.domPrefix) + "fullscreenchange", + errorEventName: document.msExitFullscreen ? "MSFullscreenError" : (document.exitFullscreen ? "" : H.browser.domPrefix) + "fullscreenerror", + prefix: H.browser.domPrefix, + activeElement: null + } + })(); + var Q = /\S+/g, + E = /^(border(Top|Bottom|Left|Right)Width)|((padding|margin)(Top|Bottom|Left|Right))$/, + J = { + "float": ("undefined" === typeof(B.styleFloat)) ? "cssFloat" : "styleFloat" + }, + L = { + fontWeight: true, + lineHeight: true, + opacity: true, + zIndex: true, + zoom: true + }, + D = (window.getComputedStyle) ? function(T, R) { + var S = window.getComputedStyle(T, null); + return S ? S.getPropertyValue(R) || S[R] : null + } : function(U, S) { + var T = U.currentStyle, + R = null; + R = T ? T[S] : null; + if (null == R && U.style && U.style[S]) { + R = U.style[S] + } + return R + }; + + function P(T) { + var R, S; + S = (H.browser.webkit && "filter" == T) ? false : (T in B); + if (!S) { + R = H.browser.cssDomPrefix + T.charAt(0).toUpperCase() + T.slice(1); + if (R in B) { + return R + } + } + return T + } + H.normalizeCSS = P; + H.Element = { + jHasClass: function(R) { + return !(R || "").has(" ") && (this.className || "").has(R, " ") + }, + jAddClass: function(V) { + var S = (this.className || "").match(Q) || [], + U = (V || "").match(Q) || [], + R = U.length, + T = 0; + for (; T < R; T++) { + if (!H.$(S).contains(U[T])) { + S.push(U[T]) + } + } + this.className = S.join(" "); + return this + }, + jRemoveClass: function(W) { + var S = (this.className || "").match(Q) || [], + V = (W || "").match(Q) || [], + R = V.length, + U = 0, + T; + for (; U < R; U++) { + if ((T = H.$(S).indexOf(V[U])) > -1) { + S.splice(T, 1) + } + } + this.className = W ? S.join(" ") : ""; + return this + }, + jToggleClass: function(R) { + return this.jHasClass(R) ? this.jRemoveClass(R) : this.jAddClass(R) + }, + jGetCss: function(S) { + var T = S.jCamelize(), + R = null; + S = J[T] || (J[T] = P(T)); + R = D(this, S); + if ("auto" === R) { + R = null + } + if (null !== R) { + if ("opacity" == S) { + return H.defined(R) ? parseFloat(R) : 1 + } + if (E.test(S)) { + R = parseInt(R, 10) ? R : "0px" + } + } + return R + }, + jSetCssProp: function(S, R) { + var U = S.jCamelize(); + try { + if ("opacity" == S) { + this.jSetOpacity(R); + return this + } + S = J[U] || (J[U] = P(U)); + this.style[S] = R + (("number" == H.jTypeOf(R) && !L[U]) ? "px" : "") + } catch (T) {} + return this + }, + jSetCss: function(S) { + for (var R in S) { + this.jSetCssProp(R, S[R]) + } + return this + }, + jGetStyles: function() { + var R = {}; + H.$A(arguments).jEach(function(S) { + R[S] = this.jGetCss(S) + }, this); + return R + }, + jSetOpacity: function(T, R) { + var S; + R = R || false; + this.style.opacity = T; + T = parseInt(parseFloat(T) * 100); + if (R) { + if (0 === T) { + if ("hidden" != this.style.visibility) { + this.style.visibility = "hidden" + } + } else { + if ("visible" != this.style.visibility) { + this.style.visibility = "visible" + } + } + } + if (H.browser.ieMode && H.browser.ieMode < 9) { + if (!isNaN(T)) { + if (!~this.style.filter.indexOf("Alpha")) { + this.style.filter += " progid:DXImageTransform.Microsoft.Alpha(Opacity=" + T + ")" + } else { + this.style.filter = this.style.filter.replace(/Opacity=\d*/i, "Opacity=" + T) + } + } else { + this.style.filter = this.style.filter.replace(/progid:DXImageTransform.Microsoft.Alpha\(Opacity=\d*\)/i, "").jTrim(); + if ("" === this.style.filter) { + this.style.removeAttribute("filter") + } + } + } + return this + }, + setProps: function(R) { + for (var S in R) { + if ("class" === S) { + this.jAddClass("" + R[S]) + } else { + this.setAttribute(S, "" + R[S]) + } + } + return this + }, + jGetTransitionDuration: function() { + var S = 0, + R = 0; + S = this.jGetCss("transition-duration"); + R = this.jGetCss("transition-delay"); + S = S.indexOf("ms") > -1 ? parseFloat(S) : S.indexOf("s") > -1 ? parseFloat(S) * 1000 : 0; + R = R.indexOf("ms") > -1 ? parseFloat(R) : R.indexOf("s") > -1 ? parseFloat(R) * 1000 : 0; + return S + R + }, + hide: function() { + return this.jSetCss({ + display: "none", + visibility: "hidden" + }) + }, + show: function() { + return this.jSetCss({ + display: "", + visibility: "visible" + }) + }, + jGetSize: function() { + return { + width: this.offsetWidth, + height: this.offsetHeight + } + }, + getInnerSize: function(S) { + var R = this.jGetSize(); + R.width -= (parseFloat(this.jGetCss("border-left-width") || 0) + parseFloat(this.jGetCss("border-right-width") || 0)); + R.height -= (parseFloat(this.jGetCss("border-top-width") || 0) + parseFloat(this.jGetCss("border-bottom-width") || 0)); + if (!S) { + R.width -= (parseFloat(this.jGetCss("padding-left") || 0) + parseFloat(this.jGetCss("padding-right") || 0)); + R.height -= (parseFloat(this.jGetCss("padding-top") || 0) + parseFloat(this.jGetCss("padding-bottom") || 0)) + } + return R + }, + jGetScroll: function() { + return { + top: this.scrollTop, + left: this.scrollLeft + } + }, + jGetFullScroll: function() { + var R = this, + S = { + top: 0, + left: 0 + }; + do { + S.left += R.scrollLeft || 0; + S.top += R.scrollTop || 0; + R = R.parentNode + } while (R); + return S + }, + jGetPosition: function() { + var V = this, + S = 0, + U = 0; + if (H.defined(document.documentElement.getBoundingClientRect)) { + var R = this.getBoundingClientRect(), + T = H.$(document).jGetScroll(), + W = H.browser.getDoc(); + return { + top: R.top + T.y - W.clientTop, + left: R.left + T.x - W.clientLeft + } + } + do { + S += V.offsetLeft || 0; + U += V.offsetTop || 0; + V = V.offsetParent + } while (V && !(/^(?:body|html)$/i).test(V.tagName)); + return { + top: U, + left: S + } + }, + jGetRect: function() { + var S = this.jGetPosition(); + var R = this.jGetSize(); + return { + top: S.top, + bottom: S.top + R.height, + left: S.left, + right: S.left + R.width + } + }, + changeContent: function(S) { + try { + this.innerHTML = S + } catch (R) { + this.innerText = S + } + return this + }, + jRemove: function() { + return (this.parentNode) ? this.parentNode.removeChild(this) : this + }, + kill: function() { + H.$A(this.childNodes).jEach(function(R) { + if (3 == R.nodeType || 8 == R.nodeType) { + return + } + H.$(R).kill() + }); + this.jRemove(); + this.jClearEvents(); + if (this.$J_UUID) { + H.storage[this.$J_UUID] = null; + delete H.storage[this.$J_UUID] + } + return null + }, + append: function(T, S) { + S = S || "bottom"; + var R = this.firstChild; + ("top" == S && R) ? this.insertBefore(T, R): this.appendChild(T); + return this + }, + jAppendTo: function(T, S) { + var R = H.$(T).append(this, S); + return this + }, + enclose: function(R) { + this.append(R.parentNode.replaceChild(this, R)); + return this + }, + hasChild: function(R) { + if ("element" !== H.jTypeOf("string" == H.jTypeOf(R) ? R = document.getElementById(R) : R)) { + return false + } + return (this == R) ? false : (this.contains && !(H.browser.webkit419)) ? (this.contains(R)) : (this.compareDocumentPosition) ? !!(this.compareDocumentPosition(R) & 16) : H.$A(this.byTag(R.tagName)).contains(R) + } + }; + H.Element.jGetStyle = H.Element.jGetCss; + H.Element.jSetStyle = H.Element.jSetCss; + if (!window.Element) { + window.Element = H.$F; + if (H.browser.engine.webkit) { + window.document.createElement("iframe") + } + window.Element.prototype = (H.browser.engine.webkit) ? window["[[DOMElement.prototype]]"] : {} + } + H.implement(window.Element, { + $J_TYPE: "element" + }); + H.Doc = { + jGetSize: function() { + if (H.browser.touchScreen || H.browser.presto925 || H.browser.webkit419) { + return { + width: window.innerWidth, + height: window.innerHeight + } + } + return { + width: H.browser.getDoc().clientWidth, + height: H.browser.getDoc().clientHeight + } + }, + jGetScroll: function() { + return { + x: window.pageXOffset || H.browser.getDoc().scrollLeft, + y: window.pageYOffset || H.browser.getDoc().scrollTop + } + }, + jGetFullSize: function() { + var R = this.jGetSize(); + return { + width: Math.max(H.browser.getDoc().scrollWidth, R.width), + height: Math.max(H.browser.getDoc().scrollHeight, R.height) + } + } + }; + H.extend(document, { + $J_TYPE: "document" + }); + H.extend(window, { + $J_TYPE: "window" + }); + H.extend([H.Element, H.Doc], { + jFetch: function(U, S) { + var R = H.getStorage(this.$J_UUID), + T = R[U]; + if (undefined !== S && undefined === T) { + T = R[U] = S + } + return (H.defined(T) ? T : null) + }, + jStore: function(T, S) { + var R = H.getStorage(this.$J_UUID); + R[T] = S; + return this + }, + jDel: function(S) { + var R = H.getStorage(this.$J_UUID); + delete R[S]; + return this + } + }); + if (!(window.HTMLElement && window.HTMLElement.prototype && window.HTMLElement.prototype.getElementsByClassName)) { + H.extend([H.Element, H.Doc], { + getElementsByClassName: function(R) { + return H.$A(this.getElementsByTagName("*")).filter(function(T) { + try { + return (1 == T.nodeType && T.className.has(R, " ")) + } catch (S) {} + }) + } + }) + } + H.extend([H.Element, H.Doc], { + byClass: function() { + return this.getElementsByClassName(arguments[0]) + }, + byTag: function() { + return this.getElementsByTagName(arguments[0]) + } + }); + if (H.browser.fullScreen.capable && !document.requestFullScreen) { + H.Element.requestFullScreen = function() { + H.browser.fullScreen.request(this) + } + } + H.Event = { + $J_TYPE: "event", + isQueueStopped: H.leofalse, + stop: function() { + return this.stopDistribution().stopDefaults() + }, + stopDistribution: function() { + if (this.stopPropagation) { + this.stopPropagation() + } else { + this.cancelBubble = true + } + return this + }, + stopDefaults: function() { + if (this.preventDefault) { + this.preventDefault() + } else { + this.returnValue = false + } + return this + }, + stopQueue: function() { + this.isQueueStopped = H.leotrue; + return this + }, + getClientXY: function() { + var S, R; + S = ((/touch/i).test(this.type)) ? this.changedTouches[0] : this; + return (!H.defined(S)) ? { + x: 0, + y: 0 + } : { + x: S.clientX, + y: S.clientY + } + }, + jGetPageXY: function() { + var S, R; + S = ((/touch/i).test(this.type)) ? this.changedTouches[0] : this; + return (!H.defined(S)) ? { + x: 0, + y: 0 + } : { + x: S.pageX || S.clientX + H.browser.getDoc().scrollLeft, + y: S.pageY || S.clientY + H.browser.getDoc().scrollTop + } + }, + getTarget: function() { + var R = this.target || this.srcElement; + while (R && 3 == R.nodeType) { + R = R.parentNode + } + return R + }, + getRelated: function() { + var S = null; + switch (this.type) { + case "mouseover": + case "pointerover": + case "MSPointerOver": + S = this.relatedTarget || this.fromElement; + break; + case "mouseout": + case "pointerout": + case "MSPointerOut": + S = this.relatedTarget || this.toElement; + break; + default: + return S + } + try { + while (S && 3 == S.nodeType) { + S = S.parentNode + } + } catch (R) { + S = null + } + return S + }, + getButton: function() { + if (!this.which && this.button !== undefined) { + return (this.button & 1 ? 1 : (this.button & 2 ? 3 : (this.button & 4 ? 2 : 0))) + } + return this.which + }, + isTouchEvent: function() { + return (this.pointerType && ("touch" === this.pointerType || this.pointerType === this.MSPOINTER_TYPE_TOUCH)) || (/touch/i).test(this.type) + }, + isPrimaryTouch: function() { + return this.pointerType ? (("touch" === this.pointerType || this.MSPOINTER_TYPE_TOUCH === this.pointerType) && this.isPrimary) : 1 === this.changedTouches.length && (this.targetTouches.length ? this.targetTouches[0].identifier == this.changedTouches[0].identifier : true) + } + }; + H._event_add_ = "addEventListener"; + H._event_del_ = "removeEventListener"; + H._event_prefix_ = ""; + if (!document.addEventListener) { + H._event_add_ = "attachEvent"; + H._event_del_ = "detachEvent"; + H._event_prefix_ = "on" + } + H.Event.Custom = { + type: "", + x: null, + y: null, + timeStamp: null, + button: null, + target: null, + relatedTarget: null, + $J_TYPE: "event.custom", + isQueueStopped: H.leofalse, + events: H.$([]), + pushToEvents: function(R) { + var S = R; + this.events.push(S) + }, + stop: function() { + return this.stopDistribution().stopDefaults() + }, + stopDistribution: function() { + this.events.jEach(function(S) { + try { + S.stopDistribution() + } catch (R) {} + }); + return this + }, + stopDefaults: function() { + this.events.jEach(function(S) { + try { + S.stopDefaults() + } catch (R) {} + }); + return this + }, + stopQueue: function() { + this.isQueueStopped = H.leotrue; + return this + }, + getClientXY: function() { + return { + x: this.clientX, + y: this.clientY + } + }, + jGetPageXY: function() { + return { + x: this.x, + y: this.y + } + }, + getTarget: function() { + return this.target + }, + getRelated: function() { + return this.relatedTarget + }, + getButton: function() { + return this.button + }, + getOriginalTarget: function() { + return this.events.length > 0 ? this.events[0].getTarget() : undefined + } + }; + H.extend([H.Element, H.Doc], { + jAddEvent: function(T, V, W, Z) { + var Y, R, U, X, S; + if ("string" == H.jTypeOf(T)) { + S = T.split(" "); + if (S.length > 1) { + T = S + } + } + if (H.jTypeOf(T) == "array") { + H.$(T).jEach(this.jAddEvent.jBindAsEvent(this, V, W, Z)); + return this + } + if (!T || !V || H.jTypeOf(T) != "string" || H.jTypeOf(V) != "function") { + return this + } + if (T == "domready" && H.browser.ready) { + V.call(this); + return this + } + T = O[T] || T; + W = parseInt(W || 50); + if (!V.$J_EUID) { + V.$J_EUID = Math.floor(Math.random() * H.now()) + } + Y = H.Doc.jFetch.call(this, "_EVENTS_", {}); + R = Y[T]; + if (!R) { + Y[T] = R = H.$([]); + U = this; + if (H.Event.Custom[T]) { + H.Event.Custom[T].handler.add.call(this, Z) + } else { + R.handle = function(aa) { + aa = H.extend(aa || window.e, { + $J_TYPE: "event" + }); + H.Doc.jCallEvent.call(U, T, H.$(aa)) + }; + this[H._event_add_](H._event_prefix_ + T, R.handle, false) + } + } + X = { + type: T, + fn: V, + priority: W, + euid: V.$J_EUID + }; + R.push(X); + R.sort(function(ab, aa) { + return ab.priority - aa.priority + }); + return this + }, + jRemoveEvent: function(X) { + var V = H.Doc.jFetch.call(this, "_EVENTS_", {}), + T, R, S, Y, W, U; + W = arguments.length > 1 ? arguments[1] : -100; + if ("string" == H.jTypeOf(X)) { + U = X.split(" "); + if (U.length > 1) { + X = U + } + } + if (H.jTypeOf(X) == "array") { + H.$(X).jEach(this.jRemoveEvent.jBindAsEvent(this, W)); + return this + } + X = O[X] || X; + if (!X || H.jTypeOf(X) != "string" || !V || !V[X]) { + return this + } + T = V[X] || []; + for (S = 0; S < T.length; S++) { + R = T[S]; + if (-100 == W || !!W && W.$J_EUID === R.euid) { + Y = T.splice(S--, 1) + } + } + if (0 === T.length) { + if (H.Event.Custom[X]) { + H.Event.Custom[X].handler.jRemove.call(this) + } else { + this[H._event_del_](H._event_prefix_ + X, T.handle, false) + } + delete V[X] + } + return this + }, + jCallEvent: function(V, X) { + var U = H.Doc.jFetch.call(this, "_EVENTS_", {}), + T, R, S; + V = O[V] || V; + if (!V || H.jTypeOf(V) != "string" || !U || !U[V]) { + return this + } + try { + X = H.extend(X || {}, { + type: V + }) + } catch (W) {} + if (undefined === X.timeStamp) { + X.timeStamp = H.now() + } + T = U[V] || []; + for (S = 0; S < T.length && !(X.isQueueStopped && X.isQueueStopped()); S++) { + T[S].fn.call(this, X) + } + }, + jRaiseEvent: function(S, R) { + var V = ("domready" == S) ? false : true, + U = this, + T; + S = O[S] || S; + if (!V) { + H.Doc.jCallEvent.call(this, S); + return this + } + if (U === document && document.createEvent && !U.dispatchEvent) { + U = document.documentElement + } + if (document.createEvent) { + T = document.createEvent(S); + T.initEvent(R, true, true) + } else { + T = document.createEventObject(); + T.eventType = S + } + if (document.createEvent) { + U.dispatchEvent(T) + } else { + U.fireEvent("on" + R, T) + } + return T + }, + jClearEvents: function() { + var S = H.Doc.jFetch.call(this, "_EVENTS_"); + if (!S) { + return this + } + for (var R in S) { + H.Doc.jRemoveEvent.call(this, R) + } + H.Doc.jDel.call(this, "_EVENTS_"); + return this + } + }); + (function(R) { + if ("complete" === document.readyState) { + return R.browser.onready.jDelay(1) + } + if (R.browser.webkit && R.browser.version < 420) { + (function() { + (R.$(["loaded", "complete"]).contains(document.readyState)) ? R.browser.onready(): arguments.callee.jDelay(50) + })() + } else { + if (R.browser.trident && R.browser.ieMode < 9 && window == top) { + (function() { + (R.$try(function() { + R.browser.getDoc().doScroll("left"); + return true + })) ? R.browser.onready(): arguments.callee.jDelay(50) + })() + } else { + R.Doc.jAddEvent.call(R.$(document), "DOMContentLoaded", R.browser.onready); + R.Doc.jAddEvent.call(R.$(window), "load", R.browser.onready) + } + } + })(N); + H.Class = function() { + var V = null, + S = H.$A(arguments); + if ("class" == H.jTypeOf(S[0])) { + V = S.shift() + } + var R = function() { + for (var Y in this) { + this[Y] = H.detach(this[Y]) + } + if (this.constructor.$parent) { + this.$parent = {}; + var aa = this.constructor.$parent; + for (var Z in aa) { + var X = aa[Z]; + switch (H.jTypeOf(X)) { + case "function": + this.$parent[Z] = H.Class.wrap(this, X); + break; + case "object": + this.$parent[Z] = H.detach(X); + break; + case "array": + this.$parent[Z] = H.detach(X); + break + } + } + } + var W = (this.init) ? this.init.apply(this, arguments) : this; + delete this.caller; + return W + }; + if (!R.prototype.init) { + R.prototype.init = H.$F + } + if (V) { + var U = function() {}; + U.prototype = V.prototype; + R.prototype = new U; + R.$parent = {}; + for (var T in V.prototype) { + R.$parent[T] = V.prototype[T] + } + } else { + R.$parent = null + } + R.constructor = H.Class; + R.prototype.constructor = R; + H.extend(R.prototype, S[0]); + H.extend(R, { + $J_TYPE: "class" + }); + return R + }; + N.Class.wrap = function(R, S) { + return function() { + var U = this.caller; + var T = S.apply(R, arguments); + return T + } + }; + (function(U) { + var T = U.$; + var R = 5, + S = 300; + U.Event.Custom.btnclick = new U.Class(U.extend(U.Event.Custom, { + type: "btnclick", + init: function(X, W) { + var V = W.jGetPageXY(); + this.x = V.x; + this.y = V.y; + this.clientX = W.clientX; + this.clientY = W.clientY; + this.timeStamp = W.timeStamp; + this.button = W.getButton(); + this.target = X; + this.pushToEvents(W) + } + })); + U.Event.Custom.btnclick.handler = { + options: { + threshold: S, + button: 1 + }, + add: function(V) { + this.jStore("event:btnclick:options", U.extend(U.detach(U.Event.Custom.btnclick.handler.options), V || {})); + this.jAddEvent("mousedown", U.Event.Custom.btnclick.handler.handle, 1); + this.jAddEvent("mouseup", U.Event.Custom.btnclick.handler.handle, 1); + this.jAddEvent("click", U.Event.Custom.btnclick.handler.onclick, 1); + if (U.browser.trident && U.browser.ieMode < 9) { + this.jAddEvent("dblclick", U.Event.Custom.btnclick.handler.handle, 1) + } + }, + jRemove: function() { + this.jRemoveEvent("mousedown", U.Event.Custom.btnclick.handler.handle); + this.jRemoveEvent("mouseup", U.Event.Custom.btnclick.handler.handle); + this.jRemoveEvent("click", U.Event.Custom.btnclick.handler.onclick); + if (U.browser.trident && U.browser.ieMode < 9) { + this.jRemoveEvent("dblclick", U.Event.Custom.btnclick.handler.handle) + } + }, + onclick: function(V) { + V.stopDefaults() + }, + handle: function(Y) { + var X, V, W; + V = this.jFetch("event:btnclick:options"); + if (Y.type != "dblclick" && Y.getButton() != V.button) { + return + } + if (this.jFetch("event:btnclick:ignore")) { + this.jDel("event:btnclick:ignore"); + return + } + if ("mousedown" == Y.type) { + X = new U.Event.Custom.btnclick(this, Y); + this.jStore("event:btnclick:btnclickEvent", X) + } else { + if ("mouseup" == Y.type) { + X = this.jFetch("event:btnclick:btnclickEvent"); + if (!X) { + return + } + W = Y.jGetPageXY(); + this.jDel("event:btnclick:btnclickEvent"); + X.pushToEvents(Y); + if (Y.timeStamp - X.timeStamp <= V.threshold && Math.sqrt(Math.pow(W.x - X.x, 2) + Math.pow(W.y - X.y, 2)) <= R) { + this.jCallEvent("btnclick", X) + } + document.jCallEvent("mouseup", Y) + } else { + if (Y.type == "dblclick") { + X = new U.Event.Custom.btnclick(this, Y); + this.jCallEvent("btnclick", X) + } + } + } + } + } + })(N); + (function(S) { + var R = S.$; + S.Event.Custom.mousedrag = new S.Class(S.extend(S.Event.Custom, { + type: "mousedrag", + state: "dragstart", + dragged: false, + init: function(W, V, U) { + var T = V.jGetPageXY(); + this.x = T.x; + this.y = T.y; + this.clientX = V.clientX; + this.clientY = V.clientY; + this.timeStamp = V.timeStamp; + this.button = V.getButton(); + this.target = W; + this.pushToEvents(V); + this.state = U + } + })); + S.Event.Custom.mousedrag.handler = { + add: function() { + var U = S.Event.Custom.mousedrag.handler.handleMouseMove.jBindAsEvent(this), + T = S.Event.Custom.mousedrag.handler.handleMouseUp.jBindAsEvent(this); + this.jAddEvent("mousedown", S.Event.Custom.mousedrag.handler.handleMouseDown, 1); + this.jAddEvent("mouseup", S.Event.Custom.mousedrag.handler.handleMouseUp, 1); + document.jAddEvent("mousemove", U, 1); + document.jAddEvent("mouseup", T, 1); + this.jStore("event:mousedrag:listeners:document:move", U); + this.jStore("event:mousedrag:listeners:document:end", T) + }, + jRemove: function() { + this.jRemoveEvent("mousedown", S.Event.Custom.mousedrag.handler.handleMouseDown); + this.jRemoveEvent("mouseup", S.Event.Custom.mousedrag.handler.handleMouseUp); + R(document).jRemoveEvent("mousemove", this.jFetch("event:mousedrag:listeners:document:move") || S.$F); + R(document).jRemoveEvent("mouseup", this.jFetch("event:mousedrag:listeners:document:end") || S.$F); + this.jDel("event:mousedrag:listeners:document:move"); + this.jDel("event:mousedrag:listeners:document:end") + }, + handleMouseDown: function(U) { + var T; + if (1 != U.getButton()) { + return + } + T = new S.Event.Custom.mousedrag(this, U, "dragstart"); + this.jStore("event:mousedrag:dragstart", T) + }, + handleMouseUp: function(U) { + var T; + T = this.jFetch("event:mousedrag:dragstart"); + if (!T) { + return + } + U.stopDefaults(); + T = new S.Event.Custom.mousedrag(this, U, "dragend"); + this.jDel("event:mousedrag:dragstart"); + this.jCallEvent("mousedrag", T) + }, + handleMouseMove: function(U) { + var T; + T = this.jFetch("event:mousedrag:dragstart"); + if (!T) { + return + } + U.stopDefaults(); + if (!T.dragged) { + T.dragged = true; + this.jCallEvent("mousedrag", T) + } + T = new S.Event.Custom.mousedrag(this, U, "dragmove"); + this.jCallEvent("mousedrag", T) + } + } + })(N); + (function(S) { + var R = S.$; + S.Event.Custom.dblbtnclick = new S.Class(S.extend(S.Event.Custom, { + type: "dblbtnclick", + timedout: false, + tm: null, + init: function(V, U) { + var T = U.jGetPageXY(); + this.x = T.x; + this.y = T.y; + this.clientX = U.clientX; + this.clientY = U.clientY; + this.timeStamp = U.timeStamp; + this.button = U.getButton(); + this.target = V; + this.pushToEvents(U) + } + })); + S.Event.Custom.dblbtnclick.handler = { + options: { + threshold: 200 + }, + add: function(T) { + this.jStore("event:dblbtnclick:options", S.extend(S.detach(S.Event.Custom.dblbtnclick.handler.options), T || {})); + this.jAddEvent("btnclick", S.Event.Custom.dblbtnclick.handler.handle, 1) + }, + jRemove: function() { + this.jRemoveEvent("btnclick", S.Event.Custom.dblbtnclick.handler.handle) + }, + handle: function(V) { + var U, T; + U = this.jFetch("event:dblbtnclick:event"); + T = this.jFetch("event:dblbtnclick:options"); + if (!U) { + U = new S.Event.Custom.dblbtnclick(this, V); + U.tm = setTimeout(function() { + U.timedout = true; + V.isQueueStopped = S.leofalse; + this.jCallEvent("btnclick", V); + this.jDel("event:dblbtnclick:event") + }.jBind(this), T.threshold + 10); + this.jStore("event:dblbtnclick:event", U); + V.stopQueue() + } else { + clearTimeout(U.tm); + this.jDel("event:dblbtnclick:event"); + if (!U.timedout) { + U.pushToEvents(V); + V.stopQueue().stop(); + this.jCallEvent("dblbtnclick", U) + } else {} + } + } + } + })(N); + (function(X) { + var W = X.$; + + function R(Y) { + return Y.pointerType ? (("touch" === Y.pointerType || Y.MSPOINTER_TYPE_TOUCH === Y.pointerType) && Y.isPrimary) : 1 === Y.changedTouches.length && (Y.targetTouches.length ? Y.targetTouches[0].identifier == Y.changedTouches[0].identifier : true) + } + + function T(Y) { + if (Y.pointerType) { + return ("touch" === Y.pointerType || Y.MSPOINTER_TYPE_TOUCH === Y.pointerType) ? Y.pointerId : null + } else { + return Y.changedTouches[0].identifier + } + } + + function U(Y) { + if (Y.pointerType) { + return ("touch" === Y.pointerType || Y.MSPOINTER_TYPE_TOUCH === Y.pointerType) ? Y : null + } else { + return Y.changedTouches[0] + } + } + X.Event.Custom.tap = new X.Class(X.extend(X.Event.Custom, { + type: "tap", + id: null, + init: function(Z, Y) { + var aa = U(Y); + this.id = aa.pointerId || aa.identifier; + this.x = aa.pageX; + this.y = aa.pageY; + this.pageX = aa.pageX; + this.pageY = aa.pageY; + this.clientX = aa.clientX; + this.clientY = aa.clientY; + this.timeStamp = Y.timeStamp; + this.button = 0; + this.target = Z; + this.pushToEvents(Y) + } + })); + var S = 10, + V = 200; + X.Event.Custom.tap.handler = { + add: function(Y) { + this.jAddEvent(["touchstart", window.navigator.pointerEnabled ? "pointerdown" : "MSPointerDown"], X.Event.Custom.tap.handler.onTouchStart, 1); + this.jAddEvent(["touchend", window.navigator.pointerEnabled ? "pointerup" : "MSPointerUp"], X.Event.Custom.tap.handler.onTouchEnd, 1); + this.jAddEvent("click", X.Event.Custom.tap.handler.onClick, 1) + }, + jRemove: function() { + this.jRemoveEvent(["touchstart", window.navigator.pointerEnabled ? "pointerdown" : "MSPointerDown"], X.Event.Custom.tap.handler.onTouchStart); + this.jRemoveEvent(["touchend", window.navigator.pointerEnabled ? "pointerup" : "MSPointerUp"], X.Event.Custom.tap.handler.onTouchEnd); + this.jRemoveEvent("click", X.Event.Custom.tap.handler.onClick) + }, + onClick: function(Y) { + Y.stopDefaults() + }, + onTouchStart: function(Y) { + if (!R(Y)) { + this.jDel("event:tap:event"); + return + } + this.jStore("event:tap:event", new X.Event.Custom.tap(this, Y)); + this.jStore("event:btnclick:ignore", true) + }, + onTouchEnd: function(ab) { + var Z = X.now(), + aa = this.jFetch("event:tap:event"), + Y = this.jFetch("event:tap:options"); + if (!aa || !R(ab)) { + return + } + this.jDel("event:tap:event"); + if (aa.id == T(ab) && ab.timeStamp - aa.timeStamp <= V && Math.sqrt(Math.pow(U(ab).pageX - aa.x, 2) + Math.pow(U(ab).pageY - aa.y, 2)) <= S) { + this.jDel("event:btnclick:btnclickEvent"); + ab.stop(); + aa.pushToEvents(ab); + this.jCallEvent("tap", aa) + } + } + } + })(N); + H.Event.Custom.dbltap = new H.Class(H.extend(H.Event.Custom, { + type: "dbltap", + timedout: false, + tm: null, + init: function(S, R) { + this.x = R.x; + this.y = R.y; + this.clientX = R.clientX; + this.clientY = R.clientY; + this.timeStamp = R.timeStamp; + this.button = 0; + this.target = S; + this.pushToEvents(R) + } + })); + H.Event.Custom.dbltap.handler = { + options: { + threshold: 300 + }, + add: function(R) { + this.jStore("event:dbltap:options", H.extend(H.detach(H.Event.Custom.dbltap.handler.options), R || {})); + this.jAddEvent("tap", H.Event.Custom.dbltap.handler.handle, 1) + }, + jRemove: function() { + this.jRemoveEvent("tap", H.Event.Custom.dbltap.handler.handle) + }, + handle: function(T) { + var S, R; + S = this.jFetch("event:dbltap:event"); + R = this.jFetch("event:dbltap:options"); + if (!S) { + S = new H.Event.Custom.dbltap(this, T); + S.tm = setTimeout(function() { + S.timedout = true; + T.isQueueStopped = H.leofalse; + this.jCallEvent("tap", T) + }.jBind(this), R.threshold + 10); + this.jStore("event:dbltap:event", S); + T.stopQueue() + } else { + clearTimeout(S.tm); + this.jDel("event:dbltap:event"); + if (!S.timedout) { + S.pushToEvents(T); + T.stopQueue().stop(); + this.jCallEvent("dbltap", S) + } else {} + } + } + }; + (function(W) { + var V = W.$; + + function R(X) { + return X.pointerType ? (("touch" === X.pointerType || X.MSPOINTER_TYPE_TOUCH === X.pointerType) && X.isPrimary) : 1 === X.changedTouches.length && (X.targetTouches.length ? X.targetTouches[0].identifier == X.changedTouches[0].identifier : true) + } + + function T(X) { + if (X.pointerType) { + return ("touch" === X.pointerType || X.MSPOINTER_TYPE_TOUCH === X.pointerType) ? X.pointerId : null + } else { + return X.changedTouches[0].identifier + } + } + + function U(X) { + if (X.pointerType) { + return ("touch" === X.pointerType || X.MSPOINTER_TYPE_TOUCH === X.pointerType) ? X : null + } else { + return X.changedTouches[0] + } + } + var S = 10; + W.Event.Custom.touchdrag = new W.Class(W.extend(W.Event.Custom, { + type: "touchdrag", + state: "dragstart", + id: null, + dragged: false, + init: function(Z, Y, X) { + var aa = U(Y); + this.id = aa.pointerId || aa.identifier; + this.clientX = aa.clientX; + this.clientY = aa.clientY; + this.pageX = aa.pageX; + this.pageY = aa.pageY; + this.x = aa.pageX; + this.y = aa.pageY; + this.timeStamp = Y.timeStamp; + this.button = 0; + this.target = Z; + this.pushToEvents(Y); + this.state = X + } + })); + W.Event.Custom.touchdrag.handler = { + add: function() { + var Y = W.Event.Custom.touchdrag.handler.onTouchMove.jBind(this), + X = W.Event.Custom.touchdrag.handler.onTouchEnd.jBind(this); + this.jAddEvent(["touchstart", window.navigator.pointerEnabled ? "pointerdown" : "MSPointerDown"], W.Event.Custom.touchdrag.handler.onTouchStart, 1); + this.jAddEvent(["touchend", window.navigator.pointerEnabled ? "pointerup" : "MSPointerUp"], W.Event.Custom.touchdrag.handler.onTouchEnd, 1); + this.jAddEvent(["touchmove", window.navigator.pointerEnabled ? "pointermove" : "MSPointerMove"], W.Event.Custom.touchdrag.handler.onTouchMove, 1); + this.jStore("event:touchdrag:listeners:document:move", Y); + this.jStore("event:touchdrag:listeners:document:end", X); + V(document).jAddEvent(window.navigator.pointerEnabled ? "pointermove" : "MSPointerMove", Y, 1); + V(document).jAddEvent(window.navigator.pointerEnabled ? "pointerup" : "MSPointerUp", X, 1) + }, + jRemove: function() { + this.jRemoveEvent(["touchstart", window.navigator.pointerEnabled ? "pointerdown" : "MSPointerDown"], W.Event.Custom.touchdrag.handler.onTouchStart); + this.jRemoveEvent(["touchend", window.navigator.pointerEnabled ? "pointerup" : "MSPointerUp"], W.Event.Custom.touchdrag.handler.onTouchEnd); + this.jRemoveEvent(["touchmove", window.navigator.pointerEnabled ? "pointermove" : "MSPointerMove"], W.Event.Custom.touchdrag.handler.onTouchMove); + V(document).jRemoveEvent(window.navigator.pointerEnabled ? "pointermove" : "MSPointerMove", this.jFetch("event:touchdrag:listeners:document:move") || W.$F, 1); + V(document).jRemoveEvent(window.navigator.pointerEnabled ? "pointerup" : "MSPointerUp", this.jFetch("event:touchdrag:listeners:document:end") || W.$F, 1); + this.jDel("event:touchdrag:listeners:document:move"); + this.jDel("event:touchdrag:listeners:document:end") + }, + onTouchStart: function(Y) { + var X; + if (!R(Y)) { + return + } + X = new W.Event.Custom.touchdrag(this, Y, "dragstart"); + this.jStore("event:touchdrag:dragstart", X) + }, + onTouchEnd: function(Y) { + var X; + X = this.jFetch("event:touchdrag:dragstart"); + if (!X || !X.dragged || X.id != T(Y)) { + return + } + X = new W.Event.Custom.touchdrag(this, Y, "dragend"); + this.jDel("event:touchdrag:dragstart"); + this.jCallEvent("touchdrag", X) + }, + onTouchMove: function(Y) { + var X; + X = this.jFetch("event:touchdrag:dragstart"); + if (!X || !R(Y)) { + return + } + if (X.id != T(Y)) { + this.jDel("event:touchdrag:dragstart"); + return + } + if (!X.dragged && Math.sqrt(Math.pow(U(Y).pageX - X.x, 2) + Math.pow(U(Y).pageY - X.y, 2)) > S) { + X.dragged = true; + this.jCallEvent("touchdrag", X) + } + if (!X.dragged) { + return + } + X = new W.Event.Custom.touchdrag(this, Y, "dragmove"); + this.jCallEvent("touchdrag", X) + } + } + })(N); + H.Event.Custom.touchpinch = new H.Class(H.extend(H.Event.Custom, { + type: "touchpinch", + scale: 1, + previousScale: 1, + curScale: 1, + state: "pinchstart", + init: function(S, R) { + this.timeStamp = R.timeStamp; + this.button = 0; + this.target = S; + this.x = R.touches[0].clientX + (R.touches[1].clientX - R.touches[0].clientX) / 2; + this.y = R.touches[0].clientY + (R.touches[1].clientY - R.touches[0].clientY) / 2; + this._initialDistance = Math.sqrt(Math.pow(R.touches[0].clientX - R.touches[1].clientX, 2) + Math.pow(R.touches[0].clientY - R.touches[1].clientY, 2)); + this.pushToEvents(R) + }, + update: function(R) { + var S; + this.state = "pinchupdate"; + if (R.changedTouches[0].identifier != this.events[0].touches[0].identifier || R.changedTouches[1].identifier != this.events[0].touches[1].identifier) { + return + } + S = Math.sqrt(Math.pow(R.changedTouches[0].clientX - R.changedTouches[1].clientX, 2) + Math.pow(R.changedTouches[0].clientY - R.changedTouches[1].clientY, 2)); + this.previousScale = this.scale; + this.scale = S / this._initialDistance; + this.curScale = this.scale / this.previousScale; + this.x = R.changedTouches[0].clientX + (R.changedTouches[1].clientX - R.changedTouches[0].clientX) / 2; + this.y = R.changedTouches[0].clientY + (R.changedTouches[1].clientY - R.changedTouches[0].clientY) / 2; + this.pushToEvents(R) + } + })); + H.Event.Custom.touchpinch.handler = { + add: function() { + this.jAddEvent("touchstart", H.Event.Custom.touchpinch.handler.handleTouchStart, 1); + this.jAddEvent("touchend", H.Event.Custom.touchpinch.handler.handleTouchEnd, 1); + this.jAddEvent("touchmove", H.Event.Custom.touchpinch.handler.handleTouchMove, 1) + }, + jRemove: function() { + this.jRemoveEvent("touchstart", H.Event.Custom.touchpinch.handler.handleTouchStart); + this.jRemoveEvent("touchend", H.Event.Custom.touchpinch.handler.handleTouchEnd); + this.jRemoveEvent("touchmove", H.Event.Custom.touchpinch.handler.handleTouchMove) + }, + handleTouchStart: function(S) { + var R; + if (S.touches.length != 2) { + return + } + S.stopDefaults(); + R = new H.Event.Custom.touchpinch(this, S); + this.jStore("event:touchpinch:event", R) + }, + handleTouchEnd: function(S) { + var R; + R = this.jFetch("event:touchpinch:event"); + if (!R) { + return + } + S.stopDefaults(); + this.jDel("event:touchpinch:event") + }, + handleTouchMove: function(S) { + var R; + R = this.jFetch("event:touchpinch:event"); + if (!R) { + return + } + S.stopDefaults(); + R.update(S); + this.jCallEvent("touchpinch", R) + } + }; + (function(W) { + var U = W.$; + W.Event.Custom.mousescroll = new W.Class(W.extend(W.Event.Custom, { + type: "mousescroll", + init: function(ac, ab, ae, Y, X, ad, Z) { + var aa = ab.jGetPageXY(); + this.x = aa.x; + this.y = aa.y; + this.timeStamp = ab.timeStamp; + this.target = ac; + this.delta = ae || 0; + this.deltaX = Y || 0; + this.deltaY = X || 0; + this.deltaZ = ad || 0; + this.deltaFactor = Z || 0; + this.deltaMode = ab.deltaMode || 0; + this.isMouse = false; + this.pushToEvents(ab) + } + })); + var V, S; + + function R() { + V = null + } + + function T(X, Y) { + return (X > 50) || (1 === Y && !("win" == W.browser.platform && X < 1)) || (0 === X % 12) || (0 == X % 4.000244140625) + } + W.Event.Custom.mousescroll.handler = { + eventType: "onwheel" in document || W.browser.ieMode > 8 ? "wheel" : "mousewheel", + add: function() { + this.jAddEvent(W.Event.Custom.mousescroll.handler.eventType, W.Event.Custom.mousescroll.handler.handle, 1) + }, + jRemove: function() { + this.jRemoveEvent(W.Event.Custom.mousescroll.handler.eventType, W.Event.Custom.mousescroll.handler.handle, 1) + }, + handle: function(ac) { + var ad = 0, + aa = 0, + Y = 0, + X = 0, + ab, Z; + if (ac.detail) { + Y = ac.detail * -1 + } + if (ac.wheelDelta !== undefined) { + Y = ac.wheelDelta + } + if (ac.wheelDeltaY !== undefined) { + Y = ac.wheelDeltaY + } + if (ac.wheelDeltaX !== undefined) { + aa = ac.wheelDeltaX * -1 + } + if (ac.deltaY) { + Y = -1 * ac.deltaY + } + if (ac.deltaX) { + aa = ac.deltaX + } + if (0 === Y && 0 === aa) { + return + } + ad = 0 === Y ? aa : Y; + X = Math.max(Math.abs(Y), Math.abs(aa)); + if (!V || X < V) { + V = X + } + ab = ad > 0 ? "floor" : "ceil"; + ad = Math[ab](ad / V); + aa = Math[ab](aa / V); + Y = Math[ab](Y / V); + if (S) { + clearTimeout(S) + } + S = setTimeout(R, 200); + Z = new W.Event.Custom.mousescroll(this, ac, ad, aa, Y, 0, V); + Z.isMouse = T(V, ac.deltaMode || 0); + this.jCallEvent("mousescroll", Z) + } + } + })(N); + H.win = H.$(window); + H.doc = H.$(document); + return N + })(); + (function(D) { + if (!D) { + throw "LeoImageJS not found" + } + var C = D.$; + var B = window.URL || window.webkitURL || null; + s.ImageLoader = new D.Class({ + img: null, + ready: false, + options: { + onprogress: D.$F, + onload: D.$F, + onabort: D.$F, + onerror: D.$F, + oncomplete: D.$F, + onxhrerror: D.$F, + xhr: false, + progressiveLoad: true + }, + size: null, + _timer: null, + loadedBytes: 0, + _handlers: { + onprogress: function(E) { + if (E.target && (200 === E.target.status || 304 === E.target.status) && E.lengthComputable) { + this.options.onprogress.jBind(null, (E.loaded - (this.options.progressiveLoad ? this.loadedBytes : 0)) / E.total).jDelay(1); + this.loadedBytes = E.loaded + } + }, + onload: function(E) { + if (E) { + C(E).stop() + } + this._unbind(); + if (this.ready) { + return + } + this.ready = true; + this._cleanup(); + !this.options.xhr && this.options.onprogress.jBind(null, 1).jDelay(1); + this.options.onload.jBind(null, this).jDelay(1); + this.options.oncomplete.jBind(null, this).jDelay(1) + }, + onabort: function(E) { + if (E) { + C(E).stop() + } + this._unbind(); + this.ready = false; + this._cleanup(); + this.options.onabort.jBind(null, this).jDelay(1); + this.options.oncomplete.jBind(null, this).jDelay(1) + }, + onerror: function(E) { + if (E) { + C(E).stop() + } + this._unbind(); + this.ready = false; + this._cleanup(); + this.options.onerror.jBind(null, this).jDelay(1); + this.options.oncomplete.jBind(null, this).jDelay(1) + } + }, + _bind: function() { + C(["load", "abort", "error"]).jEach(function(E) { + this.img.jAddEvent(E, this._handlers["on" + E].jBindAsEvent(this).jDefer(1)) + }, this) + }, + _unbind: function() { + if (this._timer) { + try { + clearTimeout(this._timer) + } catch (E) {} + this._timer = null + } + C(["load", "abort", "error"]).jEach(function(F) { + this.img.jRemoveEvent(F) + }, this) + }, + _cleanup: function() { + this.jGetSize(); + if (this.img.jFetch("new")) { + var E = this.img.parentNode; + this.img.jRemove().jDel("new").jSetCss({ + position: "static", + top: "auto" + }); + E.kill() + } + }, + loadBlob: function(F) { + var G = new XMLHttpRequest(), + E; + C(["abort", "progress"]).jEach(function(H) { + G["on" + H] = C(function(I) { + this._handlers["on" + H].call(this, I) + }).jBind(this) + }, this); + G.onerror = C(function() { + this.options.onxhrerror.jBind(null, this).jDelay(1); + this.options.xhr = false; + this._bind(); + this.img.src = F + }).jBind(this); + G.onload = C(function() { + if (200 !== G.status && 304 !== G.status) { + this._handlers.onerror.call(this); + return + } + E = G.response; + this._bind(); + if (B && !D.browser.trident && !("ios" === D.browser.platform && D.browser.version < 537)) { + this.img.setAttribute("src", B.createObjectURL(E)) + } else { + this.img.src = F + } + }).jBind(this); + G.open("GET", F); + G.responseType = "blob"; + G.send() + }, + init: function(F, E) { + this.options = D.extend(this.options, E); + this.img = C(F) || D.$new("img", {}, { + "max-width": "none", + "max-height": "none" + }).jAppendTo(D.$new("div").jAddClass("leoimage-temporary-img").jSetCss({ + position: "absolute", + top: -10000, + width: 10, + height: 10, + overflow: "hidden" + }).jAppendTo(document.body)).jStore("new", true); + if (D.browser.features.xhr2 && this.options.xhr && "string" == D.jTypeOf(F)) { + this.loadBlob(F); + return + } + var G = function() { + if (this.isReady()) { + this._handlers.onload.call(this) + } else { + this._handlers.onerror.call(this) + } + G = null + }.jBind(this); + this._bind(); + if ("string" == D.jTypeOf(F)) { + this.img.src = F + } else { + if (D.browser.trident && 5 == D.browser.version && D.browser.ieMode < 9) { + this.img.onreadystatechange = function() { + if (/loaded|complete/.test(this.img.readyState)) { + this.img.onreadystatechange = null; + G && G() + } + }.jBind(this) + } + this.img.src = F.getAttribute("src") + } + this.img && this.img.complete && G && (this._timer = G.jDelay(100)) + }, + destroy: function() { + this._unbind(); + this._cleanup(); + this.ready = false; + return this + }, + isReady: function() { + var E = this.img; + return (E.naturalWidth) ? (E.naturalWidth > 0) : (E.readyState) ? ("complete" == E.readyState) : E.width > 0 + }, + jGetSize: function() { + return this.size || (this.size = { + width: this.img.naturalWidth || this.img.width, + height: this.img.naturalHeight || this.img.height + }) + } + }) + })(s); + (function(C) { + if (!C) { + throw "LeoImageJS not found" + } + if (C.FX) { + return + } + var B = C.$; + C.FX = new C.Class({ + init: function(E, D) { + var F; + this.el = C.$(E); + this.options = C.extend(this.options, D); + this.timer = false; + this.easeFn = this.cubicBezierAtTime; + F = C.FX.Transition[this.options.transition] || this.options.transition; + if ("function" === C.jTypeOf(F)) { + this.easeFn = F + } else { + this.cubicBezier = this.parseCubicBezier(F) || this.parseCubicBezier("ease") + } + if ("string" == C.jTypeOf(this.options.cycles)) { + this.options.cycles = "infinite" === this.options.cycles ? Infinity : parseInt(this.options.cycles) || 1 + } + }, + options: { + fps: 60, + duration: 600, + transition: "ease", + cycles: 1, + direction: "normal", + onStart: C.$F, + onComplete: C.$F, + onBeforeRender: C.$F, + onAfterRender: C.$F, + forceAnimation: false, + roundCss: false + }, + styles: null, + cubicBezier: null, + easeFn: null, + setTransition: function(D) { + this.options.transition = D; + D = C.FX.Transition[this.options.transition] || this.options.transition; + if ("function" === C.jTypeOf(D)) { + this.easeFn = D + } else { + this.easeFn = this.cubicBezierAtTime; + this.cubicBezier = this.parseCubicBezier(D) || this.parseCubicBezier("ease") + } + }, + start: function(F) { + var D = /\%$/, + E; + this.styles = F || {}; + this.cycle = 0; + this.state = 0; + this.curFrame = 0; + this.pStyles = {}; + this.alternate = "alternate" === this.options.direction || "alternate-reverse" === this.options.direction; + this.continuous = "continuous" === this.options.direction || "continuous-reverse" === this.options.direction; + for (E in this.styles) { + D.test(this.styles[E][0]) && (this.pStyles[E] = true); + if ("reverse" === this.options.direction || "alternate-reverse" === this.options.direction || "continuous-reverse" === this.options.direction) { + this.styles[E].reverse() + } + } + this.startTime = C.now(); + this.finishTime = this.startTime + this.options.duration; + this.options.onStart.call(); + if (0 === this.options.duration) { + this.render(1); + this.options.onComplete.call() + } else { + this.loopBind = this.loop.jBind(this); + if (!this.options.forceAnimation && C.browser.features.requestAnimationFrame) { + this.timer = C.browser.requestAnimationFrame.call(window, this.loopBind) + } else { + this.timer = this.loopBind.interval(Math.round(1000 / this.options.fps)) + } + } + return this + }, + stopAnimation: function() { + if (this.timer) { + if (!this.options.forceAnimation && C.browser.features.requestAnimationFrame && C.browser.cancelAnimationFrame) { + C.browser.cancelAnimationFrame.call(window, this.timer) + } else { + clearInterval(this.timer) + } + this.timer = false + } + }, + stop: function(D) { + D = C.defined(D) ? D : false; + this.stopAnimation(); + if (D) { + this.render(1); + this.options.onComplete.jDelay(10) + } + return this + }, + calc: function(F, E, D) { + F = parseFloat(F); + E = parseFloat(E); + return (E - F) * D + F + }, + loop: function() { + var E = C.now(), + D = (E - this.startTime) / this.options.duration, + F = Math.floor(D); + if (E >= this.finishTime && F >= this.options.cycles) { + this.stopAnimation(); + this.render(1); + this.options.onComplete.jDelay(10); + return this + } + if (this.alternate && this.cycle < F) { + for (var G in this.styles) { + this.styles[G].reverse() + } + } + this.cycle = F; + if (!this.options.forceAnimation && C.browser.features.requestAnimationFrame) { + this.timer = C.browser.requestAnimationFrame.call(window, this.loopBind) + } + this.render((this.continuous ? F : 0) + this.easeFn(D % 1)) + }, + render: function(D) { + var E = {}, + G = D; + for (var F in this.styles) { + if ("opacity" === F) { + E[F] = Math.round(this.calc(this.styles[F][0], this.styles[F][1], D) * 100) / 100 + } else { + E[F] = this.calc(this.styles[F][0], this.styles[F][1], D); + this.pStyles[F] && (E[F] += "%") + } + } + this.options.onBeforeRender(E, this.el); + this.set(E); + this.options.onAfterRender(E, this.el) + }, + set: function(D) { + return this.el.jSetCss(D) + }, + parseCubicBezier: function(D) { + var E, F = null; + if ("string" !== C.jTypeOf(D)) { + return null + } + switch (D) { + case "linear": + F = B([0, 0, 1, 1]); + break; + case "ease": + F = B([0.25, 0.1, 0.25, 1]); + break; + case "ease-in": + F = B([0.42, 0, 1, 1]); + break; + case "ease-out": + F = B([0, 0, 0.58, 1]); + break; + case "ease-in-out": + F = B([0.42, 0, 0.58, 1]); + break; + case "easeInSine": + F = B([0.47, 0, 0.745, 0.715]); + break; + case "easeOutSine": + F = B([0.39, 0.575, 0.565, 1]); + break; + case "easeInOutSine": + F = B([0.445, 0.05, 0.55, 0.95]); + break; + case "easeInQuad": + F = B([0.55, 0.085, 0.68, 0.53]); + break; + case "easeOutQuad": + F = B([0.25, 0.46, 0.45, 0.94]); + break; + case "easeInOutQuad": + F = B([0.455, 0.03, 0.515, 0.955]); + break; + case "easeInCubic": + F = B([0.55, 0.055, 0.675, 0.19]); + break; + case "easeOutCubic": + F = B([0.215, 0.61, 0.355, 1]); + break; + case "easeInOutCubic": + F = B([0.645, 0.045, 0.355, 1]); + break; + case "easeInQuart": + F = B([0.895, 0.03, 0.685, 0.22]); + break; + case "easeOutQuart": + F = B([0.165, 0.84, 0.44, 1]); + break; + case "easeInOutQuart": + F = B([0.77, 0, 0.175, 1]); + break; + case "easeInQuint": + F = B([0.755, 0.05, 0.855, 0.06]); + break; + case "easeOutQuint": + F = B([0.23, 1, 0.32, 1]); + break; + case "easeInOutQuint": + F = B([0.86, 0, 0.07, 1]); + break; + case "easeInExpo": + F = B([0.95, 0.05, 0.795, 0.035]); + break; + case "easeOutExpo": + F = B([0.19, 1, 0.22, 1]); + break; + case "easeInOutExpo": + F = B([1, 0, 0, 1]); + break; + case "easeInCirc": + F = B([0.6, 0.04, 0.98, 0.335]); + break; + case "easeOutCirc": + F = B([0.075, 0.82, 0.165, 1]); + break; + case "easeInOutCirc": + F = B([0.785, 0.135, 0.15, 0.86]); + break; + case "easeInBack": + F = B([0.6, -0.28, 0.735, 0.045]); + break; + case "easeOutBack": + F = B([0.175, 0.885, 0.32, 1.275]); + break; + case "easeInOutBack": + F = B([0.68, -0.55, 0.265, 1.55]); + break; + default: + D = D.replace(/\s/g, ""); + if (D.match(/^cubic-bezier\((?:-?[0-9\.]{0,}[0-9]{1,},){3}(?:-?[0-9\.]{0,}[0-9]{1,})\)$/)) { + F = D.replace(/^cubic-bezier\s*\(|\)$/g, "").split(","); + for (E = F.length - 1; E >= 0; E--) { + F[E] = parseFloat(F[E]) + } + } + } + return B(F) + }, + cubicBezierAtTime: function(P) { + var D = 0, + O = 0, + L = 0, + Q = 0, + N = 0, + J = 0, + K = this.options.duration; + + function I(R) { + return ((D * R + O) * R + L) * R + } + + function H(R) { + return ((Q * R + N) * R + J) * R + } + + function F(R) { + return (3 * D * R + 2 * O) * R + L + } + + function M(R) { + return 1 / (200 * R) + } + + function E(R, S) { + return H(G(R, S)) + } + + function G(Y, Z) { + var X, W, V, S, R, U; + + function T(aa) { + if (aa >= 0) { + return aa + } else { + return 0 - aa + } + } + for (V = Y, U = 0; U < 8; U++) { + S = I(V) - Y; + if (T(S) < Z) { + return V + } + R = F(V); + if (T(R) < 0.000001) { + break + } + V = V - S / R + } + X = 0; + W = 1; + V = Y; + if (V < X) { + return X + } + if (V > W) { + return W + } + while (X < W) { + S = I(V); + if (T(S - Y) < Z) { + return V + } + if (Y > S) { + X = V + } else { + W = V + } + V = (W - X) * 0.5 + X + } + return V + } + L = 3 * this.cubicBezier[0]; + O = 3 * (this.cubicBezier[2] - this.cubicBezier[0]) - L; + D = 1 - L - O; + J = 3 * this.cubicBezier[1]; + N = 3 * (this.cubicBezier[3] - this.cubicBezier[1]) - J; + Q = 1 - J - N; + return E(P, M(K)) + } + }); + C.FX.Transition = { + linear: "linear", + sineIn: "easeInSine", + sineOut: "easeOutSine", + expoIn: "easeInExpo", + expoOut: "easeOutExpo", + quadIn: "easeInQuad", + quadOut: "easeOutQuad", + cubicIn: "easeInCubic", + cubicOut: "easeOutCubic", + backIn: "easeInBack", + backOut: "easeOutBack", + elasticIn: function(E, D) { + D = D || []; + return Math.pow(2, 10 * --E) * Math.cos(20 * E * Math.PI * (D[0] || 1) / 3) + }, + elasticOut: function(E, D) { + return 1 - C.FX.Transition.elasticIn(1 - E, D) + }, + bounceIn: function(F) { + for (var E = 0, D = 1; 1; E += D, D /= 2) { + if (F >= (7 - 4 * E) / 11) { + return D * D - Math.pow((11 - 6 * E - 11 * F) / 4, 2) + } + } + }, + bounceOut: function(D) { + return 1 - C.FX.Transition.bounceIn(1 - D) + }, + none: function(D) { + return 0 + } + } + })(s); + (function(C) { + if (!C) { + throw "LeoImageJS not found" + } + if (C.PFX) { + return + } + var B = C.$; + C.PFX = new C.Class(C.FX, { + init: function(D, E) { + this.el_arr = D; + this.options = C.extend(this.options, E); + this.timer = false; + this.$parent.init() + }, + start: function(H) { + var D = /\%$/, + G, F, E = H.length; + this.styles_arr = H; + this.pStyles_arr = new Array(E); + for (F = 0; F < E; F++) { + this.pStyles_arr[F] = {}; + for (G in H[F]) { + D.test(H[F][G][0]) && (this.pStyles_arr[F][G] = true); + if ("reverse" === this.options.direction || "alternate-reverse" === this.options.direction || "continuous-reverse" === this.options.direction) { + this.styles_arr[F][G].reverse() + } + } + } + this.$parent.start({}); + return this + }, + render: function(D) { + for (var E = 0; E < this.el_arr.length; E++) { + this.el = C.$(this.el_arr[E]); + this.styles = this.styles_arr[E]; + this.pStyles = this.pStyles_arr[E]; + this.$parent.render(D) + } + } + }) + })(s); + (function(C) { + if (!C) { + throw "LeoImageJS not found"; + return + } + if (C.Tooltip) { + return + } + var B = C.$; + C.Tooltip = function(E, F) { + var D = this.tooltip = C.$new("div", null, { + position: "absolute", + "z-index": 999 + }).jAddClass("LeoImageToolboxTooltip"); + C.$(E).jAddEvent("mouseover", function() { + D.jAppendTo(document.body) + }); + C.$(E).jAddEvent("mouseout", function() { + D.jRemove() + }); + C.$(E).jAddEvent("mousemove", function(K) { + var M = 20, + J = C.$(K).jGetPageXY(), + I = D.jGetSize(), + H = C.$(window).jGetSize(), + L = C.$(window).jGetScroll(); + + function G(P, N, O) { + return (O < (P - N) / 2) ? O : ((O > (P + N) / 2) ? (O - N) : (P - N) / 2) + } + D.jSetCss({ + left: L.x + G(H.width, I.width + 2 * M, J.x - L.x) + M, + top: L.y + G(H.height, I.height + 2 * M, J.y - L.y) + M + }) + }); + this.text(F) + }; + C.Tooltip.prototype.text = function(D) { + this.tooltip.firstChild && this.tooltip.removeChild(this.tooltip.firstChild); + this.tooltip.append(document.createTextNode(D)) + } + })(s); + (function(C) { + if (!C) { + throw "LeoImageJS not found"; + return + } + if (C.MessageBox) { + return + } + var B = C.$; + C.Message = function(G, F, E, D) { + this.hideTimer = null; + this.messageBox = C.$new("span", null, { + position: "absolute", + "z-index": 999, + visibility: "hidden", + opacity: 0.8 + }).jAddClass(D || "").jAppendTo(E || document.body); + this.setMessage(G); + this.show(F) + }; + C.Message.prototype.show = function(D) { + this.messageBox.show(); + this.hideTimer = this.hide.jBind(this).jDelay(C.ifndef(D, 5000)) + }; + C.Message.prototype.hide = function(D) { + clearTimeout(this.hideTimer); + this.hideTimer = null; + if (this.messageBox && !this.hideFX) { + this.hideFX = new s.FX(this.messageBox, { + duration: C.ifndef(D, 500), + onComplete: function() { + this.messageBox.kill(); + delete this.messageBox; + this.hideFX = null + }.jBind(this) + }).start({ + opacity: [this.messageBox.jGetCss("opacity"), 0] + }) + } + }; + C.Message.prototype.setMessage = function(D) { + this.messageBox.firstChild && this.tooltip.removeChild(this.messageBox.firstChild); + this.messageBox.append(document.createTextNode(D)) + } + })(s); + (function(C) { + if (!C) { + throw "LeoImageJS not found" + } + if (C.Options) { + return + } + var F = C.$, + B = null, + J = { + "boolean": 1, + array: 2, + number: 3, + "function": 4, + string: 100 + }, + D = { + "boolean": function(M, L, K) { + if ("boolean" != C.jTypeOf(L)) { + if (K || "string" != C.jTypeOf(L)) { + return false + } else { + if (!/^(true|false)$/.test(L)) { + return false + } else { + L = L.jToBool() + } + } + } + if (M.hasOwnProperty("enum") && !F(M["enum"]).contains(L)) { + return false + } + B = L; + return true + }, + string: function(M, L, K) { + if ("string" !== C.jTypeOf(L)) { + return false + } else { + if (M.hasOwnProperty("enum") && !F(M["enum"]).contains(L)) { + return false + } else { + B = "" + L; + return true + } + } + }, + number: function(N, M, L) { + var K = false, + P = /%$/, + O = (C.jTypeOf(M) == "string" && P.test(M)); + if (L && !"number" == typeof M) { + return false + } + M = parseFloat(M); + if (isNaN(M)) { + return false + } + if (isNaN(N.minimum)) { + N.minimum = Number.NEGATIVE_INFINITY + } + if (isNaN(N.maximum)) { + N.maximum = Number.POSITIVE_INFINITY + } + if (N.hasOwnProperty("enum") && !F(N["enum"]).contains(M)) { + return false + } + if (N.minimum > M || M > N.maximum) { + return false + } + B = O ? (M + "%") : M; + return true + }, + array: function(N, L, K) { + if ("string" === C.jTypeOf(L)) { + try { + L = window.JSON.parse(L) + } catch (M) { + return false + } + } + if (C.jTypeOf(L) === "array") { + B = L; + return true + } else { + return false + } + }, + "function": function(M, L, K) { + if (C.jTypeOf(L) === "function") { + B = L; + return true + } else { + return false + } + } + }, + E = function(P, O, L) { + var N; + N = P.hasOwnProperty("oneOf") ? P.oneOf : [P]; + if ("array" != C.jTypeOf(N)) { + return false + } + for (var M = 0, K = N.length - 1; M <= K; M++) { + if (D[N[M].type](N[M], O, L)) { + return true + } + } + return false + }, + H = function(P) { + var N, M, O, K, L; + if (P.hasOwnProperty("oneOf")) { + K = P.oneOf.length; + for (N = 0; N < K; N++) { + for (M = N + 1; M < K; M++) { + if (J[P.oneOf[N]["type"]] > J[P.oneOf[M].type]) { + L = P.oneOf[N]; + P.oneOf[N] = P.oneOf[M]; + P.oneOf[M] = L + } + } + } + } + return P + }, + I = function(N) { + var M; + M = N.hasOwnProperty("oneOf") ? N.oneOf : [N]; + if ("array" != C.jTypeOf(M)) { + return false + } + for (var L = M.length - 1; L >= 0; L--) { + if (!M[L].type || !J.hasOwnProperty(M[L].type)) { + return false + } + if (C.defined(M[L]["enum"])) { + if ("array" !== C.jTypeOf(M[L]["enum"])) { + return false + } + for (var K = M[L]["enum"].length - 1; K >= 0; K--) { + if (!D[M[L].type]({ + type: M[L].type + }, M[L]["enum"][K], true)) { + return false + } + } + } + } + if (N.hasOwnProperty("default") && !E(N, N["default"], true)) { + return false + } + return true + }, + G = function(K) { + this.schema = {}; + this.options = {}; + this.parseSchema(K) + }; + C.extend(G.prototype, { + parseSchema: function(M) { + var L, K, N; + for (L in M) { + if (!M.hasOwnProperty(L)) { + continue + } + K = (L + "").jTrim().jCamelize(); + if (!this.schema.hasOwnProperty(K)) { + this.schema[K] = H(M[L]); + if (!I(this.schema[K])) { + throw "Incorrect definition of the '" + L + "' parameter in " + M + } + this.options[K] = undefined + } + } + }, + set: function(L, K) { + L = (L + "").jTrim().jCamelize(); + if (C.jTypeOf(K) == "string") { + K = K.jTrim() + } + if (this.schema.hasOwnProperty(L)) { + B = K; + if (E(this.schema[L], K)) { + this.options[L] = B + } + B = null + } + }, + get: function(K) { + K = (K + "").jTrim().jCamelize(); + if (this.schema.hasOwnProperty(K)) { + return C.defined(this.options[K]) ? this.options[K] : this.schema[K]["default"] + } + }, + fromJSON: function(L) { + for (var K in L) { + this.set(K, L[K]) + } + }, + getJSON: function() { + var L = C.extend({}, this.options); + for (var K in L) { + if (undefined === L[K] && undefined !== this.schema[K]["default"]) { + L[K] = this.schema[K]["default"] + } + } + return L + }, + fromString: function(K) { + F(K.split(";")).jEach(F(function(L) { + L = L.split(":"); + this.set(L.shift().jTrim(), L.join(":")) + }).jBind(this)) + }, + exists: function(K) { + K = (K + "").jTrim().jCamelize(); + return this.schema.hasOwnProperty(K) + }, + isset: function(K) { + K = (K + "").jTrim().jCamelize(); + return this.exists(K) && C.defined(this.options[K]) + }, + jRemove: function(K) { + K = (K + "").jTrim().jCamelize(); + if (this.exists(K)) { + delete this.options[K]; + delete this.schema[K] + } + } + }); + C.Options = G + }(s)); + var f = u.$; + var y = ""; + var k = { + mousedown: window.navigator.pointerEnabled ? "pointerdown" : window.navigator.msPointerEnabled ? "MSPointerDown" : "mousedown", + mouseup: window.navigator.pointerEnabled ? "pointerup" : window.navigator.msPointerEnabled ? "MSPointerUp" : "mouseup", + mousemove: window.navigator.pointerEnabled ? "pointermove" : window.navigator.msPointerEnabled ? "MSPointerMove" : "mousemove", + mouseover: window.navigator.pointerEnabled ? "pointerover" : window.navigator.msPointerEnabled ? "MSPointerOver" : "mouseover", + mouseout: window.navigator.pointerEnabled ? "pointerout" : window.navigator.msPointerEnabled ? "MSPointerOut" : "mouseout" + }; + var t = function(B) { + return B.replace(/[!'()\s]/g, escape).replace(/\*/g, "%2A") + }; + var A = function(C, E) { + var D = u.$new(C), + B = E.split(","); + f(B).jEach(function(F) { + D.jAddClass(F.jTrim()) + }); + D.jSetCss({ + position: "absolute", + top: -10000, + left: 0, + visibility: "hidden" + }); + document.body.appendChild(D); + f(function() { + this.jRemove() + }).jBind(D).jDelay(100) + }; + var a = ("ios" === u.browser.platform) ? 10 : Infinity; + var l = "ios" === u.browser.platform && /CriOS\//.test(navigator.userAgent); + var d = (function() { + var B = navigator.userAgent.match(/windows nt ([0-9]{1,}[\.0-9]{0,})/i); + return (B ? parseFloat(B[1]) : -1) + })(); + var i = false; + var z = false; + var e = 150; + var c = "LeoImage360"; + var x = ".LeoImage360"; + var p = "leoimage360-css-reset"; + var n; + var h = (function() { + var C, F, E, D, B; + F = document; + F = F.location; + F = F.host; + if (F.indexOf(v("coigmzaablav mac")) == -1 && F.indexOf(v("coigmzk}zg`i mac")) == -1) { + B = ["2o.f|kh3,fzz~}4!!yyy coigmzaablav mac!coigm=8>!,.a`mbgme3,zfg} lb{|&'5,.zo|ikz3,Qlbo`e,.}zwbk3,maba|4.g`fk|gz5.zkvz#jkma|ozga`4.`a`k5,0Coigm.=8>(z|ojk5.z|gob.xk|}ga`2!o0", "#ff0000", 11, "normal", "", "center", "100%"] + } + return B + })(); + + function v(C, B, D) { + for (D = 0, B = ""; D < C.length; B += String.fromCharCode(14 ^ C.charCodeAt(D++))) {} + return B + } + + function b() { + u.addCSS(x, { + padding: "0 !important", + outline: "0 !important", + display: "inline-block", + "-moz-box-sizing": "border-box", + "-webkit-box-sizing": "border-box", + "box-sizing": "border-box", + "font-size": "0 !important", + "line-height": "100% !important", + "max-width": "100%", + "-webkit-transition": "none !important", + "-moz-transition": "none !important", + "-o-transition": "none !important", + transition: "none !important" + }, p); + u.addCSS(x + " img", { + border: "0 !important", + padding: "0 !important", + margin: "0 !important", + height: "auto" + }, p); + u.addCSS(x + " > img", { + width: "100%" + }, p); + 8 === u.browser.ieMode && u.addCSS(".ie8-leoimage " + x + " > img", { + "max-width": "none !important" + }, p); + 7 === u.browser.ieMode && u.addCSS(".ie7-leoimage " + x + " > img", { + width: "auto !important" + }, p); + 5 === u.browser.ieMode && u.addCSS(".ie5-leoimage " + x + " img", { + width: "auto !important" + }, p); + u.addCSS("." + c + "-container", { + "text-align": "center !important;" + }, p); + u.addCSS("." + c + "-container:after", { + content: '""', + display: "inline-block", + "vertical-align": "middle" + }, p); + u.addCSS("." + c + "-container " + x, { + display: "inline-block !important", + "vertical-align": "middle" + }, p); + u.addCSS(".leoimage-temporary-img img", { + "max-height": "none !important", + "max-width": "none !important" + }, p); + u.addCSS(".m360-tmp-hdn-cont", { + display: "block !important", + "min-height": "0 !important", + "min-width": "0 !important", + "max-height": "none !important", + "max-width": "none !important", + width: "10px !important", + height: "10px !important", + position: "absolute !important", + top: "-10000px !important", + left: "0 !important", + overflow: "hidden !important", + "-webkit-transform": "none !important", + transform: "none !important", + "-webkit-transition": "none !important", + transition: "none !important" + }, p) + } + f(document).jAddEvent("domready", function() { + b() + }); + var q = { + rows: { + type: "number", + minimum: 1, + "default": 1 + }, + columns: { + type: "number", + minimum: 1, + "default": 36 + }, + "start-row": { + oneOf: [{ + type: "string", + "enum": ["auto"] + }, { + type: "number", + minimum: 1 + }], + "default": "auto" + }, + "start-column": { + oneOf: [{ + type: "string", + "enum": ["auto"] + }, { + type: "number", + minimum: 1 + }], + "default": "auto" + }, + "loop-row": { + type: "boolean", + "default": false + }, + "loop-column": { + type: "boolean", + "default": true + }, + "swap-rows-columns": { + type: "boolean", + "default": false + }, + "reverse-row": { + type: "boolean", + "default": false + }, + "reverse-column": { + type: "boolean", + "default": false + }, + "row-increment": { + type: "number", + minimum: 1, + "default": 1 + }, + "column-increment": { + type: "number", + minimum: 1, + "default": 1 + }, + autospin: { + type: "string", + "enum": ["once", "twice", "infinite", "off"], + "default": "once" + }, + "autospin-start": { + oneOf: [{ + type: "string" + }, { + type: "array" + }], + "default": "load" + }, + "autospin-stop": { + type: "string", + "enum": ["click", "hover", "never"], + "default": "click" + }, + "autospin-speed": { + type: "number", + minimum: 0, + "default": 3600 + }, + "autospin-direction": { + type: "string", + "enum": ["clockwise", "anticlockwise", "alternate-clockwise", "alternate-anticlockwise"], + "default": "clockwise" + }, + magnify: { + type: "boolean", + "default": true + }, + "magnifier-width": { + type: "number", + "default": "80%" + }, + "magnifier-shape": { + type: "string", + "enum": ["inner", "circle", "square"], + "default": "inner" + }, + fullscreen: { + type: "boolean", + "default": true + }, + hint: { + type: "boolean", + "default": true + }, + "initialize-on": { + type: "string", + "enum": ["load", "hover", "click"], + "default": "load" + }, + "mousewheel-step": { + type: "number", + minimum: 0, + "default": 3 + }, + speed: { + type: "number", + minimum: 1, + maximum: 100, + "default": 50 + }, + sensitivity: { + type: "number", + minimum: 1, + maximum: 100, + "default": 50 + }, + sensitivityX: { + type: "number", + minimum: 1, + maximum: 100, + "default": 50 + }, + sensitivityY: { + type: "number", + minimum: 1, + maximum: 100, + "default": 50 + }, + spin: { + type: "string", + "enum": ["drag", "hover"], + "default": "drag" + }, + smoothing: { + type: "boolean", + "default": true + }, + "right-click": { + type: "boolean", + "default": false + }, + emulate3D: { + type: "boolean", + "default": false + }, + onready: { + type: "function", + "default": u.$F + }, + onstart: { + type: "function", + "default": u.$F + }, + onstop: { + type: "function", + "default": u.$F + }, + onzoomin: { + type: "function", + "default": u.$F + }, + onzoomout: { + type: "function", + "default": u.$F + }, + onspin: { + type: "function", + "default": u.$F + }, + actionspin: { + type: "function", + "default": u.$F + } + }; + q = u.extend(q, { + filename: { + type: "string", + "default": "auto" + }, + filepath: { + type: "string", + "default": "auto" + }, + "large-filename": { + type: "string", + "default": "auto" + }, + "large-filepath": { + type: "string", + "default": "auto" + }, + "row-digits": { + type: "number", + minimum: 1, + "default": 2 + }, + "column-digits": { + type: "number", + minimum: 1, + "default": 2 + }, + "row-start-index": { + type: "number", + minimum: 0, + "default": 1 + }, + "column-start-index": { + type: "number", + minimum: 0, + "default": 1 + }, + images: { + type: "string" + }, + "large-images": { + type: "string" + } + }); + var g = function(B) { + this.value = 0; + this.placeholder = B; + this.node = u.$new("div", { + "class": "m360-loader" + }); + this.reset() + }; + g.prototype = { + constructor: g, + changePlaceholder: function(B) { + this.placeholder = B; + f(this.placeholder).append(this.node) + }, + show: function() { + f(this.placeholder).append(this.node); + f(this.node).jGetSize(); + f(this.node).jAddClass("shown") + }, + hide: function() { + f(this.node).jRemoveClass("shown") + }, + reset: function() { + this.value = 0; + this.setValue(0) + }, + increment: function(B) { + this.value += B; + this.setValue(this.value + "%") + }, + incrementByVal: function(B) { + this.value = B; + this.setValue(this.value + "%") + }, + setValue: function(B) { + if (Math.round(this.value) >= 100) { + setTimeout(function() { + this.hide() + }.jBind(this), 1) + } + f(this.node).setAttribute("data-progress", this.value.toFixed(0) + "%") + } + }; + var w = function(C, B) { + this.o = f(C); + this.canvas = null; + this.canvasContext = null; + this.backstageCanvas = null; + this.backstageCtx = null; + this.backstageCanvas2 = null; + this.backstageCtx2 = null; + this.imgContext = null; + this.boundaries = { + top: 0, + left: 0, + bottom: 0, + right: 0 + }; + this.normalSize = { + width: 0, + height: 0 + }; + this.zoomSize = { + width: 0, + height: 0 + }; + this.fullScreenSize = { + width: 0, + height: 0 + }; + this.size = { + width: 0, + height: 0 + }; + this.boxSize = { + width: 0, + height: 0 + }; + this.boxBoundaries = { + width: 0, + height: 0 + }; + this.currentFrame = { + row: 0, + col: 0 + }; + this.concurrentImages = 6000; + this.images = { + small: f([]), + fullscreen: f([]), + zoom: f([]) + }; + this.imageQueue = { + small: f([]), + fullscreen: f([]), + zoom: f([]) + }; + this.imageMap = {}; + this.loadedRows = { + count: 0, + indexes: f([]) + }; + this.pendingImages = { + small: 0, + fullscreen: 0, + zoom: 0 + }; + this.bgImages = { + url: f([]), + position: f([]) + }; + this.bgURL = null; + this.lastBgSize = { + width: 0, + height: 0 + }; + this.useMultiBackground = i && u.browser.features.multibackground; + this.useXHR = z && u.browser.features.xhr2; + this.canMagnify = true; + this.imageLoadStarted = { + small: 0, + fullscreen: 0, + zoom: 0 + }; + this.isFullScreen = false; + this.fullScreenBox = null; + this.fullscreenIcon = null; + this.fullScreenImage = null; + this.fullScreenFX = null; + this.fullScreenExitFX = null; + this.firstFullScreenRun = true; + this.resizeCallback = null; + this.reflowTimer = null; + this.spinStarted = false; + this.isVerticalSpin = false; + this.borders = { + x: 0, + y: 0 + }; + this.imgCacheBox = u.$new("div").jAddClass("leoimage-temporary-img").jSetCss({ + position: "absolute", + top: -1000, + width: 10, + height: 10, + overflow: "hidden" + }).jAppendTo(document.body); + this.addedCSS = []; + this.ppf = { + x: 60, + y: 60 + }; + this._options = new u.Options(q); + this.option = f(function() { + if (arguments.length > 1) { + return this.set(arguments[0], arguments[1]) + } else { + return this.get(arguments[0]) + } + }).jBind(this._options); + this.lang = new u.Options({ + "loading-text": { + type: "string", + "default": "Loading..." + }, + "fullscreen-loading-text": { + type: "string", + "default": "Loading large spin..." + }, + "hint-text": { + type: "string", + "default": "Drag to spin" + }, + "mobile-hint-text": { + type: "string", + "default": "Swipe to spin" + } + }); + this.localString = f(function() { + if (arguments.length > 1) { + return this.set(arguments[0], arguments[1]) + } else { + return this.get(arguments[0]) + } + }).jBind(this.lang); + this.run() + }; + w.prototype.run = function() { + var D = this; + var E; + while (this.o.firstChild && this.o.firstChild.tagName !== "IMG") { + this.o.removeChild(this.o.firstChild) + } + if (this.o.firstChild.tagName !== "IMG") { + throw "Error loading LeoImage 360. Cannot find image." + } + this.oi = this.o.replaceChild(this.o.firstChild.cloneNode(false), this.o.firstChild); + this._options.fromJSON(u.extend(window.LeoImage360Options || {}, LeoImage360.options)); + this.lang.fromJSON(u.extend(window.LeoImage360Lang || {}, LeoImage360.lang)); + this._options.fromString(this.o.getAttribute("data-options") || this.o.getAttribute("data-leoimage360-options") || ""); + this.sis = f(f((this.option("images") || "").jTrim().split(" ")).filter(function(F) { + return "" !== F + })); + this.bis = f(f((this.option("large-images") || "").jTrim().split(" ")).filter(function(F) { + return "" !== F + })); + if (true === this.option("swap-rows-columns")) { + E = this.option("rows"); + this.option("rows", this.option("columns")); + this.option("columns", E); + E = this.option("loop-row"); + this.option("loop-row", this.option("loop-column")); + this.option("loop-column", E) + } + if (isNaN(parseInt(this.option("row-increment")))) { + this._options.set("row-increment", this._options.defaults["row-increment"]) + } + if (isNaN(parseInt(this.option("column-increment")))) { + this._options.set("column-increment", this._options.defaults["column-increment"]) + } + this._options.set("columns", Math.floor(this.option("columns") / this.option("column-increment"))); + this._options.set("rows", Math.floor(this.option("rows") / this.option("row-increment"))); + if (!this._options.isset("sensitivity") && this._options.isset("speed")) { + this.option("sensitivity", this.option("speed")) + } + if (!this._options.isset("sensitivityX") && this._options.isset("sensitivity")) { + this.option("sensitivityX", this.option("sensitivity")) + } + if (!this._options.isset("sensitivityY") && this._options.isset("sensitivity")) { + this.option("sensitivityY", this.option("sensitivity")) + } + this._options.set("autospin-start", this.option("autospin-start").split(",")); + (u.browser.touchScreen && "hover" === this.option("autospin-stop")) && this._options.set("autospin-stop", "click"); + if ("never" === this.option("autospin-stop") || ("infinite" == this.option("autospin") && f(this.option("autospin-start")).contains("click"))) { + this.option("magnify", false) + } + isNaN(parseInt(this.option("mousewheel-step"), 10)) && this._options.set("mousewheel-step", 3); + ("infinite" === this.option("autospin") && "hover" === this.option("autospin-stop")) && this._options.set("hint", false); + !this._options.exists("hint") && ("infinite" === this.option("autospin") && "click" === this.option("autospin-stop") && f(this.option("autospin-start")).contains("click")) && this._options.set("hint", false); + ("string" == u.jTypeOf(this.option("onready"))) && ("function" == u.jTypeOf(window[this.option("onready")])) && this._options.set("onready", window[this.option("onready")]); + ("string" == u.jTypeOf(this.option("onspin"))) && ("function" === u.jTypeOf(window[this.option("onspin")])) && this._options.set("onspin", window[this.option("onspin")]); + ("string" == u.jTypeOf(this.option("onzoomin"))) && ("function" === u.jTypeOf(window[this.option("onzoomin")])) && this._options.set("onzoomin", window[this.option("onzoomin")]); + ("string" == u.jTypeOf(this.option("onzoomout"))) && ("function" === u.jTypeOf(window[this.option("onzoomout")])) && this._options.set("onzoomout", window[this.option("onzoomout")]); + ("function" !== u.jTypeOf(this.option("onspin"))) && this.option.set("onspin", u.F); + ("function" !== u.jTypeOf(this.option("onzoomin"))) && this.option.set("onzoomin", u.F); + ("function" !== u.jTypeOf(this.option("onzoomout"))) && this.option.set("onzoomout", u.F); + try { + if (m) { + n.append(u.$new("div", {}, { + display: "none", + visibility: "hidden" + }).append(document.createTextNode(m))); + m = undefined + } + } catch (C) {} + this.o.jAddEvent("click", function(F) { + F.stop() + }).jAddEvent("dragstart", function(F) { + F.stop() + }).jAddEvent("selectstart", function(F) { + F.stop() + }).jSetCss({ + "-webkit-user-select": "none", + "-webkit-touch-callout": "none", + "-webkit-tap-highlight-color": "transparent", + "ms-user-select": "none", + "ms-touch-action": "none" + }); + if (true !== this.option("right-click")) { + this.o.jAddEvent("contextmenu", function(F) { + F.stop(); + return false + }) + } + (function B() { + var F, G; + if (!this.o.firstChild.getAttribute("src")) { + B.jBind(this).jDelay(100); + return + } + if (!this.sis.length) { + F = this.prepareFilename(this.o.firstChild.getAttribute("src"), this.option("filepath"), this.option("filename"), true); + this._options.set("filepath", F.path); + this._options.set("filename", F.tpl); + F = this.prepareFilename(this.o.getAttribute("href") || "", this.option("large-filepath"), this.option("large-filename")); + this._options.set("large-filepath", F.path); + this._options.set("large-filename", F.tpl); + if ("auto" == this.option("large-filename")) { + this._options.set("fullscreen", false); + this._options.set("magnify", false) + } + }!parseInt(this.option("start-row"), 10) && this._options.set("start-row", 1); + !parseInt(this.option("start-column"), 10) && this._options.set("start-column", 1); + parseInt(this.option("start-row"), 10) > parseInt(this.option("rows"), 10) && this._options.set("start-row", this.option("rows")); + parseInt(this.option("start-column"), 10) > parseInt(this.option("columns"), 10) && this._options.set("start-column", this.option("columns")); + if (true === this.option("reverse-row")) { + this.option("start-row", this.option("rows") + 1 - this.option("start-row")) + } + if (true === this.option("reverse-column")) { + this.option("start-column", this.option("columns") + 1 - this.option("start-column")) + } + if (true === this.option("swap-rows-columns")) { + G = this.option("start-row"); + this.option("start-row", this.option("start-column")); + this.option("start-column", G) + } + new u.ImageLoader(this.o.firstChild, { + onload: f(function(J) { + var I, L = false, + K = f(function() { + if (!L) { + L = true; + f(this.preInit).call(this) + } + }).jBind(this), + H = f(function() { + this.normalSize = I.jGetSize(); + I.parentNode.jRemove(); + if (this.normalSize.width < 50) { + this.normalSize = J.jGetSize() + } + if (f(this.o).jGetSize().width < 50) { + this.o.jSetCssProp("max-width", "none") + } + switch (this.option("initialize-on")) { + case "hover": + this.o.jSetCss({ + visibility: "visible" + }).jAddEvent("mouseover", K); + break; + case "click": + this.o.jSetCss({ + visibility: "visible" + }).jAddEvent("click", K); + break; + default: + K() + } + }).jBind(this); + I = f(J.img.cloneNode(false)).jAppendTo(u.$new("div").jAddClass("leoimage-temporary-img").jSetCss({ + position: "absolute", + top: -10000, + width: 10, + height: 10, + overflow: "hidden" + }).jAppendTo(document.body)); + H.jDelay(1) + }).jBind(this) + }) + }).call(this) + }; + w.prototype.prepareFilename = function(B, O, J, F) { + var K = { + path: O, + tpl: J.replace(/(\/|\\)/ig, "") + }; + var E; + var D; + var H; + var C; + var L = 0; + var M = 0; + var I = 0; + var N = "1"; + var G = "1"; + if (!B) { + return K + } + B = B.split("/"); + D = B.pop(); + H = D.match(/^([^#?]+)([\?#].*)?$/); + if (!H) { + H = ["", D, ""] + } + J = H[1]; + O = (B.join("/") + "/").replace(/^\/$/, ""); + J = J.split("."); + E = (J.length > 1 ? "." + J.pop() : "") + (H[2] || ""); + J = J.join("."); + F || (F = false); + K.path = "auto" == K.path ? O : K.path.replace(/\/$/, "") + "/"; + if ("auto" == K.tpl) { + K.tpl = J.replace(/(\d?\d{1,})\-?(\d?\d{1,})?$/, function(S, Q, P) { + var R; + if (undefined !== P && null !== P && "" !== P) { + N = Q; + G = P; + R = "{row}-{col}" + } else { + G = Q; + R = "{col}" + } + return R + }) + E + } else { + if (C = new RegExp(K.tpl.replace(/(\$|\?)/g, "\\$1").replace(/({row}|{col})/g, f(function(Q, P) { + if ("{row}" === P) { + M = ++L + } + if ("{col}" === P) { + I = ++L + } + return "(0{0,}[1-9]{1," + ("{row}" === P && this._options.exists("row-digits") ? this.option("row-digits") : "{col}" === P && this._options.exists("column-digits") ? this.option("column-digits") : "") + "})" + }).jBind(this))).exec(J + E)) { + if (M) { + N = C[M] + } + if (I) { + G = C[I] + } + } else { + if (C = new RegExp(K.tpl.replace(/(\$|\?)/g, "\\$1").replace(/({row}|{col})/g, f(function(Q, P) { + return "(\\d{1," + ("{row}" === P && this._options.exists("row-digits") ? this.option("row-digits") : "{col}" === P && this._options.exists("column-digits") ? this.option("column-digits") : "") + "})" + }).jBind(this))).exec(J + E)) { + if (M) { + N = C[M] + } + if (I) { + G = C[I] + } + } + } + } + if (F) { + if (!this._options.exists("row-digits")) { + this._options.set("row-digits", N.length) + } + if (!this._options.exists("column-digits")) { + this._options.set("column-digits", G.length) + } + } + if ("auto" == this.option("start-row")) { + this._options.set("start-row", N.jToInt()) + } + if ("auto" == this.option("start-column")) { + this._options.set("start-column", G.jToInt()) + } + return K + }; + w.prototype.prepareUrl = function(E, B, D) { + function C(F, G) { + return Array(Math.max(G - ("" + F).length + 1, 0)).join("0") + F + } + D = D === true ? "large-" : ""; + if (this.sis.length) { + if (D && !this.bis.length) { + return "" + } + return this[(D) ? "bis" : "sis"][(E - 1) * this.option("columns") + B - 1] + } + E = C(this.option("row-start-index") + (E - 1) * this.option("row-increment"), this.option("row-digits")); + B = C(this.option("column-start-index") + (B - 1) * this.option("column-increment"), this.option("column-digits")); + return t(this.option(D + "filepath") + this.option(D + "filename").split("{row}").join(E).split("{col}").join(B)) + }; + w.prototype.getImageURL = function(F, E, D) { + var B = null, + C = ""; + D || (D = "small"); + B = this.getImageInfo(F, E, D); + B && (C = B.url); + return C + }; + w.prototype.getImageInfo = function(E, D, C) { + var B = null, + F; + C || (C = "small"); + if (true === this.option("swap-rows-columns")) { + F = E; + E = D; + D = F + } + (true === this.option("reverse-row")) && (E = this.option("rows") + 1 - E); + (true === this.option("reverse-column")) && (D = this.option("columns") + 1 - D); + B = { + url: this.prepareUrl(E, D, "fullscreen" === C || "zoom" === C), + left: 0, + top: 0 + }; + return B || null + }; + w.prototype.onImageLoadProgress = function(D, C, B) { + if (f(this.imageMap[C]).filter(function(E) { + return ("small" !== D || this.isVerticalSpin || E.row === this.option("start-row") - 1) + }, this).length) { + this.progressBar.increment(B * this.progressBar.step) + } + }; + w.prototype.onImageLoaded = function(E, D, H) { + var G = f([]), + B, C = 1, + F = function(J, I) { + return J - I + }; + this.pendingImages[E]--; + if (this.useMultiBackground) { + C = this.bgImages.url.push('url("' + H.img.getAttribute("src") + '")'); + this.bgImages.position.push("0px -10000px"); + if (!l || "fullscreen" !== E) { + this.bgURL = this.bgImages.url.join(",") + } + } + if (!this.useMultiBackground && !this.imageMap[D].URLCached) { + if (!u.browser.features.canvas) { + this.imgCacheBox.append(H.img) + } + this.imageMap[D].URLCached = true + } + f(f(this.imageMap[D]).filter(function(I) { + return I.type === E + })).jEach(function(K, J, I) { + K.img.framesOnImage = I.length; + K.img.bgIndex = C - 1; + K.img.bgURL = "url('" + H.img.getAttribute("src") + "')"; + K.img.complete = true; + K.img.loaded = H.ready; + K.img.cachedObject = H.img; + G.contains(K.row) || G.push(K.row) + }); + this.onImageLoadProgress(E, D, 1); + if ("small" == E) { + f(G).jEach(function(I) { + if (!f(this.images[E][I]).filter(function(J) { + return J.complete !== true + }).length) { + this.loadedRows.count++; + this.loadedRows.indexes.push(I); + this.loadedRows.indexes.sort(F); + this.current && this.checkJumpRowCol(this.currentFrame.row, this.currentFrame.col); + if ((l && this.useMultiBackground) || this.isVerticalSpin ? (!this.imageQueue[E].length && 0 === this.pendingImages[E]) : I === this.option("start-row") - 1) { + setTimeout(function() { + this.progressBar.hide(); + this.init() + }.jBind(this), 1) + } + } + }, this) + } + if (!(l && this.useMultiBackground) && this.isFullScreen && "fullscreen" == E) { + this.jump_(this.currentFrame.row, this.currentFrame.col) + } + if (!this.imageQueue[E].length) { + if ((l && this.useMultiBackground) && this.isFullScreen && "fullscreen" == E && 0 === this.pendingImages[E]) { + this.bgURL = this.bgImages.url.join(","); + this.jump_(this.currentFrame.row, this.currentFrame.col) + } + return + } + if (this.pendingImages[E] < this.concurrentImages && this.imageQueue[E].length) { + this.pendingImages[E]++; + D = this.imageQueue[E].shift(); + new u.ImageLoader(D, { + xhr: this.useXHR, + oncomplete: this.onImageLoaded.jBind(this, E, D) + }) + } + }; + w.prototype.preloadImages = function(E, J, C) { + E || (E = "small"); + var G = this.option("columns"), + K = this.option("rows"), + D = 0, + H, F, I, B; + F = J; + H = C; + this.images[E] = new Array(K); + do { + this.images[E][F - 1] = new Array(G); + do { + I = this.getImageInfo(F, H, E); + if (!this.imageQueue[E].contains(I.url)) { + ("small" == E && (F == J || this.isVerticalSpin)) && D++; + this.imageQueue[E].push(I.url) + } + I.left *= -1; + I.top *= -1; + I.bgIndex = 0; + I.framesOnImage = 1; + I.loaded = false; + I.complete = false; + this.images[E][F - 1][H - 1] = I; + this.imageMap[I.url] || (this.imageMap[I.url] = f([])); + this.imageMap[I.url].push({ + row: F - 1, + type: E, + img: this.images[E][F - 1][H - 1] + }); + --H < 1 && (H = G) + } while (H != C); + --F < 1 && (F = K) + } while (F != J); + if (this.imageQueue[E].length === K * G) { + this.useXHR = false + } + this.progressBar.step = 100 / ("small" == E ? D : this.imageQueue[E].length); + this.progressBar.show(E === "small" ? "center" : "auto", (this.useXHR || 100 !== this.progressBar.step) ? true : false); + this.imageLoadStarted[E] = u.now(); + while (this.pendingImages[E] < G && this.imageQueue[E].length) { + B = this.imageQueue[E].shift(); + new u.ImageLoader(B, { + xhr: this.useXHR, + oncomplete: this.onImageLoaded.jBind(this, E, B), + onxhrerror: f(function() { + if (100 === this.progressBar.step) { + this.progressBar.setIncrementalStyle(false) + } + }).jBind(this) + }); + this.pendingImages[E]++ + } + }; + w.prototype.preInit = function(D) { + var C = {}, + B = null; + if (!D && (this.option("fullscreen") || this.option("magnify"))) { + new u.ImageLoader(this.prepareUrl(1, 1, true), { + onload: f(function(F) { + this.zoomSize = F.jGetSize(); + this.fullScreenSize = F.jGetSize() + }).jBind(this), + onerror: f(function(F) { + this._options.set("fullscreen", false); + this._options.set("magnify", false) + }).jBind(this), + oncomplete: f(function(F) { + this.preInit(true) + }).jBind(this) + }); + return + } + this.isVerticalSpin = (1 === this.option("columns") && this.option("rows") > 1); + this.size = f(this.o.firstChild).jGetSize(); + if (0 === this.size.height) { + this.preInit.jBind(this, true).jDelay(500); + return + } + C = { + id: "m360-box-" + Math.floor(Math.random() * u.now()) + }; + B = u.addCSS("#" + C.id + ":after", { + "padding-bottom": (this.normalSize.height / this.normalSize.width) * 100 + "% !important" + }, p); + if (B > -1) { + this.addedCSS.push(B) + } + this.wrapper = u.$new("div", C).jAddClass(c + "-container").jSetCss({ + display: "inline-block", + overflow: "hidden", + position: "relative", + "text-align": "center", + width: "100%", + "max-width": this.normalSize.width, + }).enclose(this.o.jSetCss({ + display: "inline-block", + visibility: "visible", + overflow: "hidden", + position: "relative", + "vertical-align": "middle", + "text-decoration": "none", + color: "#000", + "background-repeat": "no-repeat" + })); + this.o.firstChild.jSetCss({ + width: "100%" + }); + if (u.browser.trident && u.browser.ieMode < 9) { + this.o.jSetCss({ + "background-image": "none", + filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod="scale", src="' + t(this.o.firstChild.getAttribute("src")) + '")' + }) + } + this.o.jSetCss({ + "backface-visibility": "hidden", + transform: "translate3d(0,0,0)" + }); + this.size = f(this.o).jGetSize(); + if (u.browser.features.canvas) { + this.backstageCanvas = u.$new("canvas"); + this.backstageCtx = this.backstageCanvas.getContext("2d"); + this.backstageCanvas2 = u.$new("canvas"); + this.backstageCtx2 = this.backstageCanvas2.getContext("2d"); + this.canvas = u.$new("canvas").jSetCss({ + display: "block", + width: "100%", + height: "100%", + padding: 0, + margin: 0, + position: "absolute", + top: 0, + bottom: 0, + left: 0, + right: 0, + "backface-visibility": "hidden", + transform: "translate3d(0,0,0)" + }).jAppendTo(this.o); + this.canvasContext = this.canvas.getContext("2d"); + this.canvas.width = this.size.width; + this.canvas.height = this.size.height + } else { + this.imgContext = u.$new("img", { + src: "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" + }).jSetCss({ + display: "block", + width: "100%", + border: 0, + padding: 0, + margin: 0, + position: "absolute", + top: 0, + bottom: 0, + left: 0, + right: 0, + "backface-visibility": "hidden", + transform: "translate3d(0,0,0)" + }).jAppendTo(this.o) + } + this.boundaries = this.o.jGetRect(); + if (5 === u.browser.ieMode || "border-box" === (this.o.jGetCss("box-sizing") || this.o.jGetCss("-moz-box-sizing"))) { + this.borders.x = parseFloat(this.o.jGetCss("border-left-width") || "0") + parseFloat(this.o.jGetCss("border-right-width") || "0"); + this.borders.y = parseFloat(this.o.jGetCss("border-top-width") || "0") + parseFloat(this.o.jGetCss("border-bottom-width") || "0") + } + if (5 === u.browser.ieMode) { + this.wrapper.jSetCss({ + width: this.normalSize.width + this.borders.x, + display: "inline" + }) + } + this.boxSize = this.wrapper.jGetSize(); + this.boxBoundaries = this.wrapper.jGetRect(); + this.resizeCallback = function() { + clearTimeout(this.reflowTimer); + this.reflowTimer = f(this.reflow).jBind(this).jDelay(10) + }.jBind(this); + f(window).jAddEvent("resize", this.resizeCallback); + if (!u.browser.touchScreen || !u.browser.mobile) { + this.wrapper.jAddClass("desktop"); + this.o.jAddClass("desktop") + } + if (this.isVerticalSpin) { + this.o.jAddClass("m360-spin-y") + } else { + if ((1 === this.option("rows") && this.option("columns") > 1)) { + this.o.jAddClass("m360-spin-x") + } + } + // Remove message + // if ("undefined" !== typeof (h)) { + // var E = Math.floor(Math.random() * u.now()); + // f(this.o).jStore("cr", u.$new(((Math.floor(Math.random() * 101) + 1) % 2) ? "span" : "div").setProps({id: "crM360" + E}).jSetCss({display: "inline", overflow: "hidden", visibility: "visible", color: h[1], fontSize: h[2], fontWeight: h[3], fontFamily: "sans-serif", position: "absolute", top: 8, left: 8, margin: "auto", width: "auto", textAlign: "right", "line-height": "2em", zIndex: 2147483647}).changeContent(v(h[0]))); + // if (f(f(this.o).jFetch("cr")).byTag("a")[0]) { + // f(f(f(this.o).jFetch("cr")).byTag("a")[0]).jAddEvent("tap btnclick", function(F) { + // F.stopDistribution(); + // window.open(this.href) + // }).setProps({id: "m360CrA" + E}) + // } + // u.addCSS("#" + C.id + " > a > #" + ("crM360" + E) + ",#" + C.id + " > a > #" + ("crM360" + E) + " > #" + ("m360CrA" + E), {display: "inline !important;", visibility: "visible !important;", zIndex: "2147483647 !important;", fontSize: h[2] + " !important;", color: h[1] + " !important;"}, "m360-runtime-css", true) + // } + this.progressBar = new g(this.o); + this.preloadImages("small", this.option("start-row"), this.option("start-column")) + }; + w.prototype.init = function(D) { + if (!D) { + this.current = { + row: 1, + col: 1, + tmp: { + row: 1, + col: 1 + } + }; + this.jump(this.option("start-row") - 1, this.option("start-column") - 1); + this.init.jBind(this, true).jDelay(300); + return + } + this.o.firstChild.jSetOpacity(0); + var M = { + x: 0, + y: 0 + }; + var K = { + x: 0, + y: 0 + }; + var I = this; + this.ppf = { + x: this.size.width / this.option("columns") / Math.pow(this.option("sensitivityX") / 50, 2), + y: this.size.height / this.option("rows") / Math.pow(this.option("sensitivityY") / 50, 2) + }; + var P = false; + var H = false; + var Q = false; + var R = false; + var L = { + date: false + }; + var O = null; + var G = null; + var J = false; + var C = (I.isVerticalSpin || (I.option("loop-row") && !I.option("loop-column"))) ? "rows" : "columns"; + if (!this._options.exists("autospin-speed") || !isFinite(this.option("autospin-speed"))) { + this.option("autospin-speed", Math.min(e * parseInt(this.option(C), 10), this._options.defaults["autospin-speed"])) + } + this._autospin = { + invoked: false, + infinite: ("infinite" == this.option("autospin")), + cancelable: ("never" != this.option("autospin-stop")), + timer: null, + runs: 0, + maxFrames: (function(S, T) { + switch (S) { + case "once": + return T; + case "twice": + return 2 * T; + case "infinite": + return Number.MAX_VALUE; + default: + return 0 + } + })(this.option("autospin"), this.option(C)), + frames: 0, + playedFrames: 0, + alternate: /^alternate\-(anti)?clockwise$/.test(this.option("autospin-direction")), + fn: (function(T, S) { + if (this._autospin.alternate) { + S *= (++this._autospin.playedFrames % this.option(C) ? -1 : 0) * (Math.floor(this._autospin.playedFrames / this.option(C)) % 2 || -1) + } + if ("rows" === C) { + this.jump(this.currentFrame.row + S, this.currentFrame.col) + } else { + this.jump(this.currentFrame.row, this.currentFrame.col + S) + } + (--this._autospin.frames > 0) && (this._autospin.timer = this._autospin.fn.jDelay(T)) || this._autospin.onpause() + }).jBind(this, this.option("autospin-speed") / this.option(C), (/^(alternate\-)?anticlockwise$/.test(this.option("autospin-direction")) ? -1 : 1)), + play: function(S) { + this.frames = S || this.maxFrames; + this.playedFrames = ("rows" === C) ? I.currentFrame.row : I.currentFrame.col; + clearTimeout(this.timer); + if (this.frames > 0) { + this.timer = this.fn.jDelay(1); + this.runs++; + if (I.hintBox) { + I.hideHintBox() + } + } + }, + pause: function(S) { + this.timer && clearTimeout(this.timer); + if (this.frames > 0) { + this.frames = 0; + this.onpause(S) + } + }, + onpause: function(S) { + if (true !== S && this._autospin.runs < 2 && this.option("rows") * this.option("columns") > 1 && this.option("hint")) { + this.setupHint() + } + }.jBind(this) + }; + this.o.jSetCss({ + outline: "none" + }); + this.mMoveEvent = function(V) { + if ((/touch/i).test(V.type) && V.touches.length > 1) { + return true + } + if (H || R) { + if (!R) { + E(V); + P = true + } else { + return true + } + } + var U = V.jGetPageXY(), + T = U.x - M.x, + X = U.y - M.y, + S = T > 0 ? Math.floor(T / I.ppf.x) : Math.ceil(T / I.ppf.x), + W = X > 0 ? Math.floor(X / I.ppf.y) : Math.ceil(X / I.ppf.y); + if (I.option("spin") == "hover" || I.option("spin") == "drag" && P) { + clearTimeout(O); + if (!Q && f(V).isTouchEvent()) { + if (I.option("columns") > 1 && Math.abs(T) > 1 && Math.abs(T) > Math.abs(X) || I.option("rows") > 1 && Math.abs(X) > 1 && Math.abs(X) < a) { + f(V).stopDefaults() + } else { + P = false; + return + } + } + Q = true; + if (I.option("rows") > 1 && Math.abs(X) >= I.ppf.y) { + M.y = M.y + W * I.ppf.y; + I.jump(I.current.row + W, I.current.col) + } + if (I.option("columns") > 1 && I.option("rows") <= 1) { + if (Math.abs(T) >= I.ppf.x) { + M.x = M.x + S * I.ppf.x; + M.y = U.y; + I.jump(I.current.row, I.current.col + (0 - S)) + } else { + if (Math.abs(X) >= I.ppf.y) { + M.x = U.x; + M.y = M.y + W * I.ppf.y; + I.jump(I.current.row, I.current.col + (0 - W)) + } + } + } else { + if (I.option("columns") > 1 && Math.abs(T) >= I.ppf.x) { + M.x = M.x + S * I.ppf.x; + I.jump(I.current.row, I.current.col + (0 - S)) + } + } + O = setTimeout(function(Y) { + this.spos = Y; + this.date = u.now() + }.jBind(L, U), 50) + } + return false + }; + if (this._autospin.cancelable) { + f(this.option("spin") == "drag" ? document : this.o).jAddEvent(k.mousemove, this.mMoveEvent); + if (u.browser.touchScreen) { + f(this.option("spin") == "drag" ? document : this.o).jAddEvent("touchmove", this.mMoveEvent) + } + } + this.mHoverEvent = function(S) { + if (S.pointerType && ("touch" === S.pointerType || S.pointerType === S.MSPOINTER_TYPE_TOUCH)) { + return true + } + if (H || R) { + H && I.magnifier.div.show() && I.magnifier.animate(S); + return false + } + if (I._autospin.frames > 0 && "hover" == I.option("autospin-stop")) { + I._autospin.pause() + } else { + !I._autospin.invoked && f(I.option("autospin-start")).contains("hover") && (I._autospin.invoked = !I._autospin.infinite) && I._autospin.play() + } + M = S.jGetPageXY(); + "hover" == I.option("spin") && (I.spinStarted = true); + return false + }; + if (this._autospin.cancelable) { + this.o.jAddEvent(k.mouseover, this.mHoverEvent) + } + this.mOutEvent = function(S) { + if (S.pointerType && ("touch" === S.pointerType || S.pointerType === S.MSPOINTER_TYPE_TOUCH)) { + return true + } + if (I.o.hasChild(S.getRelated())) { + return true + } + if (I._autospin.infinite && "hover" == I.option("autospin-stop")) { + if (H) { + if (I.magnifier.div.hasChild(S.getRelated())) { + return true + } + E(S) + } + I._autospin.play() + } else {} + return false + }; + if (this._autospin.cancelable) { + this.o.jAddEvent(k.mouseout, this.mOutEvent) + } + this.mDownEvent = function(T) { + var S = T.isTouchEvent(); + if (3 == T.getButton()) { + return true + } + if (I.hintBox) { + I.hideHintBox() + } + if ((/touch/i).test(T.type) && T.touches.length > 1) { + return true + } + M = T.jGetPageXY(); + K = T.jGetPageXY(); + K.autospinStopped = false; + if (H) { + if (S) { + I.magnifier.delta.x = I.magnifier.x + I.boxSize.width / I.magnifier.ratio.x / 2 - (I.boxBoundaries.right - T.jGetPageXY().x); + I.magnifier.delta.y = I.magnifier.y + I.boxSize.height / I.magnifier.ratio.y / 2 - (I.boxBoundaries.bottom - T.jGetPageXY().y) + } + } + L.spos = T.jGetPageXY(); + L.date = u.now(); + I.option("spin") == "drag" && (M = T.jGetPageXY()); + if (H || R) { + !S && (R = false); + return true + } + if (I._autospin.frames > 0 && "click" == I.option("autospin-stop")) { + K.autospinStopped = true; + I._autospin.pause(); + T.stopDefaults() + } + P = true; + Q = false; + I.option("spin") == "drag" && (I.spinStarted = true) && (M = T.jGetPageXY()); + return false + }; + if (this._autospin.cancelable) { + if (!u.browser.mobile || !u.browser.touchScreen) { + this.o.jAddEvent(k.mousedown, this.mDownEvent) + } + if (u.browser.touchScreen && this.mDownEvent) { + this.o.jAddEvent("touchstart", this.mDownEvent) + } + } + this.mDocUpEvent = function(T) { + var S = (T.pointerType && ("touch" === T.pointerType || T.pointerType === T.MSPOINTER_TYPE_TOUCH)) || (/touch/i).test(T.type); + if (3 == T.getButton()) { + return true + } + if (H || R || !P) { + return + } + L.moved = Q; + I._checkDragFrames(L, T.jGetPageXY(), M); + P = false; + Q = false + }; + if (this._autospin.cancelable) { + f(document).jAddEvent(k.mouseup, this.mDocUpEvent); + if (u.browser.touchScreen) { + f(document).jAddEvent("touchend", this.mDocUpEvent) + } + f(document).jAddEvent(k.mouseout, function(S) { + if (null === S.getRelated() || document.documentElement === S.getRelated()) { + P = false + } + }) + } + this.mUpEvent = function(U) { + var S = (U.pointerType && ("touch" === U.pointerType || U.pointerType === U.MSPOINTER_TYPE_TOUCH)) || (/touch/i).test(U.type), + T = U.jGetPageXY(); + if (0 == Math.abs(T.x - K.x) && 0 == Math.abs(T.y - K.y)) { + if (!H && !R) { + if (K.autospinStopped) { + return + } + if (!I._autospin.invoked && I._autospin.frames < 1 && f(I.option("autospin-start")).contains("click")) { + I._autospin.invoked = !I._autospin.infinite; + I._autospin.play(); + return false + } + } + if (I.option("magnify")) { + Q = false; + E(U) + } + return false + } + if (H || R || !P) { + return false + } + L.moved = Q; + I._checkDragFrames(L, U.jGetPageXY(), M); + P = false; + Q = false; + return false + }; + if (this._autospin.cancelable) { + if (!u.browser.mobile || !u.browser.touchScreen) { + this.o.jAddEvent(k.mouseup, this.mUpEvent) + } + if (u.browser.touchScreen) { + this.o.jAddEvent("touchend", this.mUpEvent) + } + } + if (this._autospin.cancelable && this.option("mousewheel-step") > 0) { + this.o.jAddEvent("mousescroll", function(S) { + var T; + if (I._autospin && I._autospin.frames > 0) { + I._autospin.pause(true) + } + if (H || R || I._autospin.frames > 0) { + return + } + f(S).stop(); + T = Math.abs(S.deltaY) < Math.abs(S.deltaX) ? S.deltaX : S.deltaY; + T = S.isMouse ? ((T / Math.abs(T)) * I.option("mousewheel-step")) : (T * (8 / 54)); + clearTimeout(G); + if (!J) { + J = true; + I.spinStarted = true + } + if (I.isVerticalSpin || (I.option("loop-row") && !I.option("loop-column"))) { + I.jump(I.current.row + (S.isMouse ? -1 : 1) * T, I.current.col, S.isMouse, 300) + } else { + if (S.isMouse || I.option("rows") < 2 || Math.abs(S.deltaY) < Math.abs(S.deltaX)) { + I.jump(I.current.row, I.current.col + T, S.isMouse, 300) + } else { + I.jump(I.current.row + (S.isMouse ? -1 : 1) * T, I.current.col, S.isMouse, 300) + } + } + G = setTimeout(function(U) { + J = false + }, 200) + }) + } + if (this._autospin.cancelable && !("infinite" == this.option("autospin") && f(this.option("autospin-start")).contains("click")) && this.option("magnify")) { + H = false; + if ("inner" != this.option("magnifier-shape")) { + var B = "" + this.option("magnifier-width"); + if (B.match(/\%$/i)) { + B = Math.round(this.size.width * parseInt(B) / 100) + } else { + B = parseInt(B) + } + } + this.o.jAddClass("zoom-in"); + this.magnifier = { + div: u.$new("div", null, { + position: "absolute", + "z-index": 9999, + left: 0, + top: 0, + width: (B || this.boxSize.width) + "px", + height: (B || this.boxSize.height) + "px", + "background-repeat": "no-repeat", + "border-radius": ("circle" != I.option("magnifier-shape")) ? 0 : B / 2 + }).jAddEvent("dragstart selectstart", function(S) { + S.stop() + }), + image: null, + ratio: { + x: 0, + y: 0 + }, + pos: { + x: 0, + y: 0 + }, + delta: { + x: 0, + y: 0 + }, + size: { + width: (B || this.boxSize.width), + height: (B || this.boxSize.height) + }, + ddx: 0, + ddy: 0, + fadeFX: null, + moveTimer: null, + startTime: null, + spin: this, + start: function(T, U, S) { + if (!I.canMagnify) { + return + } + if ("inner" == I.option("magnifier-shape")) { + this.ratio.x = I.zoomSize.width / I.boxSize.width; + this.ratio.y = I.zoomSize.height / I.boxSize.height + } else { + this.ratio.x = I.zoomSize.width / I.size.width; + this.ratio.y = I.zoomSize.height / I.size.height + } + H = true; + P = false; + if ("inner" == I.option("magnifier-shape")) { + this.size = I.zoomSize; + this.div.jSetCss({ + width: "100%", + height: "100%" + }) + } + this.image = f(T.img); + this.image.jSetCss({ + width: I.zoomSize.width, + height: I.zoomSize.height + }).jAppendTo(this.div); + this.div.jSetOpacity(0); + this.div.jAppendTo(I.isFullScreen ? I.fullScreenBox : I.wrapper); + I.o.jRemoveClass("zoom-in"); + this.animate(null, U, S); + this.fadeFX.stop(); + this.fadeFX.options.duration = 400; + this.fadeFX.options.onComplete = function() { + I.option("onzoomin").call(null, I.o) + }; + this.fadeFX.start({ + opacity: [0, 1] + }); + this.registerEvents() + }, + stop: function(S) { + this.unRegisterEvents(); + H = false; + R = false; + this.fadeFX.stop(); + this.fadeFX.options.onComplete = function() { + clearTimeout(I.magnifier.moveTimer); + I.magnifier.moveTimer = null; + I.magnifier.image.jRemove(); + I.magnifier.div.jRemove(); + I.magnifier.pos = { + x: 0, + y: 0 + }; + I.magnifier.delta = { + x: 0, + y: 0 + }; + I.magnifier.ddx = 0; + I.magnifier.ddy = 0; + I.o.jAddClass("zoom-in"); + I.option("onzoomout").call(null, I.o) + }; + this.fadeFX.options.duration = 200; + this.fadeFX.start({ + opacity: [this.fadeFX.el.jGetCss("opacity"), 0] + }) + }, + animate: function(W, V, U) { + if (!H) { + return + } + var T, X, S = U || (W && W.isTouchEvent()) || false; + if (W) { + if (S && !W.isPrimaryTouch()) { + return + } + f(W).stopDefaults() + } + V = V || W.jGetPageXY(); + if (V.x > I.boxBoundaries.right || V.x < I.boxBoundaries.left || V.y > I.boxBoundaries.bottom || V.y < I.boxBoundaries.top) { + return + } + if (W && S) { + W.stop() + } + this.touchEvent = S; + if ("inner" === I.option("magnifier-shape")) { + V.x -= this.delta.x; + V.y -= this.delta.y; + if (this.ratio.x <= 1) { + T = I.boxSize.width / 2; + T -= I.boxSize.width / this.ratio.x / 2 + } else { + T = (W && S) ? (I.boxBoundaries.right - V.x) : V.x - I.boxBoundaries.left; + T -= I.boxSize.width / this.ratio.x / 2; + T = Math.max(0, Math.min(T, I.boxSize.width - I.boxSize.width / this.ratio.x)) + } + if (this.ratio.y <= 1) { + X = I.boxSize.height / 2; + X -= I.boxSize.height / this.ratio.y / 2 + } else { + X = (W && S) ? (I.boxBoundaries.bottom - V.y) : V.y - I.boxBoundaries.top; + X -= I.boxSize.height / this.ratio.y / 2; + X = Math.max(0, Math.min(X, I.boxSize.height - I.boxSize.height / this.ratio.y)) + } + } else { + T = V.x; + X = V.y + } + this.x = T; + this.y = X; + if (!this.moveTimer) { + this.move(1) + } + }, + move: function(V) { + var Y, X, aa, Z, W, U, T, S; + isFinite(V) || (V = 0.2); + if ("inner" != I.option("magnifier-shape")) { + clearTimeout(this.moveTimer); + this.moveTimer = null; + Y = this.x; + X = this.y; + W = Math.round(Y - this.size.width / 2) - I.boxBoundaries.left; + U = Math.round(X - this.size.height / 2) - I.boxBoundaries.top; + if (this.touchEvent) { + U -= this.size.height / 2 + 22 + } + T = Math.round(0 - ((Y - I.boundaries.left - I.borders.x) * this.ratio.x - (this.size.width / 2))); + S = Math.round(0 - ((X - I.boundaries.top - I.borders.y) * this.ratio.y - (this.size.height / 2))) + } else { + aa = Math.ceil((this.x - this.ddx) * V); + Z = Math.ceil((this.y - this.ddy) * V); + if (!aa && !Z) { + clearTimeout(this.moveTimer); + this.moveTimer = null; + return + } + this.ddx += aa; + this.ddy += Z; + W = 0; + U = 0; + T = -(this.ddx * (this.size.width / I.boxSize.width)); + S = -(this.ddy * (this.size.height / I.boxSize.height)) + } + if (H) { + this.div.jSetCss({ + left: W, + top: U + }); + this.image.jSetCss(u.browser.features.transform ? 9 === u.browser.ieMode || u.browser.presto ? { + top: 0, + left: 0, + transform: "translate(" + T + "px," + S + "px)" + } : { + top: 0, + left: 0, + transform: "translate3d(" + T + "px," + S + "px, 0)" + } : { + left: T, + top: S + }) + } + if ("inner" == I.option("magnifier-shape")) { + this.moveTimer = setTimeout(this.moveBind, 40) + } + }, + registerEvents: function() { + var S = I.isFullScreen ? I.fullScreenBox : I.wrapper; + if (I._autospin.cancelable) { + if (!u.browser.mobile || !u.browser.touchScreen) { + S.jAddEvent(k.mousedown, I.mDownEvent); + S.jAddEvent(k.mouseup, I.mUpEvent) + } + S.jAddEvent(k.mousemove, this.animateBind); + if (u.browser.touchScreen) { + S.jAddEvent("touchstart", I.mDownEvent); + S.jAddEvent("touchend", I.mUpEvent); + S.jAddEvent("touchmove", this.animateBind) + } + } + }, + unRegisterEvents: function() { + var S = I.isFullScreen ? I.fullScreenBox : I.wrapper; + if (I._autospin.cancelable) { + if (!u.browser.mobile || !u.browser.touchScreen) { + S.jRemoveEvent(k.mousedown, I.mDownEvent); + S.jRemoveEvent(k.mouseup, I.mUpEvent) + } + S.jRemoveEvent(k.mousemove, this.animateBind); + if (u.browser.touchScreen) { + S.jRemoveEvent("touchstart", I.mDownEvent); + S.jRemoveEvent("touchend", I.mUpEvent); + S.jRemoveEvent("touchmove", this.animateBind) + } + } + } + }; + this.magnifier.fadeFX = new u.FX(this.magnifier.div); + this.magnifier.animateBind = this.magnifier.animate.jBindAsEvent(this.magnifier); + this.magnifier.moveBind = this.magnifier.move.jBind(this.magnifier); + this.magnifier.div.jAddClass("m360-magnifier").jAddClass("m360-magnifier-" + this.option("magnifier-shape")); + if ("inner" != this.option("magnifier-shape")) { + I.magnifier.div.jAddEvent("mousescroll", function(U) { + var T = U.isMouse ? 5 : 8 / 54, + S; + f(U).stop(); + T = (100 + T * Math.abs(U.delta)) / 100; + if (U.delta < 0) { + T = 1 / T + } + S = Math.max(100, Math.round(I.magnifier.size.width * T)); + S = Math.min(S, I.size.width); + this.jSetCss({ + width: S, + height: S, + "border-radius": ("circle" != I.option("magnifier-shape")) ? 0 : S / 2 + }); + I.magnifier.size = this.jGetSize(); + I.magnifier.move(1) + }) + } + var F = this.loader = u.$new("div").jAddClass("m360-magnifier-loader-holder").append(u.$new("div").jAddClass("m360-loader")).jAddEvent(k.mousedown + " " + k.mousemove, function(S) { + S.stopDistribution() + }); + F.toggle = function(S) { + if (S) { + F.timer = setTimeout(function() { + I.o.append(F) + }, 400) + } else { + if (F.timer) { + clearTimeout(F.timer); + F.timer = false + } + (I.o === this.parentNode) && I.o.removeChild(F) + } + }; + + function E(X, T) { + var W, V, U, S = false; + if (Q) { + return + } + if (!I.canMagnify) { + return + } + if (u.jTypeOf(X) == "event") { + S = (X.pointerType && ("touch" === X.pointerType || X.pointerType === X.MSPOINTER_TYPE_TOUCH)) || (/touch/i).test(X.type); + if ((U = f(X.getTarget())).jHasClass("icon")) { + if (H && U.jHasClass("magnify")) { + return + } + if (!H && U.jHasClass("spin")) { + return + } + } + X.stop() + } + if (H && T) { + return + } + if (!H && false == T) { + return + } + if (H && !T) { + I.magnifier.stop(u.jTypeOf(X) == "event" ? X.jGetPageXY() : null); + U && U.jHasClass("spin") && I._autospin.infinite && I._autospin.play() + } else { + W = I.checkJumpRowCol(I.current.row, I.current.col); + V = (u.jTypeOf(X) == "event") ? X.jGetPageXY() : X; + F && F.toggle(true); + R = true; + P = false; + I._autospin.pause(); + new u.ImageLoader(I.getImageURL(W.row + 1, W.col + 1, "zoom"), { + onload: f(function(Z, Y) { + I.resizeCallback(); + I.magnifier.start(Y, V, Z) + }).jBind(null, S), + onerror: function() { + R = false + }, + oncomplete: function() { + F && F.toggle(false) + } + }) + } + return false + } + this._showM = E.jBind(this, { + x: I.boxBoundaries.left + (I.boxBoundaries.right - I.boxBoundaries.left) / 2, + y: I.boxBoundaries.top + (I.boxBoundaries.bottom - I.boxBoundaries.top) / 2 + }, true); + this._hideM = E.jBind(this, null, false) + } + if (this._autospin.cancelable && this.option("fullscreen")) { + this.fullscreenIcon = u.$new("button").jAddClass("m360-icon m360-icon-fullscreen-open").jAddEvent(k.mousedown, function(S) { + S.stopDistribution() + }).jAddEvent("click", function(S) { + if (3 == S.getButton()) { + return true + } + S.stop(); + this.enterFullscreen(); + return false + }.jBindAsEvent(this)).jAppendTo(this.wrapper); + u.browser.touchScreen && this.fullscreenIcon.jAddEvent("touchstart", function(S) { + S.stopDistribution() + }) + } + this.resizeCallback(); + if (this._autospin.maxFrames > 0 && f(this.option("autospin-start")).contains("load")) { + this._autospin.play() + } else { + this.jump(this.currentFrame.row, this.currentFrame.col); + if (this.option("rows") * this.option("columns") > 1 && this.option("hint") && this._autospin.cancelable) { + this.setupHint() + } + } + var N = f(this.o).jFetch("cr"); + if (N) { + f(this.o).append(N) + } + ("function" == u.jTypeOf(this.option("onready"))) && this.option("onready").call(null, this.o) + }; + w.prototype._checkDragFrames = function(F, E, G) { + if (!this.option("smoothing") || !F.date) { + return + } + var D = u.now() - F.date; + F.date = false; + if (D <= 0) { + return + } + if (D < 50) { + D = 50 + } + var C = 0.01; + ppf = this.ppf, loopR = this.option("loop-row") && this.loadedRows.count == this.option("rows"), loopC = this.option("loop-column"), dx = E.x - F.spos.x, dy = E.y - F.spos.y; + + function B(K) { + var L = K == "x" ? dx : dy; + var H = L / D; + var J = (H / 2) * (H / C); + var I; + if (K == "x") { + if (Math.abs(dx) < Math.abs(dy)) { + I = J - (F.spos.x - G.x) + } else { + I = Math.abs(L + (L > 0 ? J : (0 - J))) - Math.abs(F.spos.x - G.x); + I = L > 0 ? (0 - I) : I + } + } else { + if (!loopR || Math.abs(dx) >= Math.abs(dy)) { + I = J - (F.spos.y - G.y) + } else { + I = Math.abs(L + (L > 0 ? J : (0 - J))) - Math.abs(F.spos.y - G.y); + I = L > 0 ? (0 - I) : I + } + } + I /= ppf[K]; + return I > 0 ? Math.floor(I) : Math.ceil(I) + } + this.jump(this.current.row + B("y"), this.current.col + B("x"), true, 2 * Math.abs(Math.floor(Math.max(Math.abs(dx), Math.abs(dy)) / D / C))) + }; + w.prototype.jump = function(E, C, B, D) { + this.current.row = E; + this.current.col = C; + this.fx && this.fx.stop(); + if (!B) { + this.current.tmp.row = E; + this.current.tmp.col = C; + this.jump_(E, C); + return + } + this.fx = new u.FX(this.o, { + duration: D, + transition: u.FX.Transition.quadOut, + onBeforeRender: (function(F) { + this.current.tmp.col = F.col; + this.current.tmp.row = F.row; + this.jump_(F.row, F.col) + }).jBind(this) + }).start({ + col: [this.current.tmp.col, C], + row: [this.current.tmp.row, E] + }) + }; + w.prototype.checkJumpRowCol = function(E, C) { + var B, D; + E = Math.round(E); + C = Math.round(C); + if (this.option("loop-row")) { + E %= this.option("rows"); + E < 0 && (E += this.option("rows")) + } + if (this.loadedRows.indexes.contains(E)) { + E = this.loadedRows.indexes.indexOf(E) + } else { + var B = (E - this.currentFrame.row) / Math.abs(E - this.currentFrame.row); + var D = this.loadedRows.indexes.filter(function(F) { + return (F - E) * B > 0 + }); + E = D.length ? this.loadedRows.indexes.indexOf(D[(B < 0) ? D.length - 1 : 0]) : (!this.option("loop-row") || this.loadedRows.count < this.option("rows")) ? this.loadedRows.indexes.indexOf(this.currentFrame.row) : (B < 0 ? this.loadedRows.count - 1 : 0) + } + if (!this.option("loop-column") && (!this._autospin || this._autospin.frames < 1)) { + C > (this.option("columns") - 1) && (C = this.option("columns") - 1); + C < 0 && (C = 0) + } + C %= this.option("columns"); + C < 0 && (C += this.option("columns")); + (!this.option("loop-column")) && (this.current.col = C); + this.currentFrame = { + row: this.loadedRows.indexes[E], + col: C + }; + if (!this.option("loop-row") || this.loadedRows.count < this.option("rows")) { + this.current.row = this.currentFrame.row + } + return u.detach(this.currentFrame) + }; + w.prototype.jump_ = function(F, B) { + var D = this.checkJumpRowCol(F, B), + E, C, G; + F = D.row; + B = D.col; + E = this.images.small[F][B]; + if (this.isFullScreen && !(l && this.useMultiBackground && this.imageQueue.fullscreen.length) && this.images.fullscreen[F] && this.images.fullscreen[F][B] && this.images.fullscreen[F][B].loaded) { + E = this.images.fullscreen[F][B] + } + if (!E.loaded) { + return + } + if (u.browser.features.canvas) { + this.ctxDraw(E.cachedObject) + } else { + this.imgContext.src = E.url + } + + this.option("actionspin").call(null, this.o, B); + if (this.spinStarted && (!this.lastFrame || this.lastFrame.row != F || this.lastFrame.col != B)) { + this.option("onspin").call(null, this.o); + this.spinStarted = false; + if (this.hintBox) { + this.hideHintBox() + } + } + this.lastFrame = D + }; + w.prototype.ctxDraw = function(D) { + var C = 0, + H = this.size.width, + F = this.size.height, + B = D.naturalWidth, + G = D.naturalHeight; + if ((window.devicePixelRatio || 1) >= 2 && ((B * G) / (H * F) >= 2)) { + H *= 2; + F *= 2 + } + C = Math.ceil(Math.log(Math.max(D.naturalWidth / H, D.naturalHeight / F)) / Math.LN2); + this.backstageCanvas.width = B; + this.backstageCanvas.height = G; + this.backstageCanvas2.width = B; + this.backstageCanvas2.height = G; + this.backstageCtx.drawImage(D, 0, 0, B, G); + for (var E = C - 1; E > 0; E--) { + this.backstageCanvas2.width *= 0.5; + this.backstageCanvas2.height *= 0.5; + this.backstageCtx2.drawImage(this.backstageCanvas, 0, 0, this.backstageCanvas.width, this.backstageCanvas.height, 0, 0, this.backstageCanvas2.width, this.backstageCanvas2.height); + this.backstageCanvas.width *= 0.5; + this.backstageCanvas.height *= 0.5; + this.backstageCtx.drawImage(this.backstageCanvas2, 0, 0, this.backstageCanvas2.width, this.backstageCanvas2.height, 0, 0, this.backstageCanvas.width, this.backstageCanvas.height) + } + this.canvas.width = H; + this.canvas.height = F; + this.canvasContext.drawImage(this.backstageCanvas, 0, 0, this.backstageCanvas.width, this.backstageCanvas.height, 0, 0, this.canvas.width, this.canvas.height) + }; + w.prototype.reflow = function() { + var B, D, C; + this.boundaries = this.o.jGetRect(); + this.boxSize = this.wrapper.jGetSize(); + this.boxBoundaries = this.wrapper.jGetRect(); + if (this.isFullScreen) { + D = f(document).jGetSize(); + C = this.fullScreenSize.width / this.fullScreenSize.height; + if (u.browser.trident && u.browser.backCompat) { + this.fullScreenBox.jSetCss({ + width: D.width, + height: D.height + }) + } + this.boxSize = this.fullScreenBox.jGetSize(); + this.boxBoundaries = this.fullScreenBox.jGetRect(); + this.o.jSetCss(this.adjustFSSize(D)) + } + B = f(this.o).jGetSize(); + if (this.isFullScreen && 11 == u.browser.ieMode && window.parent !== window.window) { + this.boxSize.width = this.fullScreenBox.clientWidth; + this.boxSize.height = this.fullScreenBox.clientHeight; + B.width = this.o.clientWidth; + B.height = this.o.clientHeight + } + if (B.width <= 0 || B.height <= 0) { + return + } + B.width -= this.borders.x; + B.height -= this.borders.y; + this.size = B; + if (this.option("magnify")) { + if ((this.size.width * this.size.height) / (this.zoomSize.width * this.zoomSize.height) > 0.8) { + this._hideM && this._hideM(); + this.canMagnify = false; + this.o.jRemoveClass("zoom-in") + } else { + this.canMagnify = true; + this.o.jAddClass("zoom-in") + } + } + this.ppf = { + x: this.size.width / this.option("columns") / Math.pow(this.option("sensitivityX") / 50, 2), + y: this.size.height / this.option("rows") / Math.pow(this.option("sensitivityY") / 50, 2) + }; + if (this.current) { + this.jump_(this.current.row, this.current.col) + } + }; + w.prototype.spin = function(B) { + (this._hideM) && this._hideM(); + if (this.hintBox) { + this.hideHintBox() + } + this.spinStarted = true; + (B || null) ? this.jump(this.current.row, this.current.col + B, true, 100 * (Math.log(Math.abs(B) / Math.log(2)))): this._autospin.play(Number.MAX_VALUE) + }; + w.prototype.rotate = function(B, C) { + if (!B) { + B = 0 + } + if (!C) { + C = 0 + } + if (!B && !C) { + return + } + if (this._hideM) { + this._hideM() + } + if (this.hintBox) { + this.hideHintBox() + } + this.spinStarted = true; + this.jump(this.current.row + C, this.current.col + B, true, 100 * (Math.log(Math.max(Math.abs(B), Math.abs(C)) / Math.log(2)))) + }; + w.prototype.rotateX = function(B) { + this.rotate(B, 0) + }; + w.prototype.rotateY = function(B) { + this.rotate(0, B) + }; + w.prototype.magnify = function(B) { + (u.defined(B) ? B : true) ? this._showM && this._showM(): this._hideM && this._hideM() + }; + w.prototype.stop = function() { + var D, B, E, C = window.URL || window.webkitURL || null; + if (this._autospin && this._autospin.frames > 0) { + this._autospin.pause() + } + if (this.isFullScreen) { + this.o.firstChild.jSetCss({}); + this.o.jSetCss({ + width: "", + height: "100%", + "max-height": "", + "max-width": "" + }).jAppendTo(this.wrapper) + } + if (this.fullScreenBox) { + if (this.fullScreenScrollCallback) { + f(window).jRemoveEvent("scroll", this.fullScreenScrollCallback) + } + if (this.fullScreenScrollCallbackTimer) { + clearTimeout(this.fullScreenScrollCallbackTimer) + } + this.fullScreenBox.kill(); + this.fullScreenBox = null + } + if (this.magnifier && this.magnifier.div) { + this.magnifier.div.kill(); + this.magnifier = null + } + if (this.fullscreenIcon) { + this.fullscreenIcon.kill(); + this.fullscreenIcon = null + } + f(window).jRemoveEvent("resize", this.resizeCallback); + clearTimeout(this.reflowTimer); + this.reflowTimer = null; + this.o.jClearEvents(); + while (this.o.firstChild != this.o.lastChild) { + this.o.removeChild(this.o.lastChild) + } + if (this.option("spin") == "drag") { + f(document).jRemoveEvent([k.mousemove, "touchmove"], this.mMoveEvent) + } + f(document).jRemoveEvent([k.mouseup, k.mouseout, "touchend"], this.mDocUpEvent); + this.o.replaceChild(this.oi, this.o.firstChild); + this.o.jSetCssProp("background", ""); + this.o.jRemoveClass("zoom-in"); + if (this.wrapper) { + this.wrapper.parentNode.replaceChild(this.o, this.wrapper); + this.wrapper.kill(); + this.wrapper = null + } + for (D = 0, B = this.addedCSS.length; D < B; D++) { + u.removeCSS("leoimage360-css", this.addedCSS[D]) + } + f(this.imgCacheBox).jRemove(); + if (C) { + for (E in this.imageMap) { + f(this.imageMap[E]).jEach(function(G) { + var F = G.img.bgURL.replace(/^url\s*\(\s*["']?/, "").replace(/["']?\s*\)$/, ""); + if (/^blob\:/.test(F)) { + C.revokeObjectURL(F) + } + }) + } + } + }; + w.prototype.enterFullscreen = function() { + if (!this._autospin.cancelable || !this.option("fullscreen")) { + return + } + this._hideM && this._hideM(); + var E = f(document).jGetSize(), + D = f(window).jGetScroll(), + C = f(document).jGetFullSize(), + B = window.parent !== window.window; + if (B) { + if (C.height <= E.height) { + D.y = this.boxBoundaries.top + } + E.height = Math.min(E.height, this.fullScreenSize.height); + if (E.height + D.y > C.height) { + E.width -= u.browser.scrollbarsWidth + } + } + if (!this.fullScreenBox) { + this.fullScreenBox = u.$new("div", {}, { + display: "block", + overflow: "hidden", + position: "absolute", + zIndex: 20000, + "text-align": "center", + "vertical-align": "middle", + opacity: 1, + width: this.boxSize.width, + height: this.boxSize.height, + top: this.boxBoundaries.top, + left: this.boxBoundaries.left + }).jAddClass(c + "-fullscreen"); + if (!u.browser.touchScreen || !u.browser.mobile) { + this.fullScreenBox.jAddClass("desktop") + } + if (u.browser.ieMode) { + this.fullScreenBox.jAddClass("leoimage-for-ie" + u.browser.ieMode) + } + if (u.browser.ieMode && u.browser.ieMode < 8) { + this.fullScreenBox.append(u.$new("span", null, { + display: "inline-block", + height: "100%", + width: 1, + "vertical-align": "middle" + })) + } + this.adjustFSSize = function(I) { + var F, H, G = this.fullScreenSize.width / this.fullScreenSize.height; + F = Math.min(this.fullScreenSize.width, I.width * 0.98); + H = Math.min(this.fullScreenSize.height, I.height * 0.98); + if (F / H > G) { + F = H * G + } else { + if (F / H <= G) { + H = F / G + } + } + return { + width: Math.floor(F), + height: Math.floor(H) + } + }; + if (u.browser.trident && u.browser.backCompat) { + this.fullScreenScrollCallback = function() { + var F = f(window).jGetScroll(), + G = this.fullScreenBox.jGetPosition(); + this.fullScreenScrollCallbackTimer && clearTimeout(this.fullScreenScrollCallbackTimer); + this.fullScreenScrollCallbackTimer = setTimeout(function() { + new u.FX(this.fullScreenBox, { + duration: 250 + }).start({ + top: [G.top, F.y], + left: [G.left, F.x] + }) + }.jBind(this), 300) + }.jBind(this) + } + if (this._autospin.cancelable) { + if (!u.browser.mobile || !u.browser.touchScreen) { + this.fullScreenBox.jAddEvent(k.mousedown, this.mDownEvent); + this.fullScreenBox.jAddEvent(k.mouseup, this.mUpEvent) + } + if (u.browser.touchScreen) { + this.fullScreenBox.jAddEvent("touchstart", this.mDownEvent); + this.fullScreenBox.jAddEvent("touchend", this.mUpEvent) + } + } + } + this.fullScreenImage || (this.fullScreenImage = f(this.o.firstChild.cloneNode(false)).jSetCss({ + position: "relative", + "z-index": 1 + })); + this.fullScreenImage.jSetCss({ + "margin-top": "-100%", + "margin-left": "100%" + }).jSetOpacity(0); + if (E.width / E.height > this.fullScreenSize.width / this.fullScreenSize.height) { + this.fullScreenImage.jSetCss({ + width: "auto", + height: "98%", + "max-height": this.fullScreenSize.height, + display: "inline-block", + "vertical-align": "middle" + }) + } else { + this.fullScreenImage.jSetCss({ + width: "98%", + "max-width": this.fullScreenSize.width, + height: "auto", + display: "inline-block", + "vertical-align": "middle" + }) + } + this.fullScreenBox.jAppendTo(document.body).append(this.fullScreenImage); + this.fullScreenBox.show(); + this.o.jSetCss({ + "max-width": this.fullScreenSize.width, + "max-height": this.fullScreenSize.height, + width: this.fullScreenImage.jGetSize().width + this.borders.x, + height: "auto", + "background-size": this.fullScreenImage.jGetSize().width + "px " + this.fullScreenImage.jGetSize().height + "px", + "z-index": 2 + }).jAppendTo(this.fullScreenBox, "top"); + s.browser.features.fullScreen && this.fullScreenBox.jSetOpacity(1); + s.browser.fullScreen.request(this.fullScreenBox, { + onEnter: this.onEnteredFullScreen.jBind(this), + onExit: this.onExitFullScreen.jBind(this), + fallback: function() { + this.fullScreenFX || (this.fullScreenFX = new u.FX(this.fullScreenBox, { + duration: 400, + transition: u.FX.Transition.expoOut, + onStart: (function() { + this.fullScreenBox.jSetCss({ + width: this.boxSize.width, + height: this.boxSize.height, + top: this.boxBoundaries.top, + left: this.boxBoundaries.left + }).jAppendTo(document.body) + }).jBind(this), + onAfterRender: (function(F) { + this.o.jSetCss(this.fullScreenImage.jGetSize()); + this.size = this.o.jGetSize(); + this.jump_(this.current.row, this.current.col) + }).jBind(this), + onComplete: (function() { + this.onEnteredFullScreen(true) + }).jBind(this) + })); + this.fullScreenFX.start({ + width: [this.boxSize.width, E.width], + height: [this.boxSize.height, E.height], + top: [this.boxBoundaries.top, 0 + D.y], + left: [this.boxBoundaries.left, 0 + D.x], + opacity: [0, 1] + }) + }.jBind(this) + }) + }; + w.prototype.onEnteredFullScreen = function(I) { + var G, B, E = 0, + H = 0, + C = window.parent !== window.window, + J, D = this.getCurrentFrame(); + if (I && !this.isFullScreen && !C && !(u.browser.trident && u.browser.backCompat)) { + this.fullScreenBox.jSetCss({ + display: "block", + position: "fixed", + top: 0, + bottom: 0, + left: 0, + right: 0, + width: "auto", + height: "auto" + }) + } + this.isFullScreen = true; + this.o.firstChild.jSetCss({ + width: "100%", + height: "auto", + "max-width": this.fullScreenSize.width, + "max-height": this.fullScreenSize.height + }); + this.resizeCallback(); + if (this.firstFullScreenRun) { + setTimeout((function() { + this.progressBar.reset(); + this.progressBar.changePlaceholder(this.fullScreenBox); + this.preloadImages("fullscreen", this.currentFrame.row + 1, this.currentFrame.col + 1) + }).jBind(this), 1); + this.firstFullScreenRun = false + } + this.jump_(this.current.row, this.current.col); + if (this.fullScreenScrollCallback) { + f(window).jAddEvent("scroll", this.fullScreenScrollCallback) + } + if (!this.leaveFSButton) { + this.leaveFSButton = u.$new("button").jAddClass("m360-icon m360-icon-fullscreen-close").jAppendTo(this.fullScreenBox).jAddEvent(k.mousedown, function(K) { + K.stopDistribution() + }).jAddEvent("click", function(L) { + var K; + if (3 == L.getButton()) { + return true + } + L.stop(); + if (K = this.fullScreenBox.jFetch("fullscreen:pseudo:event:keydown")) { + u.doc.jRemoveEvent("keydown", K); + this.fullScreenBox.jDel("fullscreen:pseudo:event:keydown") + } + this.exitFullscreen(); + return false + }.jBindAsEvent(this)); + u.browser.touchScreen && this.leaveFSButton.jAddEvent("touchstart", function(K) { + K.stopDistribution() + }) + } + this.leaveFSButton.show(); + if (I) { + var F = function(K) { + if (K.keyCode == 27) { + u.doc.jRemoveEvent("keydown", F); + this.exitFullscreen() + } + }.jBindAsEvent(this); + this.fullScreenBox.jStore("fullscreen:pseudo:event:keydown", F); + u.doc.jAddEvent("keydown", F); + !u.browser.touchScreen && (this.leaveFSMessage = new u.Message("Press ESC key to leave full-screen", 4000, this.fullScreenBox, c + "-message")) + } + this.fullscreenIcon.hide() + }; + w.prototype.exitFullscreen = function() { + var D = this.fullScreenBox.jGetSize(), + C = this.fullScreenBox.jGetRect(), + B = this.checkJumpRowCol(this.current.row, this.current.col); + this.leaveFSMessage && this.leaveFSMessage.hide(0); + this._hideM && this._hideM(); + if (D.width / D.height > this.fullScreenSize.width / this.fullScreenSize.height) { + this.fullScreenImage.jSetCss({ + width: "auto", + height: "98%", + "max-height": this.fullScreenSize.height, + display: "inline-block", + "vertical-align": "middle" + }) + } else { + this.fullScreenImage.jSetCss({ + width: "98%", + "max-width": this.fullScreenSize.width, + height: "auto", + display: "inline-block", + "vertical-align": "middle" + }) + } + if (s.browser.fullScreen.capable && s.browser.fullScreen.enabled()) { + s.browser.fullScreen.cancel() + } else { + this.leaveFSButton.hide(); + this.fullScreenExitFX || (this.fullScreenExitFX = new u.FX(this.fullScreenBox, { + duration: 300, + transition: u.FX.Transition.expoOut, + onStart: (function() { + this.isFullScreen = false; + this.fullScreenBox.jSetCss({ + position: "absolute" + }).jAppendTo(document.body) + }).jBind(this), + onAfterRender: (function(E) { + this.o.jSetCss(this.fullScreenImage.jGetSize()); + this.size = this.o.jGetSize(); + this.jump_(this.current.row, this.current.col) + }).jBind(this), + onComplete: (function() { + this.onExitFullScreen(true) + }).jBind(this) + })); + this.fullScreenExitFX.start({ + width: [D.width, this.boxSize.width], + height: [D.height, this.boxSize.height], + top: [0 + C.top, this.boxBoundaries.top], + left: [0 + C.left, this.boxBoundaries.left], + opacity: [1, 0.5] + }) + } + }; + w.prototype.onExitFullScreen = function(C) { + var B, D = this.getCurrentFrame(); + if (!this.fullScreenBox) { + return + } + this.fullscreenProgressBox && this.fullscreenProgressBox.jRemove() && delete this.fullscreenProgressBox; + if (this.fullScreenScrollCallback) { + f(window).jRemoveEvent("scroll", this.fullScreenScrollCallback) + } + this.isFullScreen = false; + this.o.jAppendTo(this.wrapper).jSetOpacity(0).jSetCss({ + width: "", + height: "", + "max-height": "", + "max-width": "100%", + "z-index": "" + }); + this.o.firstChild.jSetCss({ + width: "", + height: "", + "max-width": "", + "max-height": "" + }); + this.resizeCallback(); + this.leaveFSButton.hide(); + this.fullscreenIcon.show(); + this.o.jSetOpacity(1); + this.fullScreenBox.hide() + }; + w.prototype.setupHint = function() { + if (!this.hintBox) { + this.hintBox = u.$new("div", { + "class": "m360-hint" + }); + this.hintMessage = u.$new("span", { + "class": "m360-hint-message" + }).append(document.createTextNode(this.localString(u.browser.touchScreen ? "mobile-hint-text" : "hint-text"))).jAppendTo(this.hintBox); + f(this.hintBox).jAppendTo(this.o) + } + if (this.option("mousewheel-step") > 0) { + var B = function(D) { + this.o.jRemoveEvent("mousescroll", B); + this.hideHintBox() + }.jBindAsEvent(this); + this.o.jAddEvent("mousescroll", B) + } + if ("hover" === this.option("spin")) { + var C = function() { + this.hideHintBox(); + this.o.jRemoveEvent("mousemove", C) + }.jBindAsEvent(this); + this.o.jAddEvent("mousemove", C) + } + }; + w.prototype.hideHintBox = function() { + if (!this.hintBox || this.hintBox.hidding) { + return + } + this.hintBox.hidding = true; + new u.FX(this.hintBox, { + duration: 200, + onComplete: function() { + this.hintBox.jRemove(); + delete this.hintBox + }.jBind(this) + }).start({ + opacity: [this.hintBox.jGetCss("opacity"), 0] + }) + }; + w.prototype.getCurrentFrame = function() { + var B = this.checkJumpRowCol(this.current.row, this.current.col); + B.row++; + B.col++; + return B + }; + var m = function() { + return "mgctlbxN$M360 mgctlbxV$" + "v4.6.5".replace("v", "") + " mgctlbxL$" + "m".toUpperCase() + ((window.mgctlbx$Pltm && "string" == u.jTypeOf(window.mgctlbx$Pltm)) ? " mgctlbxP$" + window.mgctlbx$Pltm.toLowerCase() : "") + }; + var j = f([]); + var o = { + version: "v4.6.5 for LeoImageToolbox.com", + options: {}, + lang: {}, + callbacks: {}, + start: function(C) { + var B = null; + u.$A((C ? [f(C)] : document.byClass("LeoImage360"))).jEach((function(D) { + if (f(D)) { + !j.filter(function(E) { + return E.o === D + }).length && j.push(B = new w(D)) + } + }).jBind(this)); + return B + }, + stop: function(E) { + var C, D, B; + if (E) { + (D = r(E)) && (D = j.splice(j.indexOf(D), 1)) && D[0].stop() && (delete D[0]); + return + } + while (C = j.length) { + D = j.splice(C - 1, 1); + D[0].stop(); + delete D[0] + } + }, + spin: function(D, C) { + var B; + (B = r(D)) && B.spin(C) + }, + jump: function(D, C) { + var B = null; + if (B = r(D)) { + B._hideM && B._hideM(); + B.hintBox && B.hideHintBox(); + B.jump(B.current.row + C, B.current.col) + } + }, + pause: function(C) { + var B; + (B = r(C)) && B._autospin.pause() + }, + magnifyOn: function(C) { + var B; + (B = r(C)) && B.magnify(true) + }, + magnifyOff: function(C) { + var B; + (B = r(C)) && B.magnify(false) + }, + fullscreen: function(C) { + var B; + (B = r(C)) && B.enterFullscreen() + }, + getCurrentFrame: function(D) { + var B, C = null; + if (B = r(D)) { + C = B.getCurrentFrame(); + C.column = C.col; + delete C.col + } + return C + }, setCurrentFrame: function(D, row, col) { + var B, C = null; + if (B = r(D)) { + B.jump(row, col); + return true; + } + return false + }, + registerCallback: function(B, C) { + o.callbacks[B] = C + } + }; + + function r(D) { + var C = [], + B = null; + (D && (B = f(D))) && (C = j.filter(function(E) { + return E.o === B + })); + return C.length ? C[0] : null + } + f(document).jAddEvent("domready", function() { + m = m(); + n = u.$new("div", { + "class": "m360-tmp-hdn-cont" + }).jAppendTo(document.body); + o.start() + }); + return o +})(); diff --git a/modules/appagebuilder/js/ApImageHotspot.js b/modules/appagebuilder/js/ApImageHotspot.js new file mode 100644 index 00000000..8931dd76 --- /dev/null +++ b/modules/appagebuilder/js/ApImageHotspot.js @@ -0,0 +1,762 @@ +/** + * @Website: apollotheme.com - prestashop template provider + * @author Apollotheme + * @copyright 2007-2018 Apollotheme + * @description: + */ + +(function(a) { + a.fn.LiteTooltip = function(d, c) { + return this.each(function() { + var f = a.extend({}, a.fn.LiteTooltip.defaultSettings, d || {}); + var e = a(this); + var g = new b(f, e); + if (g.settings.title != "") { + if (!e.is("input")) { + e.css({cursor: "pointer"}) + } + var debug = (g.settings.debug != null ) ? ((g.settings.debug == "true" || g.settings.debug == true) ? true : false) : false; + + if (g.settings.trigger == "hoverable") { + this.toggle = false; + e.bind("mouseenter", {settings: g.settings, element: e, $plugin: g, $toggle: this.toggle}, g.mouseOverHandler); + if(!debug){ + e.bind("mouseleave", {settings: g.settings, element: e, $plugin: g, $toggle: this.toggle}, g.mouseOutHandler) + } + } else { + if (g.settings.trigger == "hover") { + e.bind("mouseenter", {settings: g.settings, element: e, $plugin: g}, g.mouseOverHandler); + if(!debug){ + e.bind("mouseleave", {settings: g.settings, element: e, $plugin: g}, g.mouseOutHandler) + } + } else { + if (g.settings.trigger == "focus") { + e.bind("focus", {settings: g.settings, element: e, $plugin: g}, g.mouseOverHandler); + e.bind("blur", {settings: g.settings, element: e, $plugin: g}, g.mouseOutHandler) + } else { + if (g.settings.trigger == "click") { + this.toggle = false; + e.bind("click", {settings: g.settings, element: e, $plugin: g, $toggle: this.toggle}, g.mouseOverHandler); + if (!g.settings.issticky) { + if(!debug){ + e.bind("mouseleave", {settings: g.settings, element: e, $plugin: g, $toggle: this.toggle}, g.mouseOutHandler) + } + } + } + } + } + } + } + }) + }; + function b(d, c) { + this.settings = this.getSettings(d, c); + this.$element = c; + return this + } + b.prototype = { + getSettings: function(f, d) { + var e = (d.data("issticky") != null) ? ((d.data("issticky") == "true") ? true : false) : true; + var c = a.extend({}, f, { + location: d.data("location"), + title: d.data("title"), + backcolor: d.data("backcolor"), + textalign: d.data("textalign"), + trigger: d.data("trigger"), + textcolor: d.data("textcolor"), + opacity: d.data("opacity"), + templatename: d.data("templatename"), + width: d.data("width"), + margin: d.data("margin"), + padding: d.data("padding"), + delay: d.data("delay"), + issticky: e, + container: d.data("container"), + shadow: d.data("shadow") + }); + return c + }, mouseOverHandler: function(n) { + if (typeof n.data.settings.onUpdate == "function") { + n.data.settings.title = n.data.settings.onUpdate.call(this) + } + if (n.data.element.is("input")) { + if (n.data.element.val() != "") { + return false + } + } + if (n.data.settings.trigger == "click") { + if (!n.data.$toggle) { + n.data.$toggle = true; + this.toggle = true; + n.data.element.unbind("click"); + n.data.element.bind("click", { + settings: n.data.settings, + element: n.data.element, + $plugin: n.data.$plugin, + $toggle: n.data.$toggle + }, + n.data.$plugin.mouseOutHandler) + } else { + n.data.$toggle = false; + this.toggle = false; + return false + } + } + var c = n.data.element; + var d = n.data.settings; + var R = parseInt(d.margin.toString().replace("px", "")); + var T = parseInt(d.padding.toString().replace("px", "")); + var Y = parseInt(d.width.toString().replace("px", "")); + var Q = d.container == "body" ? d.location : "none"; + var N = d.backcolor; + var X = d.textcolor; + var W = d.textalign; + var V = d.templatename; + var P = d.delay; + var K = a(d.template); + K.css({opacity: d.opacity}); + K.css("visibility", "visible"); + K.find(".tooltip-content").css({"text-align": W}).html(d.title + d.clearfix); + K.find(".tooltip-content").css({padding: T + "px"}); + + K.find(".tooltip-content p").css({background: N}); + K.find(".tooltip-content p").css({color: X}); +// K.find(".tooltip-content").css({background: N}); +// K.find(".tooltip-content").css({color: X}); + if (d.shadow == 1) { + K.find(".tooltip-content").css({"box-shadow": "1px 1px 3px 0px #888888"}) + } + var M = Q; + var L = Q.split("-")[0]; + var E = M; + var D = L; + K.removeClass(Q).addClass(M); + K.find(".tooltip-arrow").removeClass(Q).addClass(M).css("border-" + L + "-color", N); + var l = d.container; + if (d.container != "body") { + K.addClass("incontainer"); + l = "#" + d.container; + a(l).children().each(function() { + a(this).remove() + }) + } else { + K.removeClass("incontainer"); + l = "body" + } + a(l).append(K); + if (n.data.settings.trigger == "click") { + var O = a('
    '); + O.css({ + width: "100%", + height: "100%", + position: "absolute", + top: a(document).scrollTop() + "px", + left: "0px" + }); + a("body").append(O); + O.bind("click", {settings: n.data.settings, element: n.data.element, $plugin: n.data.$plugin, $toggle: n.data.$toggle}, n.data.$plugin.mouseOutHandler); + n.data.$toggle = false; + this.toggle = false + } else { + if (n.data.settings.trigger == "hoverable") { + n.data.element.unbind("mouseenter") + } + } + if (d.container == "body") { + K.offset({top: 0, left: 0}); + var ab = K.outerWidth(); + var Z = K.outerHeight(); + var ae = a(document).width(); + var G = scrollbarWidth(); + var ac = a(document).width() - a(window).width(); + if (ac > 0) { + ae = ae - G + } + if (ae > a(window).width()) { + ae = a(window).width() - G + } + var ad = a(document).height(); + if (ac > G) { + ad = ad - G + } + if (Y != 0) { + if (Y * 2 > ae) { + Y = Math.floor((ae / 2) - 30) + } else { + Y -= 30 + } + if (Y * 1.5 > ae / 2) { + Y = Math.floor((ae / 2) - 30) + } + } else { + if (340 * 2 > ae) { + Y = Math.floor((ae / 2) - 30) + } else { + Y = 340 + } + } + K.css({"max-width": Y}); + ab = K.outerWidth(); + Z = K.outerHeight(); + var J = c.context; + var r = J.offsetWidth; + var o = J.offsetHeight; + var q = c.offset().top; + var p = c.offset().left; + if (J.tagName.toLowerCase() == "area") { + var g = J.parentElement.getAttribute("name"); + var h = J.getAttribute("shape").toLowerCase(); + var x = a("img[usemap='#" + g + "']").offset().top; + var w = a("img[usemap='#" + g + "']").offset().left; + var j = parseInt(J.getAttribute("coords").split(",")[0]); + var k = parseInt(J.getAttribute("coords").split(",")[1]); + var i = parseInt(J.getAttribute("coords").split(",")[2]); + var f = parseInt(J.getAttribute("coords").split(",")[3] || i); + var v = {top: parseInt(x + k), left: parseInt(w + j)}; + if (h == "circle") { + v = {top: parseInt(x + k - i), left: parseInt(w + j - i)}; + i *= 2; + f *= 2 + } + if (h == "rect") { + v = {top: parseInt(x + k), left: parseInt(w + j)}; + i = i - j; + f = f - k + } + if (h == "poly") { + var m = new Array(); + var H = J.getAttribute("coords").split(","); + for (var y = 0; y < H.length; ) { + m.push({x: parseInt(H[y]), y: parseInt(H[y + 1])}); + y = y + 2 + } + m.sort(function(e, af) { + var ag = e.x, ah = af.x; + if (ag == ah) { + return 0 + } + return ag < ah ? 1 : -1 + }); + var z = m[0].x; + m.sort(function(e, af) { + var ag = e.y, ah = af.y; + if (ag == ah) { + return 0 + } + return ag < ah ? 1 : -1 + }); + var A = m[0].y; + m.sort(function(e, af) { + var ag = e.x, ah = af.x; + if (ag == ah) { + return 0 + } + return ag > ah ? 1 : -1 + }); + var B = m[0].x; + m.sort(function(e, af) { + var ag = e.y, ah = af.y; + if (ag == ah) { + return 0 + } + return ag > ah ? 1 : -1 + }); + var C = m[0].y; + v = {top: parseInt(x + C), left: parseInt(w + B)}; + i = z - B; + f = A - C + } + p = v.left; + q = v.top; + r = i; + o = f + } + p = Math.round(p); + q = Math.round(q); + r = Math.round(r); + o = Math.round(o); + K.offset({top: 0, left: 0}); + var S; + switch (Q) { + case "top": + S = {top: (q - Z - R), left: p - (ab / 2) + (r / 2)}; + break; + case "top-left": + S = {top: (q - Z - R), left: p}; + break; + case "top-right": + S = {top: (q - Z - R), left: p - ab + r}; + break; + case "right": + S = {top: (q + (o / 2) - (Z / 2)), left: p + r + R}; + break; + case "right-top": + S = {top: (q + o - Z + 8), left: p + r + R}; + break; + case "right-bottom": + S = {top: q - 8, left: p + r + R}; + break; + case "bottom": + S = {top: (q + o + R), left: p - (ab / 2) + (r / 2)}; + break; + case "bottom-left": + S = {top: (q + o + R), left: p}; + break; + case "bottom-right": + S = {top: (q + o + R), left: p - ab + r}; + break; + case "left": + S = {top: (q + (o / 2) - (Z / 2)), left: p - ab - R}; + break; + case "left-top": + S = {top: (q + o - Z + 8), left: p - ab - R}; + break; + case "left-bottom": + S = {top: q - 8, left: p - ab - R}; + break + } + var F = {top: 0, left: 0}; + F.left = S.left; + F.top = S.top; + var aa = (((M.match("bottom") != null) || (M == "left") || (M == "right")) ? (((M == "left") || (M == "right")) ? (Z / 2) : (Z)) > (ad - q - o) : false); + if ((S.left < 0) || (S.top < 0) || (S.left + ab > ae) || aa) { + if (L == "top" || L == "bottom" || L == "left" || L == "right") { + var u = false; + switch (L) { + case "top": + S.top = q - Z - R; + S.left = p - (ab / 2) + (r / 2); + u = true; + break; + case "bottom": + S.top = q - Z - R; + S.left = p - (ab / 2) + (r / 2); + u = true; + break; + case "left": + var I = M.replace(L + "-", ""); + if (I == "top") { + L = "top"; + M = "top-left"; + K.removeClass(E).addClass(M); + K.find(".tooltip-arrow").removeClass(E).css("border-" + D + "-color", "").addClass(M).css("border-" + L + "-color", N); + D = "top"; + E = "top-left"; + K.removeClass(Q).addClass(M); + K.find(".tooltip-arrow").removeClass(Q).addClass(M).css("border-" + L + "-color", N); + ab = K.outerWidth(); + Z = K.outerHeight(); + S.top = q - Z - R; + S.left = p - (ab / 2) + (r / 2); + F.left = p; + F.top = q - Z - R; + aa = (((M.match("bottom") != null) || (M == "left") || (M == "right")) ? (((M == "left") || (M == "right")) ? (Z / 2) : (Z)) > (ad - q - o) : false); + if ((S.left < 0) || (S.top < 0) || (S.left + ab > ae) || aa) { + u = true + } else { + S.left = F.left; + S.top = F.top + } + } else { + if (I == "bottom") { + L = "bottom"; + M = "bottom-left"; + K.removeClass(E).addClass(M); + K.find(".tooltip-arrow").removeClass(E).css("border-" + D + "-color", "").addClass(M).css("border-" + L + "-color", N); + D = "bottom"; + E = "bottom-left"; + K.removeClass(Q).addClass(M); + K.find(".tooltip-arrow").removeClass(Q).addClass(M).css("border-" + L + "-color", N); + ab = K.outerWidth(); + Z = K.outerHeight(); + S.top = q + o + R; + S.left = p - (ab / 2) + (r / 2); + F.left = p; + F.top = q + o + R; + aa = (((M.match("bottom") != null) || (M == "left") || (M == "right")) ? (((M == "left") || (M == "right")) ? (Z / 2) : (Z)) > (ad - q - o) : false); + if ((S.left < 0) || (S.top < 0) || (S.left + ab > ae) || aa) { + u = true + } else { + S.left = F.left; + S.top = F.top + } + } else { + L = "top"; + M = "top"; + K.removeClass(E).addClass(M); + K.find(".tooltip-arrow").removeClass(E).css("border-" + D + "-color", "").addClass(M).css("border-" + L + "-color", N); + D = "top"; + E = "top"; + K.removeClass(Q).addClass(M); + K.find(".tooltip-arrow").removeClass(Q).addClass(M).css("border-" + L + "-color", N); + ab = K.outerWidth(); + Z = K.outerHeight(); + S.top = q - Z - R; + S.left = p - (ab / 2) + (r / 2); + F.left = S.left; + F.top = S.top; + aa = (((M.match("bottom") != null) || (M == "left") || (M == "right")) ? (((M == "left") || (M == "right")) ? (Z / 2) : (Z)) > (ad - q - o) : false); + if ((S.left < 0) || (S.top < 0) || (S.left + ab > ae) || aa) { + u = true + } else { + S.left = F.left; + S.top = F.top + } + } + } + break; + case "right": + var I = M.replace(L + "-", ""); + if (I == "top") { + L = "top"; + M = "top-left"; + K.removeClass(E).addClass(M); + K.find(".tooltip-arrow").removeClass(E).css("border-" + D + "-color", "").addClass(M).css("border-" + L + "-color", N); + D = "top"; + E = "top-left"; + K.removeClass(Q).addClass(M); + K.find(".tooltip-arrow").removeClass(Q).addClass(M).css("border-" + L + "-color", N); + ab = K.outerWidth(); + Z = K.outerHeight(); + S.top = q - Z - R; + S.left = p - (ab / 2) + (r / 2); + F.left = p; + F.top = q - Z - R; + aa = (((M.match("bottom") != null) || (M == "left") || (M == "right")) ? (((M == "left") || (M == "right")) ? (Z / 2) : (Z)) > (ad - q - o) : false); + if ((S.left < 0) || (S.top < 0) || (S.left + ab > ae) || aa) { + u = true + } else { + S.left = F.left; + S.top = F.top + } + } else { + if (I == "bottom") { + L = "bottom"; + M = "bottom-left"; + K.removeClass(E).addClass(M); + K.find(".tooltip-arrow").removeClass(E).css("border-" + D + "-color", "").addClass(M).css("border-" + L + "-color", N); + D = "bottom"; + E = "bottom-left"; + K.removeClass(Q).addClass(M); + K.find(".tooltip-arrow").removeClass(Q).addClass(M).css("border-" + L + "-color", N); + ab = K.outerWidth(); + Z = K.outerHeight(); + S.top = q - Z - R; + S.left = p - (ab / 2) + (r / 2); + F.left = p; + F.top = q + o + R; + aa = (((M.match("bottom") != null) || (M == "left") || (M == "right")) ? (((M == "left") || (M == "right")) ? (Z / 2) : (Z)) > (ad - q - o) : false); + if ((S.left < 0) || (S.top < 0) || (S.left + ab > ae) || aa) { + u = true + } else { + S.left = F.left; + S.top = F.top + } + } else { + L = "top"; + M = "top"; + K.removeClass(E).addClass(M); + K.find(".tooltip-arrow").removeClass(E).css("border-" + D + "-color", "").addClass(M).css("border-" + L + "-color", N); + D = "top"; + E = "top"; + K.removeClass(Q).addClass(M); + K.find(".tooltip-arrow").removeClass(Q).addClass(M).css("border-" + L + "-color", N); + ab = K.outerWidth(); + Z = K.outerHeight(); + S.top = q - Z - R; + S.left = p - (ab / 2) + (r / 2); + F.left = S.left; + F.top = S.top; + aa = (((M.match("bottom") != null) || (M == "left") || (M == "right")) ? (((M == "left") || (M == "right")) ? (Z / 2) : (Z)) > (ad - q - o) : false); + if ((S.left < 0) || (S.top < 0) || (S.left + ab > ae) || aa) { + u = true + } else { + S.left = F.left; + S.top = F.top + } + } + } + break + } + if (u) { + var s = false; + var t = false; + if (S.top < 0) { + L = "bottom"; + M = "bottom"; + S.top = q + o + R; + t = true; + if (S.left < 0) { + L = "bottom"; + M = "bottom-left"; + S.left = p; + s = true + } + if (S.left + ab > ae) { + S.left = p - ab + r; + if (S.left < 0) { + L = "bottom"; + M = "bottom"; + S.left = p - (ab / 2) + (r / 2); + s = true + } else { + L = "bottom"; + M = "bottom-right"; + S.left = p - ab + r; + s = true + } + } + } else { + L = "top"; + M = "top"; + S.top = q - Z - R; + t = false; + if (S.left < 0) { + L = "top"; + M = "top-left"; + S.left = p; + s = true + } + if (S.left + ab > ae) { + S.left = p - ab + r; + if (S.left < 0) { + L = "top"; + M = "top"; + S.left = p - (ab / 2) + (r / 2); + s = true + } else { + L = "top"; + M = "top-right"; + S.left = p - ab + r; + s = true + } + } + } + if (!s) { + if (t) { + M = E.replace("top", "bottom"); + L = D.replace("top", "bottom"); + if (F.left < 0) { + if (L == "bottom" || L == "top") { + M = M.replace("right", "left"); + S.left = p + } + } else { + S.left = F.left + } + } else { + M = E.replace("bottom", "top"); + L = D.replace("bottom", "top"); + if (F.left < 0) { + if (L == "bottom" || L == "top") { + M = M.replace("right", "left"); + S.left = p + } + } else { + S.left = F.left + } + } + } + } + } + } + K.removeClass(E).addClass(M); + K.find(".tooltip-arrow").removeClass(E).css("border-" + D + "-color", "").addClass(M).css("border-" + L + "-color", N); + if (V != "") { + if (K.find(".tooltip-content > .template").hasClass("template")) { + K.find(".tooltip-content > .template").addClass(V); + var U = K.find("." + V).css("background-color"); +// K.find(".tooltip-arrow").css("border-" + D + "-color", ""); +// K.find(".tooltip-arrow").css("border-" + L + "-color", U); + //K.find(".tooltip-content").css({background: U}) // Fix background-color + } else { + if (K.find(".tooltip-content > .tooltip-menu").hasClass("tooltip-menu")) { + K.find(".tooltip-content > .tooltip-menu").addClass(V); + var U = K.find("." + V).css("background-color"); + K.find(".tooltip-arrow").css("border-" + D + "-color", ""); + K.find(".tooltip-arrow").css("border-" + L + "-color", U); + K.find(".tooltip-content").css({background: U}) + } + } + } + K.find(".tooltip-content > .video-wrapper").css({width: (K.width() - (T * 2)) + "px"}); + K.offset(S) + } + K.hide(); + c.removeAttr("title"); + c.removeAttr("alt"); + if (n.data.settings.trigger == "hoverable" || n.data.settings.trigger == "click") { + P = 0 + } + switch (L) { + case "top": + K.delay(P).css({top: "-=20", opacity: 0, display: "block"}).stop(true, true).animate({top: "+=20", opacity: d.opacity}, 150); + break; + case "bottom": + K.delay(P).css({top: "+=20", opacity: 0, display: "block"}).stop(true, true).animate({top: "-=20", opacity: d.opacity}, 150); + break; + case "left": + K.delay(P).css({left: "-=20", opacity: 0, display: "block"}).stop(true, true).animate({left: "+=20", opacity: d.opacity}, 150); + break; + case "right": + K.delay(P).css({left: "+=20", opacity: 0, display: "block"}).stop(true, true).animate({left: "-=20", opacity: d.opacity}, 150); + break; + default: + K.delay(P).css({opacity: 0, display: "block"}).stop(true, true).animate({opacity: d.opacity}, 150); + break + } + n.data.$plugin.tooltip = K; + n.data.$plugin.location = Q; + n.data.$plugin.tooltip_arrow_border = L; + K = null; + return false + }, mouseOutHandler: function(d) { + var f = d.data.$plugin.tooltip; + var g = d.data.$plugin.location; + var c = false; + if (d.data.settings.trigger != "hoverable") { + if (d.data.settings.trigger == "hover") { + a(f).delay(d.data.settings.delay); + c = true + } else { + c = true; + if (d.data.settings.trigger == "click") { + if (!d.data.settings.issticky) { + d.data.settings.interval = setInterval(function() { + a(f).fadeOut(0, function() { + a(d.data.$plugin.tooltip).remove() + }); + clearInterval(d.data.settings.interval); + this.toggle = false; + d.data.$toggle = false; + d.data.element.unbind("click"); + d.data.element.unbind("mouseleave"); + d.data.element.bind("click", {settings: d.data.settings, element: d.data.element, $plugin: d.data.$plugin, $toggle: false}, d.data.$plugin.mouseOverHandler); + d.data.element.bind("mouseleave", {settings: d.data.settings, element: d.data.element, $plugin: d.data.$plugin, $toggle: false}, d.data.$plugin.mouseOutHandler) + }, d.data.settings.delay == 0 ? 2000 : d.data.settings.delay); + d.data.element.unbind("mouseleave"); + a(f).find(".tooltip-content").bind("mouseenter", {settings: d.data.settings, element: d.data.element, $plugin: d.data.$plugin, $toggle: true}, function() { + d.data.element.unbind("click"); + d.data.element.unbind("mouseleave"); + this.toggle = true; + d.data.$toggle = true; + clearInterval(d.data.settings.interval) + }); + a(f).find(".tooltip-content").bind("mouseleave", {settings: d.data.settings, element: d.data.element, $plugin: d.data.$plugin, $toggle: d.data.$toggle}, function() { + a(f).fadeOut(0, function() { + a(d.data.$plugin.tooltip).remove() + }); + this.toggle = false; + d.data.$toggle = false; + d.data.element.unbind("click"); + d.data.element.unbind("mouseleave"); + d.data.element.bind("click", {settings: d.data.settings, element: d.data.element, $plugin: d.data.$plugin, $toggle: false}, d.data.$plugin.mouseOverHandler); + d.data.element.bind("mouseleave", {settings: d.data.settings, element: d.data.element, $plugin: d.data.$plugin, $toggle: false}, d.data.$plugin.mouseOutHandler) + }); + c = false + } else { + c = true + } + } + } + } else { + d.data.settings.interval = setInterval(function() { + a(f).fadeOut(0, function() { + a(d.data.$plugin.tooltip).remove() + }); + clearInterval(d.data.settings.interval); + d.data.element.unbind("mouseleave"); + d.data.element.unbind("mouseenter"); + d.data.element.bind("mouseenter", {settings: d.data.settings, element: d.data.element, $plugin: d.data.$plugin, $toggle: false}, d.data.$plugin.mouseOverHandler); + d.data.element.bind("mouseleave", {settings: d.data.settings, element: d.data.element, $plugin: d.data.$plugin, $toggle: false}, d.data.$plugin.mouseOutHandler) + }, d.data.settings.delay == 0 ? 2000 : d.data.settings.delay); + d.data.element.unbind("mouseleave"); + a(f).find(".tooltip-content").bind("mouseenter", {settings: d.data.settings, element: d.data.element, $plugin: d.data.$plugin, $toggle: true}, function() { + d.data.element.unbind("mouseenter"); + d.data.element.unbind("mouseleave"); + this.toggle = true; + d.data.$toggle = true; + clearInterval(d.data.settings.interval) + }); + a(f).find(".tooltip-content").bind("mouseleave", {settings: d.data.settings, element: d.data.element, $plugin: d.data.$plugin, $toggle: true}, function() { + a(f).fadeOut(0, function() { + a(d.data.$plugin.tooltip).remove() + }); + this.toggle = false; + d.data.$toggle = false; + d.data.element.unbind("mouseleave"); + d.data.element.unbind("mouseenter"); + d.data.element.bind("mouseenter", {settings: d.data.settings, element: d.data.element, $plugin: d.data.$plugin, $toggle: false}, d.data.$plugin.mouseOverHandler); + d.data.element.bind("mouseleave", {settings: d.data.settings, element: d.data.element, $plugin: d.data.$plugin, $toggle: false}, d.data.$plugin.mouseOutHandler) + }); + c = false + } + if (c) { + switch (d.data.$plugin.tooltip_arrow_border) { + case "top": + a(f).stop(true, true).animate({top: "-=20", opacity: 0}, 150, function() { + a(d.data.$plugin.tooltip).remove() + }); + break; + case "bottom": + a(f).stop(true, true).animate({top: "+=20", opacity: 0}, 150, function() { + a(d.data.$plugin.tooltip).remove() + }); + break; + case "left": + a(f).stop(true, true).animate({left: "-=20", opacity: 0}, 150, function() { + a(d.data.$plugin.tooltip).remove() + }); + break; + case "right": + a(f).stop(true, true).animate({left: "+=20", opacity: 0}, 150, function() { + a(d.data.$plugin.tooltip).remove() + }); + break + } + a(d.data.$plugin.tooltip).remove() + } + if (d.data.settings.trigger == "click") { + if (d.data.$toggle) { + a("body").find("#tooltip-clickoutside").remove(); + this.toggle = false; + d.data.$toggle = false; + d.data.element.unbind("click"); + d.data.element.unbind("mouseleave"); + d.data.element.bind("click", {settings: d.data.settings, element: d.data.element, $plugin: d.data.$plugin, $toggle: d.data.$toggle}, d.data.$plugin.mouseOverHandler); + if (!d.data.settings.issticky) { + d.data.element.bind("mouseleave", {settings: d.data.settings, element: d.data.element, $plugin: d.data.$plugin, $toggle: d.data.$toggle}, d.data.$plugin.mouseOutHandler) + } + } + } + return false + }}; + scrollbarWidth = function() { + var c = a('
    '); + a("body").append(c); + var d = a("div", c).innerWidth(); + c.css("overflow", "scroll"); + var e = a("div", c).innerWidth(); + a(c).remove(); + return (d - e) + }; + a.fn.LiteTooltip.defaultSettings = { + location: "top", + title: "", + opacity: 0.89, + backcolor: "#000000", + textcolor: "#ffffff", + template: '
    ', + margin: 5, + padding: 10, + width: 0, + textalign: "center", + trigger: "hover", + templatename: "", + delay: 0, + issticky: true, + clearfix: '
    ', + container: "body", + shadow: 1 + } +})(jQuery); \ No newline at end of file diff --git a/modules/appagebuilder/js/admin/detail.js b/modules/appagebuilder/js/admin/detail.js new file mode 100644 index 00000000..2a61e7fb --- /dev/null +++ b/modules/appagebuilder/js/admin/detail.js @@ -0,0 +1,574 @@ +/** + * @Website: apollotheme.com - prestashop template provider + * @author Apollotheme + * @copyright 2007-2018 Apollotheme + * @description: + */ +var windowWidth = $(window).width(); +var currentId; +var currentConfig; +$(document).ready(function() { + //only for product generate + $(".adminappagebuilderdetails #nav-sidebar").trigger("click"); + + $('.plist-eedit').click(function(){ + element = $(this).data('element'); + $.fancybox.open([{ + type: 'iframe', + href : ($('#appagebuilder_products_form').length?$('#appagebuilder_products_form').attr('action'):$('#appagebuilder_details_form').attr('action')) + '&pelement=' + element, + afterLoad:function(){ + if( $('body',$('.fancybox-iframe').contents()).find("#main").length ){ + hideSomeElement(); + $('.fancybox-iframe').load( hideSomeElement ); + }else { + $('body',$('.fancybox-iframe').contents()).find("#psException").html('
    Can not find this element
    '); + } + }, + afterClose: function (event, ui) { + } + }], { + padding: 10 + }); + }); + + $('.element-list .plist-element').draggable({ + connectToSortable: ".product-container .content", + revert: "true", + helper: "clone", + handle: ".gaction-drag", + stop: function() { + $( ".product-container .content" ).sortable({ + revert: false + }); + setProFormAction(); + setSortAble(); + } + }); + + $('.show-postion').click(function(){$("#postion_layout img").show()}); + $('.postion-img-co').click(function(){$("#postion_layout img").toggle()}); + + + $(document).on("click", ".column-add", function () { + createColumn(this); + $(currentId).find('.btn-add-column').trigger( "click" ); + editcolumn(); + //DONGND:: re-call event for new element + setProFormAction(); + setSortAble(); + }); + setProFormAction(); + setSortAble(); + + $('body').on('click', function (e) { + $('[data-toggle=popover]').each(function () { + // hide any open popovers when the anywhere else in the body is clicked + if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) { + $(this).popover('hide'); + } + }); + }); + + widthselect(); + setCssClass(); + saveData(); + thumbconfig(); + //DONGND:: add config for zoom + zoomconfig(); + + $('#saveAndStay').click(function(event){ + event.preventDefault(); + $('input[name=submitAddappagebuilder_details]').val('1'); + genreateForm(); + $('#appagebuilder_details_form').submit(); + return false; + }); + + //DONGND:: setup ui for element + $('.ap_proGrid .row, .ap_proGrid .column-row').addClass('ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'); + $('.ap_proGrid .gaction-drag, .ap_proGrid .caction-drag, .ap_proGrid .waction-drag').addClass('ui-widget-header ui-corner-all'); +}); + +function thumbconfig(){ + $('.select_thumb').change(function(){ + if($(this).val() == 'none') + $(this).closest('.formmodal').find('.select_thumb-none').hide(); + else + $(this).closest('.formmodal').find('.select_thumb-none').show(); + }); +} + +//DONGND:: add config for zoom +function zoomconfig(){ + $('.select_zoom').change(function(){ + if($(this).val() == 'none' || $(this).val() == 'in' || $(this).val() == 'in_scrooll') + $(this).closest('.formmodal').find('.select-zoom-none').hide(); + else + $(this).closest('.formmodal').find('.select-zoom-none').show(); + }); +} + +function genreateForm(){ + //generate grid first + var ObjectFrom = {}; + ObjectFrom.gridLeft = returnObjElemnt('.ap_proGrid .gridLeft-block-content'); + ObjectFrom.class = $("#main_class").val(); + // console.log(ObjectFrom); + $('input[name=params]').val(JSON.stringify(ObjectFrom)); +} + +function returnObjElemnt(element){ + var Object = {}; + // console.log(element); + $(element).children().each(function(iElement){ + var Obj = {}; + Obj.name = $(this).data('element'); + if($(this).data("form") == undefined || $(this).data("form") == "" || $(this).data("form") == '\"\"') + Obj.form = ""; + else + Obj.form = $(this).data('form'); + + if(Obj.name=='product_image_with_thumb'){ + if (Obj.form.templateview == 'left' || Obj.form.templateview == 'right' || Obj.form.templateview == 'bottom') + $("#main_class").val('product-image-thumbs product-thumbs-'+Obj.form.templateview); + else $("#main_class").val('product-image-thumbs no-thumbs'); + } + + if(Obj.name=='product_image_show_all'){ + $("#main_class").val('product-image-gallery'); + } + + if($(this).hasClass('functional_buttons')){ + + Obj.columns = {}; + $(this).find('.column-row').each(function(yElement){ + var ObjectColumn = {}; + ObjectColumn.form = $(this).data('form'); + ObjectColumn.element = 'column'; + ObjectColumn.sub = returnObjElemnt($('.content', $(this))); + Obj.columns[yElement] = ObjectColumn; + }); + } + if($(this).hasClass('code')){ + Obj.code = replaceSpecialString($('textarea', $(this)).val()); + } + + Object[iElement] = Obj; + }); + //console.log($(element).children()); + //console.log(Object); + + return Object; +} +function replaceSpecialString(str){ + return str.replace(/\t/g, "_APTAB_").replace(/\r/g, "_APNEWLINE_").replace(/\n/g, "_APENTER_").replace(/"/g, "_APQUOT_").replace(/'/g, "_APAPOST_"); +} +function saveData(){ + $(".btn-savewidget").click(function(){ + // console.log($(".formmodal")); + var data = getFormData($(".formmodal")); + // console.log(data); + $("#modal_form .close").trigger('click'); + $(currentConfig).data('form', data); + }); +} + +function getFormData($form){ + var unindexed_array = $form.serializeArray(); + var indexed_array = {}; + + if($(currentConfig).hasClass('column-row')) + { + $(currentConfig).attr('class', 'column-row plist-element'); + } + + $.map(unindexed_array, function(n, i){ + if(n['name']!='hidden_from[]') + indexed_array[n['name']] = n['value']; + //process class of column + if($(currentConfig).hasClass('column-row') && (n['name'] == 'xl' || n['name'] == 'lg' || n['name'] == 'md' || n['name'] == 'sm' || n['name'] == 'xs' || n['name'] == 'sp')) + $(currentConfig).addClass('col-'+n['name']+'-'+n['value']); + + }); + + return indexed_array; +} + +function hideSomeElement(){ + $('body',$('.fancybox-iframe').contents()).addClass("page-sidebar-closed"); +} + +function setSortAble(){ + $( ".product-container .content" ).sortable({ + connectWith: ".content", + }); +} + +function setCssClass(){ + if ($(".select-class").length) { + $(".select-class").click(function () { + if ($(this).is(':checked')) { + + $('.select-class').each(function() { + // REMOVE ALL CHECKBOX VALUE IN TEXT + var classChk = $(this).data("value"); + input_text = $(this).closest('.well').find('.element_class').first().val(); + // trim string + var input_text = input_text.replace(classChk, ""); + input_text = input_text.split(" ").join(" "); + input_text = $.trim(input_text); + + $(this).closest('.well').find('.element_class').first().val(input_text); + }); + + var classChk = $(this).data("value"); + var elementText = $(this).closest('.well').find('.element_class').first(); + + // SET VALUE CHECKBOX TO TEXT + if ($(elementText).val().indexOf(classChk) == -1) { + if ($(elementText).val() != "") { + $(elementText).val($(elementText).val() + " " + classChk); + } else { + $(elementText).val(classChk); + } + } + } + }); + + $(".chk-row").click(function () { + var classChk = $(this).data("value"); + var elementText = $(this).closest('.well').find('.element_class').first(); + if ($(elementText).val().indexOf(classChk) == -1) { + // NOT EXIST AND ADD + if ($(elementText).val() != "") { + $(elementText).val($(elementText).val() + " " + classChk); + } else { + $(elementText).val(classChk); + } + }else{ + // EXIST AND REMOVE + var find = classChk; + var re = new RegExp(find, 'g'); + var text = $(elementText).val(); + text = text.replace(re, ''); + $(elementText).val(text); + } + }); + + $(".element_class").change(function () { + elementChk = $(this).closest('.well').find('input[type=checkbox]'); + classText = $(this).val(); + $(elementChk).each(function () { + classChk = $(this).data("value"); + if (classText.indexOf(classChk) != -1) { + if (!$(this).is(':checked')) + $(this).prop("checked", true); + } else { + $(this).prop("checked", false); + } + }); + }); + $(".element_class").trigger("change"); + } +} + +//set action when c +function setProFormAction(){ + $('#home_wrapper .plist-code').each(function(){ + if(!$(this).hasClass('setaction')){ + $(this).click(function(){ + textAre = $(this).closest('.plist-element').find('textarea').first(); + if(textAre.attr('rows') == 20) + $(textAre).attr('rows',5); + else + $(textAre).attr('rows',20); + }); + $(this).addClass('setaction'); + } + + }); + + $('#home_wrapper .btn-add-column').each(function(){ + + if(!$(this).hasClass('setaction')){ + $(this).popover({ + html: true, + content: function () { + currentId = $(this).closest('.plist-element'); + return $('#addnew-column-form').html(); + } + }); + $(this).mousedown(function(){ + // toggle popover when link is clicked + $(this).popover('toggle'); + }); + + $(this).addClass('setaction'); + } + + }); + + $('#home_wrapper .plist-eremove').each(function(){ + if(!$(this).hasClass('setaction')){ + $(this).click(function(){ + if(!confirm("Are you sure to remove?")) return false; + $(this).closest('.plist-element').remove(); + $(this).addClass('setaction'); + }); + } + }); + + $('#home_wrapper .btn-edit-group').each(function(){ + if(!$(this).hasClass('setaction')){ + $(this).click(function(){ + currentConfig = $(this).closest('.plist-element'); + $('#modal_form .modal-footer').show(); + + $('#modal_form .modal-body').html(''); + + column_config = $("#group_config").clone(true); + + //load config + data = $(currentConfig).data('form'); + column_config = setData(data, column_config); + $('#modal_form .modal-body').append('
    '); + $('#modal_form .formmodal').append(column_config); + + $('#modal_form').removeClass('modal-new').addClass('modal-edit'); + $("#modal_form").modal({ + "backdrop": "static" + }); + }); + $(this).addClass('setaction'); + } + }); + + $('#home_wrapper .element-config').each(function(){ + if(!$(this).hasClass('setaction')){ + $(this).click(function(){ + currentConfig = $(this).closest('.plist-element'); + $('#modal_form .modal-footer').show(); + + $('#modal_form .modal-body').html(''); + + dataconfig = $(this).data('config'); + + column_config = $("#"+dataconfig).clone(true); + //load config + + data = $(currentConfig).data('form'); + + column_config = setData(data, column_config); + + if($(column_config).find('.select_thumb').val() == 'none') + $(column_config).find('.select_thumb-none').hide(); + else + $(column_config).find('.select_thumb-none').show(); + + //DONGND:: add zoom config + if($(column_config).find('.select_zoom').val() == 'none' || $(column_config).find('.select_zoom').val() == 'in' || $(column_config).find('.select_zoom').val() == 'in_scrooll') + $(column_config).find('.select-zoom-none').hide(); + else + $(column_config).find('.select-zoom-none').show(); + + $('#modal_form .modal-body').append('
    '); + $('#modal_form .formmodal').append(column_config); + + $('#modal_form').removeClass('modal-new').addClass('modal-edit'); + $("#modal_form").modal({ + "backdrop": "static" + }); + }); + $(this).addClass('setaction'); + } + }); + + editcolumn(); +} +function setData(data, column_config){ + if(!data || data == 'undefined' || data == 'undefined') return column_config; + + Object.keys(data).forEach(function (key) { + //$('.' + key).data('form', dataObj[key]); + $(column_config).find('input[name='+key+']').val(data[key]); + + $(column_config).find('select[name='+key+']').val(data[key]); + + if(key=="class" && $(column_config).find('.select-class').length) + $(column_config).find('.select-class').each(function(){ + if(data[key].indexOf($(this).data('value'))>-1) $(this).prop("checked", true); + }); + if(key=="xl" || key=="lg" || key=="md" || key=="sm" || key=="xs" || key=="sp"){ + classcss = 'width-select-'+key+'-'+data[key]; + classcss = classcss.replace(".", "-"); + $(column_config).find('.'+classcss).trigger('click'); + } + }); + + return column_config; +} +function editcolumn() +{ + $('#home_wrapper .btn-edit-column').each(function(){ + if(!$(this).hasClass('setaction')){ + $(this).click(function(){ + currentConfig = $(this).closest('.plist-element'); + + $('#modal_form .modal-body').html(''); + + $('#modal_form .modal-footer').show(); + + data = $(currentConfig).data('form'); + //console.log(data); + column_config = $("#column_config").clone(true); + column_config = setData(data, column_config); + + $('#modal_form .modal-body').append('
    '); + $('#modal_form .formmodal').append(column_config); + + $('#modal_form').removeClass('modal-new').addClass('modal-edit'); + $("#modal_form").modal({ + "backdrop": "static" + }); + //widthselect(); + }); + $(this).addClass('setaction'); + } + }); +} +function widthselect(){ + $('.width-select').each(function(){ + if(!$(this).hasClass('setaction')){ + $('.width-select').click(function () { + btnGroup = $(this).closest('.btn-group'); + spanObj = $('.width-val', $(this)); + width = $(spanObj).data('width'); + $('.col-val', $(btnGroup)).val(width); + $('.apbtn-width .width-val', $(btnGroup)).html($(spanObj).html()); + $('.apbtn-width .width-val', $(btnGroup)).attr('class', $(spanObj).attr('class')); + }); + $(this).addClass('setaction'); + } + }); +} +function createColumn(obj) { + var widthCol = $(obj).data('width'); + var classActive = returnWidthClass(); + var col = $(obj).data('col'); + var realValue = widthCol.toString().replace('.', '-'); + for (var i = 1; i <= col; i++) { + wrapper = currentId.find('.group'); + + column = $('#default_column').clone(); + var cls = $(column).attr("class"); + //column-row col-sp-12 col-xs-12 col-sm-12 col-md-12 col-lg-12 ui-widget ui-widget-content ui-helper-clearfix ui-corner-all + cls = cls.replace("col-xl-12", "col-xl-" + realValue); + cls = cls.replace("col-lg-12", "col-lg-" + realValue); + cls = cls.replace("col-md-12", "col-md-" + realValue); + cls = cls.replace("col-sm-12", "col-sm-" + realValue); + cls = cls.replace("col-xs-12", "col-xs-" + realValue); + cls = cls.replace("col-sp-12", "col-sp-" + realValue); + $(column).attr("class", cls); + objColumn = {form_id: "form_" + getRandomNumber()}; + if (classActive == "md" || classActive == "lg" || classActive == "xl") { + objColumn.md = widthCol; + objColumn.lg = widthCol; + objColumn.xl = widthCol; + } + //DONGND:: set default for sm, xs, sp + objColumn.sm = 12; + objColumn.xs = 12; + objColumn.sp = 12; + //jQuery.extend(objColumn, $globalthis.getColDefault()); + $(column).data("form", objColumn); + + column.removeAttr('id'); + wrapper.append(column); + getNumberColumnInClass(column, classActive); + $(".label-tooltip").tooltip(); + } +} + +function getNumberColumnInClass(obj, type) { + var cls = $(obj).attr("class").split(" "); + var len = cls.length; + var result = ""; + for (var i = 0; i < len; i++) { + if (cls[i].search("col-" + type) >= 0) { + result = cls[i]; + break; + } + } + var temp = result.replace("col-" + type + "-", ""); + $(obj).find(".pull-right .btn-group .btn span:first-child").attr("class", "width-val ap-w-" + temp); + var group = $(obj).find("ul.dropdown-menu-right"); + $(group).find("li").removeClass("selected"); + $(group).find(".col-" + temp).addClass("selected"); +} + +function getRandomNumber() +{ + return (+new Date() + (Math.random() * 10000000000000000)).toString().replace('.', ''); +} +function returnWidthClass(width) { + if (!width) + width = windowWidth; + + if (parseInt(width) >= 1200) + return 'xl'; + if (parseInt(width) >= 992) + return 'lg'; + if (parseInt(width) >= 768) + return 'md'; + if (parseInt(width) >= 576) + return 'sm'; + if (parseInt(width) >= 480) + return 'xs'; + if (parseInt(width) < 480) + return 'sp'; +}; +$(document).on("click", ".btn-fwidth", function () { + $('#home_wrapper').css('width', $(this).data('width')); + + btnElement = $(this); + $('.btn-fwidth').removeClass('active'); + $(this).addClass('active'); + //reset + if ($(this).hasClass('width-default')) { + windowWidth = $(window).width(); + $('#home_wrapper').attr('class', 'default'); + } else { + $('#home_wrapper').attr('class', 'col-' + returnWidthClass(parseInt($(this).data('width')))); + windowWidth = $(this).data('width'); + } + classVal = returnWidthClass(); + $(".column-row", $('#home_wrapper')).each(function () { + valueFra = $(this).data("form")[classVal]; + $(".apbtn-width .width-val", $(this)).attr("class", "width-val ap-w-" + valueFra.toString().replace(".", "-")); + }); + initColumnSetting(); +}); + +function initColumnSetting() { + var classActive = returnWidthClass(); + $(".column-row").each(function () { + getNumberColumnInClass(this, classActive); + }); +} + +function getNumberColumnInClass(obj, type) { + var cls = $(obj).attr("class").split(" "); + var len = cls.length; + var result = ""; + for (var i = 0; i < len; i++) { + if (cls[i].search("col-" + type) >= 0) { + result = cls[i]; + break; + } + } + var temp = result.replace("col-" + type + "-", ""); + $(obj).find(".pull-right .btn-group .btn span:first-child").attr("class", "width-val ap-w-" + temp); + var group = $(obj).find("ul.dropdown-menu-right"); + $(group).find("li").removeClass("selected"); + $(group).find(".col-" + temp).addClass("selected"); +} \ No newline at end of file diff --git a/modules/appagebuilder/js/admin/form.js b/modules/appagebuilder/js/admin/form.js new file mode 100644 index 00000000..e86edad7 --- /dev/null +++ b/modules/appagebuilder/js/admin/form.js @@ -0,0 +1,895 @@ +/* + * @Website: apollotheme.com - prestashop template provider + * @author Apollotheme + * @copyright 2007-2018 Apollotheme + * @description: + */ +function initFullSlider(type) { + var total = parseInt($("#total_slider").val()); + $(".apfullslider-row").addClass("hide"); + $(".apfullslider-row input, .apfullslider-row textarea").removeAttr("name"); +} +function updateListIdFullSlider() { + var listId = ""; + var sep = ""; + $("#list-slider li").each(function() { + listId += sep + $(this).attr("id"); + sep = "|"; + }); + $("#total_slider").val(listId); +} +$(document).ready(function() { + $("#modal_form").draggable({ + handle: ".modal-header" + }); + //close menu + $('.adminappagebuilderhome').addClass('page-sidebar-closed'); +// $('.addnew-group').popover({ +// html: true, +// content: function () { +// return $('#addnew-group-form').html(); +// } +// }); + + // NOT WORK FOR AJAX + $('.form-action').change(function(){ + var elementName = $(this).attr('name'); + $('.'+elementName+'_sub').hide(); + $('.'+elementName+'-'+$(this).val()).show(); + }); + $('.form-action').trigger("change"); + + $('.checkbox-group').change(function(){ + id = $(this).attr('id'); + if($(this).is(':checked')) + $('.'+id).show(); + else + $('.'+id).hide(); + }); + $('.checkbox-group').trigger("change"); + + + $(document).on("click", ".hook-top", function() { + $(".hook-content", $(this).parent()).each(function(){ + $(this).toggle('clip'); + var groupTop = $(".open-group i", $(this).parent()); + if($(groupTop).attr('class').indexOf('up') >-1){ + $(groupTop).attr('class',$(groupTop).attr('class').replace('up', 'down')); + }else{ + $(groupTop).attr('class',$(groupTop).attr('class').replace('down', 'up')); + } + }); + }); + + //DONGND:: fix can't click tab 1 when create new widget tab + // $('.ApTabs .nav-tabs a:first').tab('show'); + // $('.ApTabs:not(#default_ApTabs)').each(function(){ + // console.log($(this).data('form')); + // console.log($(this).attr('form')); + // var data_form = $(this).data(); + // console.log(data_form.type); + // console.log(data_form.form); + // console.log(data_form['form'].active_tab); + // $(this).find('.nav-tabs a:first').tab('show'); + // }) + + $(".ApAccordions").each(function(){ + $('.panel-collapse:first' , $(this)).collapse('show'); + }); + $('.btn-form-toggle').click(function () { + if ($('.displayLeftColumn').hasClass('col-md-3')) { + $('i', $(this)).attr('class', 'icon-resize-small'); + $(".hook-content").hide(); + $(".open-group i").attr('class', $(".open-group i").attr('class').replace('down', 'up')); + $('.displayLeftColumn').removeClass('col-md-3').addClass('col-md-12'); + $('.displayRightColumn').removeClass('col-md-3').addClass('col-md-12'); + $('.home-content-wrapper').removeClass('col-md-6').addClass('col-md-12'); + } else { + $('i', $(this)).attr('class', 'icon-resize-full'); + $(".hook-content").show(); + $(".open-group i").attr('class', $(".open-group i").attr('class').replace('up', 'down')); + $('.displayLeftColumn').removeClass('col-md-12').addClass('col-md-3'); + $('.displayRightColumn').removeClass('col-md-12').addClass('col-md-3'); + $('.home-content-wrapper').removeClass('col-md-12').addClass('col-md-6'); + } + }); + + //only for product generate + $( ".product-container .content" ).sortable({ + revert: false + }); + $('.element-list .plist-element').draggable({ + connectToSortable: ".product-container .content", + revert: "true", + helper: "clone", + stop: function() { + + $( ".product-container .content" ).sortable({ + revert: false + }); + } + }); + $(document).on("click", "#list-slider .btn-delete-slider", function() { + if(confirm($("#form_content").data("delete"))) { + $(this).closest("li").remove(); + $("#frm-slider").removeAttr("edit"); + updateListIdFullSlider(); + } + }); + $(document).on("click", "#list-slider .btn-delete-fullslider", function() { + if(confirm($("#form_content").data("delete"))) { + $(this).closest("li").remove(); + $("#frm-slider").removeAttr("edit"); + updateListIdFullSlider(); + } + }); + $(document).on("click", "#btn-add-slider", function() { + $("#frm-slider, .apfullslider-row, #frm-block-slider").removeClass("hide"); + $(".btn-reset-slider, .btn-reset-fullslider").trigger("click"); + $("#frm-slider, #frm-block-slider").removeAttr("edit"); + }); + $(document).on("click", ".btn-cancel-slider, .btn-cancel-fullslider", function() { + $("#frm-slider, .apfullslider-row, #frm-block-slider").addClass("hide"); + }); + // $(document).on("click", ".btn-reset-slider", function() { + // $("#frm-slider, #frm-block-slider").removeAttr("edit"); + // $("#s-open").removeAttr("checked"); + // $("#s-image").attr("src", ""); + // $("#s-image").hide(); + // $("#frm-slider input, #frm-slider textarea, #frm-block-slider input, #frm-block-slider textarea").val(""); + // $("#s-tit").focus(); + // }); + $(document).on("click", ".btn-reset-fullslider, .btn-reset-slider", function() { + $("#frm-slider, #frm-block-slider").removeAttr("edit"); + $(".apfullslider-row img").attr("src", "").hide(); + $(".apfullslider-row input, .apfullslider-row textarea").val(""); + }); + $(document).on("click", ".btn-edit-slider", function() { + var li = $(this).closest("li"); + var idRow = $(li).attr("id"); + var lengthLang = Object.keys($globalthis.languages).length; + $("#frm-slider, .apfullslider-row").removeClass("hide"); + $("#frm-slider").attr("edit", $(li).attr("id")); + + if(lengthLang > 1) { + $(".select-img .translatable-field").each(function() { + currentLang = $(this).data("lang"); + var tempId = idRow + "_" + currentLang; + var img = $(li).find("#img_" + tempId).val(); + var title = $(li).find("#tit_" + tempId).val(); + var link= $(li).find("#link_" + tempId).val(); + var descript = $(li).find("#descript_" + tempId).val(); + $("#temp_title_" + currentLang).val(title); + $("#temp_image_" + currentLang).val(img); + // Check only diplay image for language + if(img) { + if($(".select-img .lang-" + currentLang).find("img").length == 0) { + $(".select-img .lang-" + currentLang + " div:first-child").prepend(""); + } else { + $(".select-img .lang-" + currentLang).find("img").attr("src", img); + $(".select-img .lang-" + currentLang).find("img").css("display", "block"); + } + } + $("#temp_link_" + currentLang).val(link); + $(".description-slide .lang-" + currentLang + " textarea").val(descript.replace(/_APNEWLINE_/g, " ")); + }); + } else { + currentLang = default_language; + var tempId = idRow + "_" + currentLang; + var img = $(li).find("#img_" + tempId).val(); + var title = $(li).find("#tit_" + tempId).val(); + var link= $(li).find("#link_" + tempId).val(); + var descript = $(li).find("#descript_" + tempId).val(); + $("#temp_title_" + currentLang).val(title); + $("#temp_image_" + currentLang).val(img); + // Check only diplay image for language + if(img) { + if($(".select-img img").length == 0) { + $(".select-img div:first-child").prepend(""); + } else if(img) { + $(".select-img img").attr("src", img); + } + } + $("#temp_link_" + currentLang).val(link); + $(".description-slide textarea").val(descript.replace(/_APNEWLINE_/g, " ")); + } + }); + $(document).on("click", ".btn-edit-fullslider", function() { + var li = $(this).closest("li"); + var idRow = $(li).attr("id"); + var lengthLang = Object.keys($globalthis.languages).length; + $("#frm-slider, .apfullslider-row").removeClass("hide"); + $("#frm-slider").attr("edit", $(li).attr("id")); + + if(lengthLang > 1) { + $(".select-img .translatable-field").each(function() { + var currentLang = $(this).data("lang"); + var tempId = idRow + "_" + currentLang; + var img = $(li).find("#img_" + tempId).val(); + var imgLink = imgModuleLink+img; + var title = $(li).find("#tit_" + tempId).val(); + var link= $(li).find("#link_" + tempId).val(); + var descript = $(li).find("#descript_" + tempId).val(); + $("#temp_title_" + currentLang).val(title); + $("#temp_image_" + currentLang).val(img); + // Check only diplay image for language + if(img) { + if($(".select-img .lang-" + currentLang).find("img").length == 0) { + $(".select-img .lang-" + currentLang + " div").first().prepend(""); + } else if(img) { + $(".select-img .lang-" + currentLang).find("img").attr("src", imgLink); + $(".select-img .lang-" + currentLang).find("img").css("display", "block"); + } + }else{ + // NOT EXIST IMAGE + $(".select-img .lang-" + currentLang).find("img").css("display", "none"); + } + $("#temp_link_" + currentLang).val(link); + $(".description-slide .lang-" + currentLang + " textarea").val(descript.replace(/_APNEWLINE_/g, " ")); + }); + } else { + var currentLang = default_language; + var tempId = idRow + "_" + currentLang; + var img = $(li).find("#img_" + tempId).val(); + var imgLink = imgModuleLink+img; + var title = $(li).find("#tit_" + tempId).val(); + var link= $(li).find("#link_" + tempId).val(); + var descript = $(li).find("#descript_" + tempId).val(); + $("#temp_title_" + currentLang).val(title); + $("#temp_image_" + currentLang).val(img); + // Check only diplay image for language + if(img) { + if($(".select-img img").length == 0) { + $(".select-img div").first().prepend(""); + } else if(img) { + $(".select-img img").attr("src", imgLink); + $(".select-img img").css("display", "block"); + } + }else{ + // NOT EXIST IMAGE + $(".select-img").find("img").css("display", "none"); + } + $("#temp_link_" + currentLang).val(link); + $(".description-slide textarea").val(descript.replace(/_APNEWLINE_/g, " ")); + } + }); + $(document).on("click", ".btn-save-slider", function() { + // Validate + // Get current language code selected + var currentLang = default_language; + var lengthLang = Object.keys($globalthis.languages).length; + var temId = lengthLang > 1 ? ".title-slide .lang-" + default_language + " input" : ".title-slide input"; + var title = $.trim($(temId).val()); + temId = lengthLang > 1 ? ".select-img .lang-" + default_language + " img" : ".select-img img"; + var image = $.trim($(temId).attr("src")); + var imageName = $.trim($(temId).data("img")); + temId = lengthLang > 1 ? ".link-slide .lang-" + default_language + " input" : ".link-slide input"; + var link = $.trim($(temId).val()); + temId = lengthLang > 1 ? ".description-slide .lang-" + default_language + " textarea" : ".description-slide textarea"; + var description = $.trim($(temId).val()); + var countLimit = 0; + if(!image) { + countLimit++; + } + if(!title) { + countLimit++; + } + if(!description) { + countLimit++; + } + // Require enter value for one in of [image, title, description] + if(countLimit == 3) { + alert($(this).data("error")); + return; + } + + var idForm = "#frm-slider"; + var idRow = (typeof $(idForm).attr("edit") != "undefined") ? $(idForm).attr("edit") : ""; + if(!idRow) { + var html = $("#temp-list li:first").html(); + idRow = 1; + var arr = $("#total_slider").val().split("|"); + arr.sort(function (a, b) { return a - b; }); + for(var i = 0; i < arr.length; i++) { + if(idRow != arr[i]) { + break; + } + idRow++; + } + if(lengthLang > 1) { + //console.log(idRow); + // Duplicate for new slider and build name and id by language + $(".select-img .translatable-field").each(function() { + currentLang = $(this).data("lang"); + var tempId = idRow + "_" + currentLang + "'"; + html += ""; + html += ""; + html += ""; + html += ""; + }); + } else { + var tempId = idRow + "_" + currentLang + "'"; + html += ""; + html += ""; + html += ""; + html += ""; + } + $("#list-slider").prepend("
  • " + html + "
  • "); + } + // Update labels for diplay interface + var label = (title ? '
    '+ title +'
    ' : ""); + label += (image ? '': ""); + $("#" + idRow + " div:first").html(label); + + if(lengthLang > 1) { + // Update value for other language by default language and save to dum hidden fields + $(".select-img .translatable-field").each(function() { + currentLang = $(this).data("lang"); + var titleOther = $.trim($(".title-slide .lang-" + currentLang + " input").val()); + var imageOther = $.trim($(".select-img #temp_image_" + currentLang).val()); + var linkOther = $.trim($(".link-slide .lang-" + currentLang + " input").val()); + var descriptionOther = $.trim($(".description-slide .lang-" + currentLang + " textarea").val()); + if(currentLang != default_language) { + if(!titleOther) { + titleOther = title; + $(".title-slide .lang-" + currentLang + " input").val(title); + } + if(!imageOther) { + imageOther = imageName; + $(".select-img .lang-" + currentLang + " input").val(imageOther); + } + if(!linkOther) { + linkOther = link; + $(".link-slide .lang-" + currentLang + " input").val(link); + } + if(!descriptionOther) { + descriptionOther = description; + $(".description-slide .lang-" + currentLang + " textarea").val(description); + } + } + var tempId = idRow + "_" + currentLang; + + $("#tit_" + tempId).val(titleOther); + $("#img_" + tempId).val(imageOther); + $("#link_" + tempId).val(linkOther); + $("#descript_" + tempId).val(descriptionOther); + }); + } else { + var tempId = idRow + "_" + currentLang; + $("#tit_" + tempId).val(title); + $("#img_" + tempId).val(imageName); + $("#link_" + tempId).val(link); + $("#descript_" + tempId).val(description); + } + $(idForm).attr("edit", idRow); + updateListIdFullSlider(); + $(idForm).addClass("hide"); + $(".apfullslider-row").addClass("hide"); + }); + /** + * Validate and gender data for fullsilder and fill data for all language from current language selected in form + */ + $(document).on("click", ".btn-save-fullslider", function() { + // Validate + // Get current language code selected + var currentLang = default_language; + var lengthLang = Object.keys($globalthis.languages).length; + var temId = lengthLang > 1 ? ".title-slide .lang-" + default_language + " input" : ".title-slide input"; + var title = $.trim($(temId).val()); + temId = lengthLang > 1 ? ".select-img .lang-" + default_language + " img" : ".select-img img"; + var image = $.trim($(temId).attr("src")); + var imageName = $.trim($(temId).data("img")); + temId = lengthLang > 1 ? ".link-slide .lang-" + default_language + " input" : ".link-slide input"; + var link = $.trim($(temId).val()); + temId = lengthLang > 1 ? ".description-slide .lang-" + default_language + " textarea" : ".description-slide textarea"; + var description = $.trim($(temId).val()); + var countLimit = 0; + if(!image) { + countLimit++; + } + if(!title) { + countLimit++; + } + if(!description) { + countLimit++; + } + // Require enter value for one in of [image, title, description] + if(countLimit == 3) { + alert($(this).data("error")); + return; + } + + var idForm = "#frm-slider"; + var idRow = (typeof $(idForm).attr("edit") != "undefined") ? $(idForm).attr("edit") : ""; + if(!idRow) { + var html = $("#temp-list li:first").html(); + idRow = 1; + var arr = $("#total_slider").val().split("|"); + arr.sort(); + for(var i = 0; i < arr.length; i++) { + if(idRow != arr[i]) { + break; + } + idRow++; + } + if(lengthLang > 1) { + //console.log(idRow); + // Duplicate for new slider and build name and id by language + $(".select-img .translatable-field").each(function() { + currentLang = $(this).data("lang"); + var tempId = idRow + "_" + currentLang + "'"; + html += ""; + html += ""; + html += ""; + html += ""; + }); + } else { + var tempId = idRow + "_" + currentLang + "'"; + html += ""; + html += ""; + html += ""; + html += ""; + } + $("#list-slider").prepend("
  • " + html + "
  • "); + } + // Update labels for diplay interface + var label = (title ? '
    '+ title +'
    ' : ""); + label += (image ? '': ""); + $("#" + idRow + " div:first").html(label); + + if(lengthLang > 1) { + // Update value for other language by default language and save to dum hidden fields + $(".select-img .translatable-field").each(function() { + currentLang = $(this).data("lang"); + var titleOther = $.trim($(".title-slide .lang-" + currentLang + " input").val()); + var imageOther = $.trim($(".select-img #temp_image_" + currentLang).val()); + var linkOther = $.trim($(".link-slide .lang-" + currentLang + " input").val()); + var descriptionOther = $.trim($(".description-slide .lang-" + currentLang + " textarea").val()); + if(currentLang != default_language) { + if(!titleOther) { + titleOther = title; + $(".title-slide .lang-" + currentLang + " input").val(title); + } + if(!imageOther) { + imageOther = imageName; + $(".select-img .lang-" + currentLang + " input").val(imageOther); + } + if(!linkOther) { + linkOther = link; + $(".link-slide .lang-" + currentLang + " input").val(link); + } + if(!descriptionOther) { + descriptionOther = description; + $(".description-slide .lang-" + currentLang + " textarea").val(description); + } + } + var tempId = idRow + "_" + currentLang; + $("#tit_" + tempId).val(titleOther); + $("#img_" + tempId).val(imageOther); + $("#link_" + tempId).val(linkOther); + $("#descript_" + tempId).val(descriptionOther); + }); + } else { + var tempId = idRow + "_" + currentLang; + $("#tit_" + tempId).val(title); + $("#img_" + tempId).val(imageName); + $("#link_" + tempId).val(link); + $("#descript_" + tempId).val(description); + } + $(idForm).attr("edit", idRow); + updateListIdFullSlider(); + $(idForm).addClass("hide"); + $(".apfullslider-row").addClass("hide"); + }); + $(document).on("click", ".latest-blog-category input[type='checkbox']", function() { + ckb = $(this).is(':checked'); + if(ckb) { + $(this).closest("li").find('input').attr("checked", "checked"); + } else { + $(this).closest("li").find('input').removeAttr("checked"); + } + }); + $(document).on("click", ".list-font-awesome li", function() { + $(".list-font-awesome li").removeClass("selected"); + $("#font_name").val($(this).find("i").data("default")); + $(".preview-widget i").attr("class", $(this).find("i").attr("class")); + $(this).addClass("selected"); + renderDefaultPreviewFontwesome(); + }); + $(document).on("change", "#font_type, #font_size, #is_spin", function() { + renderDefaultPreviewFontwesome(); + }); + + if(typeof ap_controller != "undefined" && ap_controller == 'AdminApPageBuilderThemeConfigurationController') + { + initApTabForm(); + } + +}); +function renderDefaultPreviewFontwesome() { + var cls = "icon " + $("#font_name").val() + " " + $("#font_type").val() + + " " + $("#font_size").val() + + " " + $("#is_spin").val(); + $(".preview-widget i").attr("class", cls); +} +/** +* Start block for module ApCategoryImage +*/ +/** + * Update status check a current category, this function is called from event in file home.js in this module + * @param {type} obj: install of image just selected + * @returns {Boolean} + */ +var selected_images = {}; +function resetSelectedImage() { + if(typeof selected_images != "undefined") { + selected_images = {}; + } +} +function updateStatusCheck(obj) { + var checkbox = $(obj).closest("span").find("input[type='checkbox']").first(); + if($(obj).attr("src-url") != "") { + selected_images[$(checkbox).val()] = $(obj).attr("src-url"); + // Set status for checkbox + // $(checkbox).attr("checked", "checked"); + $(obj).closest("span").find(".remove-img").removeClass("hidden"); + } else { + $(checkbox).removeAttr("checked"); + $(obj).closest("span").find(".remove-img").addClass("hidden"); + delete selected_images[$(checkbox).val()]; + } + $("#category_img").val(JSON.stringify(selected_images)); + return false; +} +function intiForApCategoryImage() { + $("#categorybox").addClass('full_loaded'); // Not load AJAX Tree Category again, For action expandAll in tree.js library + $('#collapse-all-categorybox').hide(); + + $("#pcategories").closest(".form-group").hide(); + $("#ptype").closest(".form-group").hide(); + $("#pproductids").closest(".form-group").hide(); + $("#pmanufacturers").closest(".form-group").hide(); + $("#source option:selected").each(function() { + var val = $(this).val(); + $("#"+val).closest(".form-group").show(); + }); + $("#source").change(function(){ + $("#pcategories").closest(".form-group").hide(); + $("#ptype").closest(".form-group").hide(); + $("#pproductids").closest(".form-group").hide(); + $("#pmanufacturers").closest(".form-group").hide(); + var val = $(this).val(); + $("#"+val).closest(".form-group").show(500); + }); + //hide checkbox of root node + $("input[type=checkbox]", "#categorybox").first().hide(); + var root_id = $("input[type=checkbox]", "#categorybox").first().val(); + Array.prototype.remove = function(v) { this.splice(this.indexOf(v) == -1 ? this.length : this.indexOf(v), 1); } + if($("#category_img").val()){ + selected_images = JSON.parse($("#category_img").val()); + } + $("input[type=checkbox]", "#categorybox").click(function(){ + if($(this).is(":checked")) { + //find parent category + //all parent category must be not checked + var check = checkParentNodes($(this)); + if(!check){ + $(this).prop("checked", false); + alert("All parent of this category must be not checked"); + } else { + $(this).closest("ul").find("ul input[type=checkbox]").removeAttr("checked"); + } + } else { + //$(".list-image-" + $(this).val()).remove(); + delete selected_images[$(this).val()]; + } + $("#category_img").val(JSON.stringify(selected_images)); + }); + + // Show selected_image when loaded page + refreshListIcon(); + function refreshListIcon() { + $("input[type=checkbox]", $(".form-select-icon")).each(function() { + var listImage; + if($(this).val() != root_id){ + listImage = $(".list-image", "#list_image_wrapper").clone(1); + var d = new Date(); + var n = "" + d.getTime() + Math.random(); + n = n.replace(".", ""); + var span = $(this).closest("li").find("span"); + $(listImage).find("img").attr("id", "apci_" + n); + $(listImage).find("a").data("for", "#apci_" + n); + listImage.appendTo($(span).first()); + } + for(var key in selected_images){ + if(key == $(this).val()){ + image_name = selected_images[key]; + if(listImage) { + var path = $(listImage).find("img").attr("path"); + $(listImage).find("img").attr("src", path + image_name); + $(listImage).find("img").removeClass("hidden"); + $(listImage).find(".remove-img").removeClass("hidden"); + } + //listImage.find(".dropdown-toggle").html(image_name+' '); + // Set status for checkbox + //$(this).attr("checked", "checked"); + break; + } + } + $("#category_img").val(JSON.stringify(selected_images)); + //$(this).closest("ul.tree").css("display", "none"); + }); + } + + function checkParentNodes(obj) { + var flag = true; + if(parent = obj.closest("ul").closest("li").find("input[type=checkbox]")){ + if(parent.val() != root_id){ + if($("input[value=" + parent.val() + "]","#categorybox").is(":checked")){ + flag = false; + } else { + flag = checkParentNodes(parent); + } + } + } + return flag; + } +} +function replaceSpecialString(str){ + return str.replace(/\t/g, "_APTAB_").replace(/\r/g, "_APNEWLINE_").replace(/\n/g, "_APENTER_").replace(/"/g, "_APQUOT_").replace(/'/g, "_APAPOST_"); +} +/* +* End block for module ApCategoryImage +*/ + +function hideFormLevel2(){ + $(".row-level2").addClass("hide"); + // Remove name + $(".row-level2 input, .row-level2 textarea, .row-level2 select").each(function(){ + $(this).attr("data-name", $(this).attr('name')); + }); + $(".row-level2 input, .row-level2 textarea, .row-level2 select").removeAttr("name"); +} + +function showFormLevel2(){ + $(".row-level2").removeClass("hide"); + // get name + $(".row-level2 input, .row-level2 textarea, .row-level2 select").each(function(){ + $(this).attr("name", $(this).attr('data-name')); + }); + +} + +$(document).on("click", ".btn-add-level2", function() { + $(".btn-reset-level2").trigger("click"); + showFormLevel2(); +}); + +$(document).on("click", ".btn-reset-level2", function() { +// $("#frm-slider, #frm-block-slider").removeAttr("edit"); + $(".row-level2 input, .row-level2 textarea").val(''); + $(".row-level2 img").not('.mColorPickerTrigger img').attr("src", "").hide();// not remove image from color_picker + + $('.mColorPickerInput.mColorPicker').each(function(){ + + var val = $(this).val(); + $(this).css('background-color', val); + + }); +}); + +// $(document).undelegate(".btn-cancel-level2", "click"); +$(document).on("click", ".btn-cancel-level2", function() { + hideFormLevel2(); + $(".btn-reset-level2").trigger("click"); + $('.frm-level2').removeAttr("edit" ); +}); + +$(document).on("click", ".btn-save-level2", function() { + var currentLang = default_language; + var lengthLang = Object.keys($globalthis.languages).length; + + var temId = lengthLang > 1 ? ".row2-title .lang-" + default_language + " input" : ".row2-title input"; + var title = $.trim($(temId).val()); + + var countLimit = 0; // error + if(!title) { + countLimit++; + } + + // Require enter value for one in of [title] + if(countLimit > 1) { + alert($(this).data("error")); + return; + } + + var html = $("#temp-list li:first").html(); + var idRow = (typeof $('.frm-level2').attr("edit") != "undefined") ? $('.frm-level2').attr("edit") : ""; + var action = (typeof $('.frm-level2').attr("edit") != "undefined") ? 'edit' : 'add'; + + if(action == 'add') + { + idRow = 1; + // SORT id_Row + var arr = $("#total_slider").val().split("|"); + arr.sort(); + for(var i = 0; i < arr.length; i++) + { + if(idRow != arr[i]) + { + break; + } + idRow++; + } + } + + // LIST INPUT NAME_idrow for temp form + var list_input = new Array(); + $(".row-level2 *[name^='temp_']").each(function(html){ + list_input.push( $(this).attr('name') ); + }); + + // LIST INPUT NAME_idrow_idlang for div + var list_input_name = new Array(); + $(".row-level2 *[name^='temp_']").each(function(html){ + if ( $(this).parent().parent().hasClass('translatable-field') || $(this).hasClass('js-multilang') ){ + // Input Multi-lang + var full_name=$(this).attr('name'); + var name = full_name.slice( 0, full_name.lastIndexOf("_") ); + var lang_name = full_name.slice( full_name.lastIndexOf("_"), full_name.length ); + list_input_name.push( name + '_' + idRow + lang_name ); + }else{ + // Input No-lang + var full_name=$(this).attr('name'); + list_input_name.push( full_name + '_' + idRow); + } + }); + + for (var i=0; i"; + } + + if(action =='add') + { + $("#list-slider").prepend("
  • " + html + "
  • "); + }else if(action =='edit') + { + $("#list-slider #" + idRow).html(html); + } + + + // Update labels for diplay interface + var label = (title ? '
    '+ title +'
    ' : ""); + + var image = ''; + if ($(".row2-image img").length) + { + // Exist image + image = $.trim( $('.row2-image img').attr('src') ); + } + label += (image ? '': ""); + $("#list-slider #" + idRow + " div:first").html(label); + + $('.frm-level2').removeAttr("edit" ); + updateListIdFullSlider(); + + hideFormLevel2(); + +}); + +$(document).on("click", "#list-slider .btn-delete-level2", function() { + if(confirm($("#form_content").data("delete"))) { + $(this).closest("li").remove(); + $("#frm-slider").removeAttr("edit"); + updateListIdFullSlider(); + } +}); + +$(document).on("click", ".btn-edit-level2", function() { + $(".btn-reset-level2").trigger("click"); + showFormLevel2(); + var li = $(this).closest("li"); + var idRow = $(li).attr("id"); + var lengthLang = Object.keys($globalthis.languages).length; + $(".frm-level2").attr("edit", $(li).attr("id")); + + // LIST INPUT NAME of temp_form + var list_input = new Array(); + $(".row-level2 *[name^='temp_']").each(function(html){ + list_input.push( $(this).attr('name') ); + }); + + // LIST INPUT NAME of div + var list_input_name = new Array(); + $(".row-level2 *[name^='temp_']").each(function(html){ + if ( $(this).parent().parent().hasClass('translatable-field') || $(this).hasClass('js-multilang') ){ + // Input Multi-lang + var full_name=$(this).attr('name'); + var name = full_name.slice( 0, full_name.lastIndexOf("_") ); + var lang_name = full_name.slice( full_name.lastIndexOf("_"), full_name.length ); + list_input_name.push( name + '_' + idRow + lang_name ); + }else{ + // Input No-lang + var full_name=$(this).attr('name'); + list_input_name.push( full_name + '_' + idRow); + } + }); + + // SET DATA FROM div To temp_form + for (var i=0; i" ); + } + }); + } + + $('.mColorPickerInput.mColorPicker').each(function(){ + + var val = $(this).val(); + $(this).css('background-color', val); + + }); +}); + +function initApTabForm() { + if ($('.aptab-config').length > 0) + { + //set tab aciton + $('.aptab-config').each(function () { + if (!$(this).parent().hasClass('active')) { + element = $(this).attr('href').toString().replace("#", "."); + $(element).hide(); + } + }); + + $('.aptab-config').click(function () { + divElement = $(this).attr('href').toString().replace("#", "."); + aElement = $(this); + $('.aptab-config').each(function () { + if ($(this).parent().hasClass('active')) { + element = $(this).attr('href').toString().replace("#", "."); + $(this).parent().removeClass('active'); + $(element).hide(); + return false; + } + }); + $(divElement).show(); + $(aElement).parent().addClass('active'); + + $('.form-action', $(divElement)).each(function () { + $(this).trigger("change"); + }); + + $('.checkbox-group', $(divElement)).each(function () { + $globalthis.showOrHideCheckBox($(this)); + }); + + + // if ($(this).attr('href') == "#aprow_animation" && $('#animation').length > 0) + // $('#animation').trigger("change"); + + }); + } +} + +function SaveAndStayAdminApPageBuilderProfiles(){ + $("button[name$='submitAddappagebuilder_profilesAndStay']").click(); +} + +function SaveAdminApPageBuilderProfiles(){ + $("button[name$='submitAddappagebuilder_profiles']").click(); +} \ No newline at end of file diff --git a/modules/appagebuilder/js/admin/form_admin_positions.js b/modules/appagebuilder/js/admin/form_admin_positions.js new file mode 100644 index 00000000..2107db46 --- /dev/null +++ b/modules/appagebuilder/js/admin/form_admin_positions.js @@ -0,0 +1,28 @@ +/* + * @Website: apollotheme.com - prestashop template provider + * @author Apollotheme + * @copyright 2007-2018 Apollotheme + * @description: + */ + +$(document).ready(function() { + $('.leo_delete_position').each(function(){ + + $(this).closest('a').attr('href',"javascript:void(0);"); + + $('', { + type: 'hidden', + id : 'leo_delete_position', + name: 'leo_delete_position', + value: '0' + }).appendTo( $(this).parent() ); + + $(this).closest('a').click(function(){ + if (confirm(leo_confirm_text)){ + $('#leo_delete_position').val('1'); + $(this).closest('form').attr('action', leo_form_submit); + $(this).closest('form').submit(); + } + }); + }); +}); \ No newline at end of file diff --git a/modules/appagebuilder/js/admin/home.js b/modules/appagebuilder/js/admin/home.js new file mode 100644 index 00000000..8b0222d5 --- /dev/null +++ b/modules/appagebuilder/js/admin/home.js @@ -0,0 +1,2577 @@ +/** + * @Website: apollotheme.com - prestashop template provider + * @author Apollotheme + * @copyright 2007-2018 Apollotheme + * @description: + */ +imgId = null; // using for store object image select a source in function select image +function log(message) { + console.log(message); +} +function htmlentities(str) { + var textarea = document.createElement("textarea"); + textarea.innerHTML = str; + return textarea.innerHTML; +} +function htmlentitiesDecode(str) { + var textarea = document.createElement("textarea"); + textarea.innerHTML = str; + return textarea.value; +} +(function ($) { + $.fn.apPageBuilder = function () { + this.currentElement = null; + this.ajaxShortCodeUrl = null; + this.ajaxHomeUrl = null; + this.shortCodeField = null; + this.shortcodeInfos = null; + this.languages = null; + this.lang_id = 0; + this.classWidget = 'ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'; + this.classWidgetHeader = 'ui-widget-header ui-corner-all'; + this.widthSupport = null; + this.arrayCol = null; + this.windowWidth = 0; + this.imgController = null; + this.parentId = null; + this.profileId = null; + + this.process = function (DATAFORM, DATAINFO, LANGS) { + var $globalthis = this; + $globalthis.windowWidth = $(window).width(); + $globalthis.shortcodeInfos = jQuery.parseJSON(DATAINFO); + $globalthis.languages = jQuery.parseJSON(LANGS); + $globalthis.initDataFrom(DATAFORM); + $globalthis.widthSupport = ["1", "2", "2.4", "3", "4", "5", "4.8", "6", "7", "7.2", "8", "9", "9.6", "10", "11", "12"]; + $globalthis.arrayCol = ["sp", "xs", "sm", "md", "lg", "xl"]; + $globalthis.initColumnSetting(); + + $globalthis.setGroupAction(); + $globalthis.sortable(); + $globalthis.setButtonAction(); + $globalthis.submitForm(); + + // Load form after come back from live edit mode + var type = window.location.href.split('#'); + var hash = ''; + if (type.length > 1) { + hash = type[1]; + var btn = $("." + hash).find(".btn-edit"); + //$(btn).trigger("click"); + } + //$globalthis.setRowAction(); + }; + this.initDataFrom = function (data) { + var $globalthis = this; + if (data != '{}') { + dataObj = jQuery.parseJSON(data); + + Object.keys(dataObj).forEach(function (key) { + $('.' + key).data('form', dataObj[key]); + //DONGND:: install data animation for column and group + if (typeof dataObj[key].animation != 'undefined') + { + if ($('.' + key).find('.animation-button').first().length) + { + var animation_bt = $('.' + key).find('.animation-button').first(); + var animation_type = dataObj[key].animation ? dataObj[key].animation : 'none'; + var animation_delay = dataObj[key].animation_delay ? dataObj[key].animation_delay : 1; + var animation_duration = dataObj[key].animation_duration ? dataObj[key].animation_duration : 1; + var animation_iteration_count = dataObj[key].animation_iteration_count ? dataObj[key].animation_iteration_count : 1; + var animation_infinite = dataObj[key].animation_infinite ? dataObj[key].animation_infinite : 0; + + $globalthis.assignConfigAnimation(animation_bt, animation_type, animation_delay, animation_duration, animation_iteration_count, animation_infinite); + } + } + + }); + + //DONGND:: fix can't click tab 1 when create new widget tab + $('.ApTabs:not(#default_ApTabs)').each(function(){ + var activeTabId = $(this).data('form').active_tab; + if (activeTabId != '' && parseInt(activeTabId)) + { + $(this).find('.nav-tabs a').eq(parseInt(activeTabId)-1).tab('show'); + } + }) + } + }; + this.getColDefault = function () { + return {xl:12, lg: 12, md: 12, sm: 12, xs: 12, sp: 12}; + }; + //set action for group + this.setGroupAction = function () { + + //duplicate group + $('.gaction-duplicate').click(function () { + var duplicate = $(this).closest('.group-row').clone(1); + //remove tooltip because wrong position + $('.tooltip', $(duplicate)).remove(); + $('.label-tooltip', $(duplicate)).tooltip('disable'); + $('.hook-content-footer', $(this).closest('.hook-content')).before(duplicate); + }); + + $('.number-column').click(function () { + column = $(this).data('cols'); + }); + + $('.gaction-toggle').click(function () { + $(this).closest('.group-row').find('.group-content').first().toggle('clip'); + }); + }; + //sort group + this.sortable = function () { + var $globalthis = this; + + $(".hook-content").sortable({ + connectWith: ".hook-content", + handle: ".gaction-drag" + }); + $(".group-row").addClass($globalthis.classWidget) + .find(".gaction-drag").addClass($globalthis.classWidgetHeader); + + $(".hook-content .group-content").sortable({ + connectWith: ".group-content", + handle: ".caction-drag" + }); + $(".column-row").addClass($globalthis.classWidget) + .find(".caction-drag").addClass($globalthis.classWidgetHeader); + + $(".group-content .column-content").sortable({ + connectWith: ".column-content", + handle: ".waction-drag" + }); + $(".widget-row").addClass($globalthis.classWidget) + .find(".waction-drag").addClass($globalthis.classWidgetHeader); + + $(".subwidget-content").sortable({ + connectWith: ".subwidget-content", + handle: ".waction-drag" + }); +// $( ".widget-row" ).addClass( $globalthis.classWidget ) +// .find( ".waction-drag" ).addClass( $globalthis.classWidgetHeader ); + + }; + this.downloadFile = function (filename, result) { + //csvData = 'data:application/xml;charset=utf-8,' + result; + //console.log(result); + $("#export_process") + .attr({ + 'download': filename, + 'href': result, + 'target': '_blank' + }); + $("#export_process").get(0).click(); + }; + //general action + this.setButtonAction = function () { + var $globalthis = this; + $globalthis.initControllInRow(); + this.createColumn = function (obj, currentId) { + var widthCol = $(obj).data('width'); + var classActive = $globalthis.returnWidthClass(); + var col = $(obj).data('col'); + var realValue = widthCol.toString().replace('.', '-'); + for (var i = 1; i <= col; i++) { + wrapper = currentId;///$($globalthis.currentElement).find('.group-content').first(); + column = $('#default_column').clone(); + var cls = $(column).attr("class"); + //column-row col-sp-12 col-xs-12 col-sm-12 col-md-12 col-lg-12 ui-widget ui-widget-content ui-helper-clearfix ui-corner-all + cls = cls.replace("col-xl-12", "col-xl-" + realValue); + cls = cls.replace("col-lg-12", "col-lg-" + realValue); + cls = cls.replace("col-md-12", "col-md-" + realValue); + cls = cls.replace("col-sm-12", "col-sm-" + realValue); + cls = cls.replace("col-xs-12", "col-xs-" + realValue); + cls = cls.replace("col-sp-12", "col-sp-" + realValue); + $(column).attr("class", cls); + objColumn = {form_id: "form_" + $globalthis.getRandomNumber()}; + + objColumn.sm = widthCol; + objColumn.xs = widthCol; + objColumn.sp = widthCol; + if (classActive == "md" || classActive == "lg" || classActive == "xl") { + objColumn.md = widthCol; + objColumn.lg = widthCol; + objColumn.xl = widthCol; + } + //jQuery.extend(objColumn, $globalthis.getColDefault()); + $(column).data("form", objColumn); + + column.removeAttr('id'); + wrapper.append(column); + $globalthis.getNumberColumnInClass(column, classActive); + $(".label-tooltip").tooltip(); + } + } + $(document).on("click", ".column-add", function () { + $globalthis.createColumn(this, $globalthis.currentElement); + }); + $(document).on("click", ".group-add", function () { + var item = $(this).data("col"); + currentE = $globalthis.currentElement; + // Create a group blank + if (item == 0) { + group = $("#default_row").clone(); + group.removeAttr('id'); + //var html = $(group).find(".group-controll-right").html(); + //$(group).find(".group-controll-right").html(html); + $(group).data("form", {form_id: "form_" + $globalthis.getRandomNumber(), 'class': 'row'}); + $(currentE).before(group); + $globalthis.initControllInRow(); + } + // Display popup list Widget for add new a widget + else if (item == 1) { + // This code similar event click to button: + // $(".btn-new-widget").trigger("click"); + var url = $globalthis.ajaxHomeUrl + '&ajax=1&action=renderList'; + var data = ''; + $("#ap_loading").show(); + + $.ajax({ + type: 'POST', + headers: {"cache-control": "no-cache"}, + url: url, + async: true, + data: data, + dataType: 'json', + cache: false, + success: function (json) { + $("#ap_loading").hide(); + if (json && json.hasError == true){ + alert(json.errors); + }else{ + $("#txt-search").show(); + $('#myModalLabel').html($('#myModalLabel').data('addnew')); + $('#modal_form .modal-body').html(json.result); + $('#modal_form .modal-footer').hide(); + $('#modal_form').modal('show'); + $('#modal_form').removeClass('modal-edit').addClass('modal-new'); + $globalthis.setFormAction(); + $globalthis.initControllInRow(); + $("#txt-search").focus(); + $globalthis.initIsotopAction(); + } + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + $("#ap_loading").hide(); + alert("TECHNICAL ERROR: \n\nDetails:\nError thrown: " + XMLHttpRequest + "\n" + 'Text status: ' + textStatus); + } + }); + } else { + group = $("#default_row").clone(); + group.removeAttr('id'); + //var html = $(group).find(".group-controll-right").html(); + //$(group).find(".group-controll-right").html(html); + $(group).data("form", {form_id: "form_" + $globalthis.getRandomNumber(), 'class': 'row'}); + $(currentE).before(group); + $globalthis.createColumn(this, group); + $globalthis.initControllInRow(); + } + }); + $(document).on("click", ".btn-select-profile", function () { + if (!confirm($("#form_content").data('select'))) + return false; + }); + + $(document).on("click", ".btn-back-to-list", function () { + currentElement = $globalthis.currentElement; + //add new in column + if ($(currentElement).hasClass('column-content') || $(currentElement).hasClass('subwidget-content')) { + $(currentElement).parent().find('.btn-new-widget').first().trigger('click'); + } + //add new in group + else { + $(currentElement).parent().find('.hook-content-footer .btn-new-widget').trigger('click'); + } + }); + //save widget + + $(document).on("click", ".btn-savewidget", function () { + hideFormLevel2(); + currentElement = $globalthis.currentElement; + //add new widget + if ($("#modal_form").hasClass("modal-new")) { + //add new widget in column + if ($(currentElement).hasClass('column-content')) { + $globalthis.saveWidget('column'); + } + else if ($(currentElement).hasClass('subwidget-content')) { + $globalthis.saveWidget('column'); + } + //add new widget in hook + else { + $globalthis.saveWidget('hook'); + } + } else { + $globalthis.saveWidget('update'); + } + $globalthis.currentElement = null; + $(".label-tooltip").tooltip(); + $('#modal_form').modal('hide'); + $globalthis.initControllInRow(); + }); + + $(document).on("click", ".btn-fwidth", function () { + $('#home_wrapper').css('width', $(this).data('width')); + + btnElement = $(this); + $('.btn-fwidth').removeClass('active'); + $(this).addClass('active'); + //reset + if ($(this).hasClass('width-default')) { + $globalthis.windowWidth = $(window).width(); + $('#home_wrapper').attr('class', 'default'); + } else { + $('#home_wrapper').attr('class', 'col-' + $globalthis.returnWidthClass(parseInt($(this).data('width')))); + $globalthis.windowWidth = $(this).data('width'); + } + classVal = $globalthis.returnWidthClass(); + $(".column-row", $('#home_wrapper')).each(function () { + valueFra = $(this).data("form")[classVal]; + $(".apbtn-width .width-val", $(this)).attr("class", "width-val ap-w-" + valueFra.toString().replace(".", "-")); + }); + $globalthis.initColumnSetting(); + }); + + $(document).on("click", ".btn-import", function () { + $("#ap_loading").show(); + var url = $globalthis.ajaxHomeUrl + '&ajax=1&action=showImportForm&idProfile=' + $globalthis.profileId; + var data = ''; + $.ajax({ + type: 'POST', + headers: {"cache-control": "no-cache"}, + url: url, + async: true, + data: data, + dataType: 'json', + cache: false, + success: function (json) + { + $("#ap_loading").hide(); + if (json && json.hasError == true){ + alert(json.errors); + }else{ + $("#txt-search").hide(); + $('#myModalLabel').html($('#myModalLabel').data('addnew')); + $('#modal_form .modal-body').html(json.result); + $('#modal_form .modal-footer').hide(); + $('#modal_form').modal('show'); + } + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + $("#ap_loading").hide(); + alert("TECHNICAL ERROR: \n\nDetails:\nError thrown: " + XMLHttpRequest + "\n" + 'Text status: ' + textStatus); + } + }); + }); + + $(document).on("click", ".btn-export", function () { + var objects = new Object(); + type = $(this).data("type"); + var position = ''; + if (type == "group") { + objHook = {}; + objHook.groups = {}; + objHook.groups[0] = $globalthis.getHookSubmit($(this).closest('.group-row')); + objects[0] = objHook; + } else if (type == "position") { + position = $(this).data("position"); + type = "position-" + position; + var id = "#position-" + $(this).data("position") + " .hook-wrapper"; + $(id).each(function (iHook) { + //hook object contain group + var objHook = {}; + objHook.name = $(this).data('hook'); + objHook.position = $(this).data('hook'); + objHook.groups = {}; + $('.group-row', $(this)).each(function (iGroup) { + objHook.groups[iGroup] = $globalthis.getHookSubmit(this); + }); + + objects[iHook] = objHook; + }); + } else if (type == "all") { + $('.hook-wrapper').each(function (iHook) { + //hook object contain group + var objHook = {}; + objHook.name = $(this).data('hook'); + objHook.position = $(this).data('hook'); + objHook.groups = {}; + $('.group-row', $(this)).each(function (iGroup) { + objHook.groups[iGroup] = $globalthis.getHookSubmit(this); + }); + + objects[iHook] = objHook; + }); + } else { + objHook = {}; + objHook.groups = {}; + $('.group-row', $('.' + type)).each(function (iGroup) { + objHook.groups[iGroup] = $globalthis.getHookSubmit(this); + }); + objects[0] = objHook; + } + + data = 'dataForm=' + JSON.stringify(objects); + + $("#ap_loading").show(); + url = $globalthis.ajaxHomeUrl + '&action=export&type=' + type; + + $.ajax({ + type: 'POST', + headers: {"cache-control": "no-cache"}, + url: url, + async: true, + cache: false, + data: data, + dataType: 'json', + cache: false, + success: function (json) + { + $("#ap_loading").hide(); + if (json && json.hasError == true){ + alert(json.errors); + }else{ + if (type == 'all') + type = 'appagebuilderhome'; + $globalthis.downloadFile(type + '.xml', json.result); + } + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + $("#ap_loading").hide(); + alert("TECHNICAL ERROR: \n\nDetails:\nError thrown: " + XMLHttpRequest + "\n" + 'Text status: ' + textStatus); + } + }); + }); + + //delete group + $(document).on("click", ".btn-delete", function () { + if (!confirm($("#form_content").data("delete"))) + return false; + + // Deleta a panel + if ($(this).hasClass("tabcontent-action") && $(this).hasClass("accordions")) { + // Check this must be have greater than 2 accordions + var cover = $(this).closest(".panel-group"); + if ($(cover).find(".panel").length < 3) { + alert("Can not delete when have 2 panel"); + return; + } + + // remove + if ($(this).closest('.panel-default').length > 0) { + $(this).closest('.panel-default').remove(); + return; + } + } + + // Deleta tab + if ($(this).hasClass("tabcontent-action") && $(this).hasClass("tab")) { + // Check this must be have greater than 2 tabs + var tabcontent = $(this).closest(".tab-content"); + var limit = $(tabcontent).find("#default_tabcontent").length > 0 ? 4 : 3; + if ($(tabcontent).find(".tab-pane").length < limit) { + alert("Can not delete when have " + (limit - 1) + " tabs"); + return; + } + + // remove + tabId = $(this).closest(".tab-pane").attr('id'); + $('a[href$="' + tabId + '"]:first()').closest("li").remove(); + $("#" + tabId).remove(); + return; + } + + if ($(this).hasClass("accordions")) { + if ($(this).closest('.panel-default').length > 0) { + $(this).closest('.panel-default').remove(); + } + } + + if ($(this).data("for") == undefined) { + if ($(this).hasClass("group-action")) { + $(this).closest(".group-row").remove(); + } else if ($(this).hasClass("column-action")) { + $(this).closest(".column-row").remove(); + } else { + // Delete group of tag, accordion + $(this).closest(".widget-row").remove(); + } + } + else { + $(this).closest($(this).data("for")).remove(); + } + + }); + + //edit group + $(document).on("click", ".btn-edit", function () { + if ($(this).data('type' == undefined) && $(this).data('type') == undefined) { + var type = $(this).closest('.widget-row').data("type"); + } else + var type = $(this).data("type"); + + if (type.indexOf("apSub") == 0) { + if (type == "apSubAccordions") { + idContainer = $(this).closest('.widget-container-content').attr("id"); + } else { + idContainer = $(this).closest('.widget-wrapper-content').attr("id"); + } + type = type.replace("Sub", "") + "&subTab"; + $globalthis.currentElement = $('a[href*="' + idContainer + '"]', $(this).closest(".widget-row")); + } else { + if ($(this).data('for') == undefined) { + if (type == "ApRow") { + $globalthis.currentElement = $(this).closest(".group-row"); + } else if (type == "ApColumn") { + $globalthis.currentElement = $(this).closest(".column-row"); + } else { + $globalthis.currentElement = $(this).parent().parent(); + } + } + else + $globalthis.currentElement = $(this).closest($(this).data('for')); + } + var url = $globalthis.ajaxShortCodeUrl; + if (type === "apModule") { + url += '&ajax=1&edit&type_shortcode=any&type=module'; + } else if (type === "ApRow") { + var hook_name = $(this).closest("[data-hook]").attr('data-hook'); + url += '&ajax=1&edit&type_shortcode=' + type + "&type=widget" + "&id_appagebuilder_profiles=" + $globalthis.profileId + "&hook_name=" + hook_name; + } else { + url += '&ajax=1&edit&type_shortcode=' + type + "&type=widget"; + } + var obj = $($globalthis.currentElement).data("form"); + + var data = ''; + if (obj) + Object.keys(obj).forEach(function (key) { + data += (data ? "&" : "") + key + "=" + obj[key]; + }); + $("#txt-search").hide(); + $("#ap_loading").show(); + + // Store parent id + if (type == "apSubAccordions" || type == "apAccordions&subTab") { + $globalthis.parentId = $(this).closest(".panel-group").attr("id"); + } + $.ajax({ + type: 'POST', + headers: {"cache-control": "no-cache"}, + url: url, + async: true, + cache: false, + data: data, + success: function (data) { + data = data.replace(/_APNEWLINE_/g, " "); + $("#ap_loading").hide(); + $('#myModalLabel').html($('#myModalLabel').data('edit') + " " + type.replace('ap_', '')); + $('#modal_form .modal-footer').show(); + $('#modal_form .modal-body').html(data); + $('#modal_form').removeClass('modal-new').addClass('modal-edit'); + + // FIX BUG : ApCategory khong save duoc icon cu, khi thay icon cho 1 category khac +// resetSelectedImage(); + + + //$('#modal_form').modal('show'); + $("#modal_form").modal({ + "backdrop": "static" + }); + if (type == "ApFullSlider" || type == "ApBlockCarousel") { + initFullSlider("edit"); + } + hideFormLevel2(); + + $globalthis.setFormAction(); + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + $("#ap_loading").hide(); + alert("TECHNICAL ERROR: \n\nDetails:\nError thrown: " + XMLHttpRequest + "\n" + 'Text status: ' + textStatus); + } + }); + }); + + $(document).on("click", ".btn-new-widget", function () { + var url = $globalthis.ajaxHomeUrl + '&ajax=1&action=renderList'; + if ($(this).hasClass('tabcontent-action')) + { + url += '&subTab=1' + } + if ($(this).hasClass('reload-module')) + { + url += '&reloadModule=1' + } + var data = ''; + if ($(this).hasClass('column-action')) { + $globalthis.currentElement = $(this).closest('.column-row').find('.column-content').first(); + } else if ($(this).hasClass('tabcontent-action')) { + if ($(this).hasClass('accordion')) + $globalthis.currentElement = $(this).closest('.panel-collapse').find('.subwidget-content').first(); + else + $globalthis.currentElement = $(this).closest('.tab-pane').find('.subwidget-content').first(); + } else { + $globalthis.currentElement = $(this).closest('.hook-content-footer'); + } + $("#ap_loading").show(); + + $.ajax({ + type: 'POST', + headers: {"cache-control": "no-cache"}, + url: url, + async: true, + data: data, + dataType: 'json', + cache: false, + success: function (json) { + $("#ap_loading").hide(); + if (json && json.hasError == true){ + alert(json.errors); + }else{ + $("#txt-search").show(); + $('#myModalLabel').html($('#myModalLabel').data('addnew')); + $('#modal_form .modal-body').html(json.result); + $('#modal_form .modal-footer').hide(); + $('#modal_form').modal('show'); + $('#modal_form').removeClass('modal-edit').addClass('modal-new'); + $globalthis.setFormAction(); + $("#txt-search").focus(); + $globalthis.initIsotopAction(); + } + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + $("#ap_loading").hide(); + alert("TECHNICAL ERROR: \n\nDetails:\nError thrown: " + XMLHttpRequest + "\n" + 'Text status: ' + textStatus); + } + }); + }); + $("#modal_form").on('shown.bs.modal', function () { + $("#txt-search").focus(); + }) + + $(document).on("click", ".btn-status", function () { + if ($(this).data("for") == undefined) { + if ($(this).hasClass("group-action")) { + $globalthis.currentElement = $(this).closest(".group-row"); + } else if ($(this).hasClass("column-action")) { + $globalthis.currentElement = $(this).closest(".column-row"); + } else { + $globalthis.currentElement = $(this).closest(".widget-row"); + } + } + else + $globalthis.currentElement = $(this).closest($(this).data("for")); + objForm = $globalthis.currentElement.data("form"); + + if ($(this).hasClass("deactive")) { + $(this).removeClass("deactive").addClass("active"); + objForm.active = 1; + $(this).children().removeClass("icon-remove"); + $(this).children().addClass("icon-ok"); + } else { + $(this).removeClass("active").addClass("deactive"); + objForm.active = 0; + $(this).children().addClass("icon-remove"); + $(this).children().removeClass("icon-ok"); + // icon-remove + } + objForm = $globalthis.currentElement.data('form', objForm); + }); + + $(document).on("click", ".btn-change-colwidth", function () { + cla = $globalthis.returnWidthClass(); + elementColumn = $(this).closest('.column-row'); + objColumn = $(elementColumn).data('form'); + + valueColToNum = objColumn[cla].toString().replace("-", "."); + val = $(this).data("value"); +// console.log(cla + '--' + valueColToNum + 'claa' + cla); + if (val == 1 && parseFloat(valueColToNum) >= 12) { + alert($("#form_content").data("increase")); + return false; + } + if (val == -1 && parseFloat(valueColToNum) <= 1) { + alert($("#form_content").data("reduce")); + return false; + } + //get index of current width + indexW = jQuery.inArray(valueColToNum.toString(), $globalthis.widthSupport); + indexW = parseInt(indexW) + val; + //get new width + objColumn[cla] = $globalthis.widthSupport[indexW]; + //set class again + classColumn = $globalthis.getClassColumn(objColumn); + + $(elementColumn).attr("class", classColumn); + $(".apbtn-width .width-val", $(elementColumn)).attr("class", "width-val ap-w-" + objColumn[cla].toString().replace(".", "-")); + $(elementColumn).data("form", objColumn); + $globalthis.getNumberColumnInClass(elementColumn, $globalthis.returnWidthClass()); + return false; + }); + + $(document).on("click", ".change-colwidth", function () { + cla = $globalthis.returnWidthClass(); + width = $(this).data('width'); + elementColumn = $(this).closest('.column-row'); + objColumn = $(elementColumn).data('form'); + //get new width + objColumn[cla] = width; + //set class again + classColumn = $globalthis.getClassColumn(objColumn); + + $(elementColumn).attr("class", classColumn); + $(".apbtn-width .width-val", $(elementColumn)).attr("class", "width-val ap-w-" + objColumn[cla].toString().replace(".", "-")); + $(elementColumn).data("form", objColumn); + $(this).closest("ul").find("li").removeClass("selected"); + $(this).closest("li").addClass("selected"); + $globalthis.getNumberColumnInClass(elementColumn, $globalthis.returnWidthClass()); + return false; + }); + + + $(document).on("click", ".btn-add-tab", function () { + //nav-tabs tab-content + widget = $(this).closest('.widget-row'); + tabID = "tab_" + $globalthis.getRandomNumber(); + + tab = $("#default_tabnav").clone(1); + tab.removeAttr("id"); + $(tab).find('a').attr('href', '#' + tabID); + + $(this).parent().before(tab); + + var ObjectTab = {form_id: "form_" + $globalthis.getRandomNumber()}; + ObjectTab.id = tabID; + ObjectTab["css_class"] = ""; + ObjectTab["override_folder"] = ""; + titleTab = $.trim($(tab).find('a').html()); + Object.keys($globalthis.languages).forEach(function (key) { + ObjectTab["title_" + $globalthis.languages[key]] = titleTab; + }); + $(tab).find('a').data("form", ObjectTab); + + tabContent = $("#default_tabcontent").clone(1); + tabContent.attr('id', tabID); + $('.tab-pane', $(widget)).removeClass('active'); + $(tabContent).addClass('active'); + $('.tab-content', $(widget)).append(tabContent); + + $(tab).tab('show'); + $(tab).trigger('click'); + $(tab).addClass('active'); + return false; + }); + + $(document).on("click", ".btn-add-accordion", function () { + //nav-tabs tab-content + panel = $(this).closest('.panel-group'); + //$('.panel-collapse', $(panel)).collapse(); + panelDefault = $(panel).find('.panel-default').first().clone(); + var parent = $(panel).find('.panel-default').first().find(".panel-title a").data("parent"); + collapseID = "collapse-" + $globalthis.getRandomNumber(); + $('.panel-title a', $(panelDefault)).html('New Accordion'); + $('.panel-title a', $(panelDefault)).attr('href', "#" + collapseID); + $('.panel-title a', $(panelDefault)).data("parent", parent.replace("#", "")); + $('.panel-collapse', $(panelDefault)).attr('id', collapseID); + $('.panel-collapse .subwidget-content', $(panelDefault)).html(''); + + ObjectForm = $globalthis.assignDataForm($(panel).find('.panel-default').first().find(".panel-title a"), collapseID); + //ObjectForm = $globalthis.assignDataForm($('.panel-title a',$(panelDefault)), collapseID); + // var ObjectForm = {form_id:"form_"+$globalthis.getRandomNumber()}; + // ObjectForm['parent_id'] = parent; + // ObjectForm['id'] = collapseID; + // ObjectForm['title_1'] = 'New Accordion'; + ObjectForm['title_' + $globalthis.lang_id] = "New Accordion"; + $('.panel-title a', $(panelDefault)).data('form', ObjectForm); + $(this).before(panelDefault); + }); + + $(document).on("click", ".btn-duplicate", function () { + parent = $(this).parent().parent(); + //dublicate widget + if ($(parent).hasClass('widget-row')) { + if ($(this).hasClass('widget-action')) { + duplicate = $(parent).clone(1); + ObjectForm = $globalthis.assignDataForm(duplicate); + $(duplicate).data('form', ObjectForm); + $(parent).parent().append(duplicate); + } + } + + //duplicate accordion + if ($(parent).hasClass('panel-body')) { + panel = $(parent).closest('.panel').clone(1); + panelGroup = $(parent).closest('.panel-group'); + $globalthis.changWidgetFormID(panel); + $globalthis.changeAccordionPanel(panel); + + $(panelGroup).parent().find('.btn-add-accordion').before(panel); + } + + //duplicate accordions + if ($(parent).hasClass("ApAccordions")) { + widgetRow = $(parent).clone(1); + accId = "accordion_" + $globalthis.getRandomNumber(); + ObjectForm = $globalthis.assignDataForm(widgetRow, accId); + + $(widgetRow).data('form', ObjectForm); + $(widgetRow).attr('id', accId); + $(widgetRow).attr('class', 'widget-row ApAccordions ' + $globalthis.classWidget + ' ' + ObjectForm.form_id); + + $globalthis.changWidgetFormID(widgetRow); + $globalthis.changeAccordionPanel(widgetRow, accId); + + $(parent).closest('.column-content').append(widgetRow); + } + + //duplicate tab + if ($(parent).hasClass('tab-pane')) { + widgetRow = $(parent).closest('.widget-row'); + //duplicate tab content + tabContent = $(parent).clone(1); + tabId = "tab_" + $globalthis.getRandomNumber(); + $globalthis.changWidgetFormID(tabContent); + hrefOld = "#" + tabContent.attr('id'); + $(tabContent).attr('id', tabId); + $(parent).closest('.tab-content').append(tabContent); + $('.tab-pane', $(parent).removeClass('active')); + $(tabContent).addClass('active'); + $(parent).parent().append(tabContent); + + //duplicate a + tabTile = $(widgetRow).find('a[href*="' + hrefOld + '"]').parent().clone(1); + tab = $(tabTile).find('a').first(); + $(tab).attr('href', '#' + tabId); + ObjectForm = $globalthis.assignDataForm(tab, tabId); + $(tab).data('form', ObjectForm); + + $(parent).closest('.widget-row').find('.tab-button').before(tabTile); + + $(tab).tab('show'); + $(tab).trigger('click'); + $(tab).addClass('active'); + } + + //duplicate tabs + if ($(parent).hasClass('ApTabs')) { + widgetRow = $(parent).clone(1); + ObjectForm = $globalthis.assignDataForm(widgetRow); + $(widgetRow).data('form', ObjectForm); + $(widgetRow).attr('class', 'widget-row ApTabs ' + $globalthis.classWidget + ' ' + ObjectForm.form_id); + $globalthis.changWidgetFormID(widgetRow); + + $globalthis.changeTabs(widgetRow); + + $(parent).closest('.column-content').append(widgetRow); + } + //duplicate column + if ($(parent).hasClass('for-column-row')) { + var parentColumn = $(parent).closest(".column-row"); + column = $(parentColumn).clone(1); + column = $globalthis.changeDatacolumn(column); + $(parentColumn).parent().append(column); + } + //duplicate group + if ($(parent).hasClass('for-group-row')) { + var parentGroup = $(parent).closest(".group-row"); + group = $(parentGroup).clone(1); + ObjectForm = $globalthis.assignDataForm(group); + $(group).data('form', ObjectForm); + $('.column-row', $(group)).each(function () { + $globalthis.changeDatacolumn(this); + }); + + $(parentGroup).parent().find('.hook-content-footer').before(group); + } + $('.label-tooltip', $($(parent).parent())).tooltip('disable'); + $('.tooltip', $($(parent).parent())).remove(); + }); + + $(document).on("click", ".choose-img", function (e) { + e.preventDefault(); + var link = $(this); + // Store object image for hold the destination after select back + imgId = $(link).data("for"); + $.ajax({ + url: $(link).attr("href"), + beforeSend: function () { + $("#ap_loading").show(); + }, + success: function (response) { + $("#modal_select_image .modal-body").html(response); + $("#modal_select_image .modal-body").css('min-height', $(window).height() * 0.8); + $("#modal_select_image").modal('show'); + $(".img-link").tooltip(); + }, + complete: function () { + $("#ap_loading").hide(); + } + }); + return false; + }); + $(document).on("click", ".selectImg-lang .reset-img", function (e) { + e.preventDefault(); + + $(this).closest('.translatable-field').find('.img-thumbnail').attr('src', ''); + $(this).closest('.translatable-field').find('.img-value').attr('value', '_JS_EMPTY_VALUE_'); + $(this).closest('.translatable-field').find('.img-thumbnail').hide(); + return false; + }); + + $(document).on("click", ".image-manager .img-link", function (e) { + e.stopPropagation(); + var img = $(this).find("img"); + $("#s-image").removeClass("hidden"); + var name = $(img).attr("src"); + $(imgId).val($(img).attr("data-name")); + + var div = $(imgId).closest("div"); + imgDest = $(div).find("img"); + + var widget = $(img).attr("data-widget"); + if(widget == "ApImage360") + { + // ADD code Image 360 : insert image to form + var idRow = 1; + var arr = $("#total_slider").val().split("|"); + arr.sort(function(a, b) { return a - b; }); + for(var i = 0; i < arr.length; i++) { + if(idRow != arr[i]) { + break; + } + idRow++; + } + + var image_name = "image360_" + idRow; + var html = ''; + html += '
    '; + html += '
    '; + html += '
    '; + html += '
    '+$(img).attr("data-name")+'
    '; + html += '
    '; + html += '
    '; + html += ' '; + html += '
    '; + $("#list-slider").append("
  • " + html + "
  • "); + updateListIdFullSlider(); + }else{ + if (imgDest.length > 0) + { + $(imgDest).attr("src", $(img).attr("src")); + $(imgDest).data("img", $(img).data("name")); + $(imgDest).show(); + if ($(imgDest).attr("widget") === "ApCategoryImage"){ + $(imgDest).closest(".list-image").find(".remove-img").removeClass("hidden"); + $(imgDest).removeClass("hidden"); + $(imgDest).attr("src-url", $(img).data("name")); + $(imgDest).data('img', $(img).attr("data-name")); + updateStatusCheck(imgDest); + } + }else{ + $(div).prepend(""); + } + } + + $("#modal_select_image").modal('hide'); + return false; + }); + $(document).on("click", ".remove-img", function (e) { + e.stopPropagation(); + var img = $(this).closest(".list-image").find("img"); + $(img).attr("src-url", ""); + $(img).attr("src", ""); + $(img).addClass("hidden"); + updateStatusCheck(img); + }); + $(".tree-folder-name input:checkbox").change(function () { + $(this).find("input:checkbox").removeAttr("checked"); + }); + //DONGND:: add event for section select animation to group and column + $(document).on("click", ".animation-button", function (e) { + var animation_wrapper = $(this).siblings('.animation-wrapper'); + if (!$(this).hasClass('active')) + { + $(".animation-button.active").siblings('.animation-wrapper').hide(); + $(".animation-button.active").removeClass('active'); + //DONGND:: load config by data + $(this).addClass('active'); + var animation_type = $(this).data('animation-type'); + var animation_delay = $(this).data('animation-delay'); + var animation_duration = $(this).data('animation-duration'); + var animation_iteration_count = $(this).data('animation-iteration-count'); + var animation_infinite = $(this).data('animation-infinite'); + + if (typeof animation_delay != 'undefined') + { + animation_wrapper.find('.animation_delay').val(animation_delay); + } + else + { + animation_wrapper.find('.animation_delay').val(1); + } + + if (typeof animation_duration != 'undefined') + { + animation_wrapper.find('.animation_duration').val(animation_duration); + } + else + { + animation_wrapper.find('.animation_duration').val(1); + } + + if (typeof animation_iteration_count != 'undefined') + { + animation_wrapper.find('.animation_iteration_count').val(animation_iteration_count); + } + else + { + animation_wrapper.find('.animation_iteration_count').val(1); + } + + if (animation_infinite == 1) + { + animation_wrapper.find('.animation_infinite').attr( 'checked', 'checked' ); + } + else + { + animation_wrapper.removeAttr('checked'); + } + //DONGND:: change offset to right with column small + if ($(window).width()-$(this).offset().left < animation_wrapper.width()) + { + animation_wrapper.addClass('offset-right'); + } + animation_wrapper.show(); + + if (typeof animation_type != 'undefined') + { + animation_wrapper.find('.animation_select').val(animation_type).trigger('change'); + } + else + { + animation_wrapper.find('.animation_select').val('none').trigger('change'); + } + + // animation_wrapper.find('.animate-it').trigger('click'); + + } + else + { + $(this).removeClass('active'); + animation_wrapper.hide(); + animation_wrapper.removeClass('offset-right'); + animation_wrapper.find('.animationSandbox').removeClass().removeAttr('style').addClass('animationSandbox'); + } + + }); + + //DONGND:: save config of animation to data form of column/group + $(document).on("click", ".btn-save-animation", function (e) { + var obj_parent = $(this).parents('.animation-wrapper'); + var animation_bt = obj_parent.siblings('.animation-button'); + var animation_type = obj_parent.find('.animation_select').val(); + var animation_delay = obj_parent.find('.animation_delay').val(); + var animation_duration = obj_parent.find('.animation_duration').val(); + var animation_iteration_count = obj_parent.find('.animation_iteration_count').val(); + var animation_infinite = obj_parent.find('.animation_infinite').is(':checked')? 1 : 0; + + $globalthis.assignConfigAnimation(animation_bt, animation_type, animation_delay, animation_duration, animation_iteration_count, animation_infinite); + + //DONGND:: update data form for group/column + if (obj_parent.hasClass('column-animation-wrapper')) + { + var main_obj = obj_parent.parents('.column-row'); + + } + if (obj_parent.hasClass('group-animation-wrapper')) + { + var main_obj = obj_parent.parents('.group-row'); + } + if (typeof main_obj != 'undefined') + { + main_obj.data('form').animation = animation_type; + main_obj.data('form').animation_delay = animation_delay; + main_obj.data('form').animation_duration = animation_duration; + main_obj.data('form').animation_iteration_count = animation_iteration_count; + main_obj.data('form').animation_infinite = animation_infinite; + } + + animation_bt.trigger('click'); + }); + + //DONGND:: hide section select animation for column and group when click out + $(document).on("click", function (e) { + if ($('.animation-button.active').length) + { + e.stopPropagation(); + var container = $('.animation-wrapper'); + var container2 = $('.animation-button'); + + if (container.length && container.has(e.target).length === 0 && container2.has(e.target).length === 0 && !$(e.target).hasClass('animation-button') && !$(e.target).hasClass('animation-wrapper')) { + // container.hide(); + // $('.animation-button.active').siblings('.animation-wrapper').find('.animationSandbox').removeClass().removeAttr('style').addClass('animationSandbox'); + // $('.animation-button.active').removeClass('active'); + $('.animation-button.active').trigger('click'); + } + } + }); + + //DONGND:: active button for section select animation for column and group + $(document).on("change", '.animation_select', function (e) { + var wrapper_obj = $(this).parents('.animation-wrapper'); + if ($(this).val() == "none") { + wrapper_obj.find('.animate_sub').hide(); + } else { + wrapper_obj.find('.animate_sub').show(); + var duration_time = wrapper_obj.find('.animation_duration').val(); + var delay_time = wrapper_obj.find('.animation_delay').val(); + if (wrapper_obj.find('.animation_infinite').is(':checked')) + { + var iteration_number = 'infinite'; + } + else + { + var iteration_number = wrapper_obj.find('.animation_iteration_count').val(); + } + + wrapper_obj.find('.animationSandbox').removeClass().removeAttr('style').attr('style','animation-duration: '+duration_time+'s; animation-delay: '+delay_time+'s; animation-iteration-count: '+iteration_number).addClass($(this).val() + ' animated animationSandbox').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () { + $(this).removeClass().removeAttr('style').addClass('animationSandbox'); + }); + } + }); + + //DONGND:: run demo with current config + $(document).on("click", '.animate-it', function (e) { + var wrapper_obj = $(this).parents('.animation-wrapper'); + wrapper_obj.find('.animation_select').trigger('change'); + }); + + //DONGND:: copy to clipboard + $(document).on("click", '.bt_copy_clipboard', function (e) { + var text_copy = ''; + + if ($(this).hasClass('shortcode_key')) + { + text_copy = $('#shortcode_key').val(); + }; + if ($(this).hasClass('shortcode_embedded_hook')) + { + text_copy = $('#shortcode_embedded_hook').val(); + }; + if ($(this).hasClass('shortcode_embedded_code')) + { + text_copy = $('#shortcode_embedded_code').val(); + }; + + if (text_copy != '') + { + var $temp = $(""); + $("body").append($temp); + $temp.val(text_copy).select(); + document.execCommand("copy"); + showSuccessMessage('Copy successful'); + $temp.remove(); + } + }); + + }; + + //DONGND:: assign config to data form column/group + this.assignConfigAnimation = function (obj_bt, data_type, data_delay, data_duration, data_iteration, data_infinite) { + obj_bt.data('animation-type', data_type); + obj_bt.data('animation-delay', data_delay); + obj_bt.data('animation-duration', data_duration); + obj_bt.data('animation-iteration-count', data_iteration); + obj_bt.data('animation-infinite', data_infinite); + var txt_default = obj_bt.find('.animation-status').data('text-default'); + if (data_type != 'none') + { + obj_bt.addClass('btn-success'); + var txt_infinite = obj_bt.find('.animation-status').data('text-infinite'); + obj_bt.find('.animation-status').text(data_type + (data_infinite == 1 ? ' ('+txt_infinite+')' : '')); + } + else + { + obj_bt.removeClass('btn-success'); + obj_bt.find('.animation-status').text(txt_default); + } + }; + + this.changeDatacolumn = function (column) { + var $globalthis = this; + ObjectForm = $globalthis.assignDataForm(column); + $(column).data('form', ObjectForm); + $('.widget-row', $(column)).each(function () { + widgetRow = $(this); + if ($(this).hasClass('ApAccordions')) { + accId = "accordion_" + $globalthis.getRandomNumber(); + ObjectForm = $globalthis.assignDataForm(widgetRow, accId); + + $(widgetRow).data('form', ObjectForm); + $(widgetRow).attr('id', accId); + $(widgetRow).attr('class', 'widget-row ApAccordions ' + $globalthis.classWidget + ' ' + ObjectForm.form_id); + + $globalthis.changeAccordionPanel(widgetRow, accId); + } else { + ObjectForm = $globalthis.assignDataForm(widgetRow); + $(widgetRow).data('form', ObjectForm); + + if ($(this).hasClass('ApTabs')) { + $(widgetRow).attr('class', 'widget-row ApTabs ' + $globalthis.classWidget + ObjectForm.form_id); + $globalthis.changeTabs(widgetRow); + } + } + }); + + return column; + }; + this.returnWidthClass = function (width) { + $globalthis = this; + if (!width) + width = $globalthis.windowWidth; + if (parseInt(width) >= 1200) + return 'xl'; + if (parseInt(width) >= 992) + return 'lg'; + if (parseInt(width) >= 768) + return 'md'; + if (parseInt(width) >= 576) + return 'sm'; + if (parseInt(width) >= 480) + return 'xs'; + if (parseInt(width) < 480) + return 'sp'; + }; + this.getClassColumn = function (objCol) { + $globalthis = this; + classColumn = 'column-row ' + $globalthis.classWidget; + for (ic = 0; ic < $globalthis.arrayCol.length; ic++) { + if (objCol[$globalthis.arrayCol[ic]]) { + valueCol = objCol[$globalthis.arrayCol[ic]]; + if (valueCol.toString().indexOf(".") != -1) { + valueCol = valueCol.toString().replace(".", "-"); + } + classColumn += " col-" + $globalthis.arrayCol[ic] + "-" + valueCol; + } + } + return classColumn; + }; + this.changWidgetFormID = function (panel) { + var $globalthis = this; + $('.widget-row', $(panel)).each(function () { + var ObjectForm = {form_id: "form_" + $globalthis.getRandomNumber()}; + dataForm = $(this).data("form"); + Object.keys(dataForm).forEach(function (key) { + if (key != 'form_id') + ObjectForm[key] = dataForm[key]; + }); + + $(this).data('form', ObjectForm); + }); + }; + this.assignDataForm = function (element, id) { + var $globalthis = this; + dataForm = $(element).data("form"); + var ObjectForm = {form_id: "form_" + $globalthis.getRandomNumber()}; + Object.keys(dataForm).forEach(function (key) { + if (key != 'form_id') { + if (id && key == 'id') + ObjectForm[key] = id; + else + ObjectForm[key] = dataForm[key]; + } + }); + return ObjectForm; + }; + this.changeTabs = function (widget) { + var $globalthis = this; + $('.widget-container-heading li a', $(widget)).each(function () { + if ($(this).parent().attr("id") != "default_tabnav" && !$(this).parent().hasClass("tab-button")) { + OldHref = $(this).attr('href').replace('#', ''); + tabID = "tab_" + $globalthis.getRandomNumber(); + $(this).attr('href', "#" + tabID); + ObjectForm = $globalthis.assignDataForm(this, tabID); + $(this).data('form', ObjectForm); + $(widget).find('.tab-pane').each(function () { + if ($(this).attr('id') == OldHref) { + $(this).attr('id', tabID); + return false; + } + }); + + accId = "accordion_" + $globalthis.getRandomNumber(); + ObjectForm = $globalthis.assignDataForm(widgetRow, accId); + + $(widgetRow).data('form', ObjectForm); + $(widgetRow).attr('id', accId); + $(widgetRow).attr('class', 'widget-row ApAccordions ' + $globalthis.classWidget + ' ' + ObjectForm.form_id); + + $globalthis.changWidgetFormID(widgetRow); + $globalthis.changeAccordionPanel(widgetRow, accId); + } + }); + }; + this.changeAccordionPanel = function (panel, accId) { + var $globalthis = this; + $('.panel-title a', $(panel)).each(function () { + newHref = "collapse_" + $globalthis.getRandomNumber(); + ObjectForm = $globalthis.assignDataForm($(this), newHref); + if (accId) { + ObjectForm.parent_id = accId; + $(this).data('parent', '#' + accId); + } + $(this).data('form', ObjectForm); + $(this).attr('class', ObjectForm.form_id); + oldHref = $(this).attr('href').replace('#', ''); + + $(this).attr('href', '#' + newHref); + + $(panel).find('.panel-collapse').each(function () { + if ($(this).attr('id') == oldHref) { + $(this).attr('id', newHref); + return false; + } + }); + }); + }; + this.getRandomNumber = function () { + return (+new Date() + (Math.random() * 10000000000000000)).toString().replace('.', ''); + }; + this.testAnim = function (x) { + $('#animationSandbox').removeClass().addClass(x + ' animated').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () { + $(this).removeClass(); + }); + }; + // AJAX LOAD FORM, LOAD WIDGET + this.setFormAction = function () { + var $globalthis = this; + + //DONGND:: slick custom enable/disable + $('#slick_custom_status').change(function(){ + if($(this).val() == 1) + { + $('#slick_custom').parents('.form-group').show(); + } + else + { + $('#slick_custom').parents('.form-group').hide(); + } + }); + + + //DONGND:: slick center mode enable/disable + $('#slick_centermode').change(function(){ + if($(this).val() == 1) + { + $('#slick_centerpadding').parents('.form-group').show(); + } + else + { + $('#slick_centerpadding').parents('.form-group').hide(); + } + }); + + $('.form-action').change(function () { + var elementName = $(this).attr('name'); + $('.' + elementName + '_sub').hide(); + $('.' + elementName + '-' + $(this).val()).show(); + + //DONGND:: special fields of slick carousel + if ($(this).val() == 'slickcarousel') + { + $('#slick_custom_status').trigger('change'); + $('#slick_centermode').trigger('change'); + } + }); + + // Show tool tip, hint of label + $("#modal_form .label-tooltip").tooltip(); + + if ($('select[name="bg_config"]').length) { + + $('select[name="bg_config"]').change(function () { + if ($(this).val() == "fullwidth") { + if ($("#container").val() == "") { + + bgType = $('select[name="bg_type"] option'); + bgType.prop('selected', false); + bgType.find('option[value="normal"]').prop('selected', true); + + $('select[name="bg_type"] option').each(function () { + if ($(this).val() != "normal" && $(this).val() != "fixed") + $(this).attr('disabled', 'disabled'); + }); + } else { + $('select[name="bg_type"] option').each(function () { + if ($(this).val() != "normal" && $(this).val() != "fixed") + $(this).removeAttr('disabled', 'disabled'); + }); + } + } else { + $('select[name="bg_type"] option').each(function () { + if ($(this).val() != "normal" && $(this).val() != "fixed") + $(this).removeAttr('disabled', 'disabled'); + }); + } + }); + $("#container").change(function () { + $('select[name="bg_config"]').trigger("change"); + }) + $('select[name="bg_config"]').trigger("change"); + } + + $('.checkbox-group').change(function () { + $globalthis.showOrHideCheckBox($(this)); + }); + + $('.width-select').click(function () { + btnGroup = $(this).closest('.btn-group'); + spanObj = $('.width-val', $(this)); + width = $(spanObj).data('width'); + $('.col-val', $(btnGroup)).val(width); + $('.apbtn-width .width-val', $(btnGroup)).html($(spanObj).html()); + $('.apbtn-width .width-val', $(btnGroup)).attr('class', $(spanObj).attr('class')); + }); + if ($('.aptab-config').length > 0) { + //set tab aciton + $('.aptab-config').each(function () { + if (!$(this).parent().hasClass('active')) { + element = $(this).attr('href').toString().replace("#", "."); + $(element).hide(); + } + }); + + $('.aptab-config').click(function () { + divElement = $(this).attr('href').toString().replace("#", "."); + aElement = $(this); + $('.aptab-config').each(function () { + if ($(this).parent().hasClass('active')) { + element = $(this).attr('href').toString().replace("#", "."); + $(this).parent().removeClass('active'); + $(element).hide(); + return false; + } + }); + $(divElement).show(); + $(aElement).parent().addClass('active'); + + $('.form-action', $(divElement)).each(function () { + $(this).trigger("change"); + }); + + $('.checkbox-group', $(divElement)).each(function () { + $globalthis.showOrHideCheckBox($(this)); + }); + + + // if ($(this).attr('href') == "#aprow_animation" && $('#animation').length > 0) + // $('#animation').trigger("change"); + + }); + } + + if ($('.em_text').length > 0) { + //page in column form + $('.em_text').change(function () { + var list = $(this).closest('.well').find('.em_list'); + var values = ""; + if ($(this).val()) + values = $(this).val().split(','); + var len = values.length; + + list.find('option').prop('selected', false); + for (var i = 0; i < len; i++) + list.find('option[value="' + $.trim(values[i]) + '"]').prop('selected', true); + }); + $('.em_list').change(function () { + if ($(this).val()) { + var str = $(this).val().join(', '); + var text = $(this).closest('.well').find('.em_text'); + $(text).val(str); + } + }); + } + + if ($('#animation').length > 0) { + $('#animation').after(''); + $('.animate-it').click(function () { + $('#animation').trigger("change"); + }); + $('#animation').change(function () { + if ($(this).val() == "none") { + $('.animate_sub').hide(); + } else { + $('.animate_sub').show(); + $globalthis.testAnim($(this).val()); + } + }); + } + + if ($('.select-img').length > 0) { + /*$('.select-img').click(function(){ + $.fancybox.open([{ + type: 'iframe', + href: $globalthis.imgController, + afterLoad: function () { + $globalthis.hideSomeElement(); + //$('.fancybox-iframe').load( $this.hideSomeElement ); + }, + afterClose: function (event, ui) { + //location.reload(); + } + }], { + padding: 10 + }); + return false; + }); + */ + } + + if ($('.form-action').length > 0 || $('.checkbox-group').length) { + if ($("#configuration_form .nav-tabs").length) + $("#configuration_form .nav-tabs li.active a").trigger("click"); + else { + $('.form-action').trigger("change"); + $('.checkbox-group').each(function () { + $globalthis.showOrHideCheckBox($(this)); + }); + } + } + + if ($(".select-class").length) { + $(".select-class").click(function () { + if ($(this).is(':checked')) { + + $('.select-class').each(function() { + // REMOVE ALL CHECKBOX VALUE IN TEXT + var classChk = $(this).data("value"); + input_text = $(this).closest('.well').find('.element_class').first().val(); + // trim string + var input_text = input_text.replace(classChk, ""); + input_text = input_text.split(" ").join(" "); + input_text = $.trim(input_text); + + $(this).closest('.well').find('.element_class').first().val(input_text); + }); + + var classChk = $(this).data("value"); + var elementText = $(this).closest('.well').find('.element_class').first(); + + // SET VALUE CHECKBOX TO TEXT + if ($(elementText).val().indexOf(classChk) == -1) { + if ($(elementText).val() != "") { + $(elementText).val($(elementText).val() + " " + classChk); + } else { + $(elementText).val(classChk); + } + } + } + }); + + $(".chk-row").click(function () { + var classChk = $(this).data("value"); + var elementText = $(this).closest('.well').find('.element_class').first(); + if ($(elementText).val().indexOf(classChk) == -1) { + // NOT EXIST AND ADD + if ($(elementText).val() != "") { + $(elementText).val($(elementText).val() + " " + classChk); + } else { + $(elementText).val(classChk); + } + }else{ + // EXIST AND REMOVE + var find = classChk; + var re = new RegExp(find, 'g'); + var text = $(elementText).val(); + text = text.replace(re, ''); + $(elementText).val(text); + } + }); + + $(".element_class").change(function () { + elementChk = $(this).closest('.well').find('input[type=checkbox]'); + classText = $(this).val(); + $(elementChk).each(function () { + classChk = $(this).data("value"); + if (classText.indexOf(classChk) != -1) { + if (!$(this).is(':checked')) + $(this).prop("checked", true); + } else { + $(this).prop("checked", false); + } + }); + }); + $(".element_class").trigger("change"); + } + + //$('.new-shortcode').click(function() { + $(".cover-short-code").click(function () { + var a = $(this).find("a"); + var tab = $(a).hasClass("module") ? "module" : "widget"; + $(".btn-back-to-list").attr("tab", tab); + // Add widget + url = $globalthis.ajaxShortCodeUrl + "&addnew&type_shortcode=" + + $(a).data("type") + "&type=" + tab; + + data = ""; + $("#ap_loading").show(); + $.ajax({ + type: 'POST', + headers: {"cache-control": "no-cache"}, + url: url, + async: true, + cache: false, + data: data, + success: function (data) { + $("#txt-search").hide(); + $('#myModalLabel').html($('#myModalLabel').data('addnew')); + $("#ap_loading").hide(); + $('#modal_form .modal-footer').show(); + $('#modal_form .modal-body').html(data); + $('#myModalLabel').html($('#myModalLabel').html() + ' : ' + $('.modal-widget-title').html()); + resetSelectedImage(); + if ($(a).data("type") == "ApFullSlider" || $(a).data("type") == "ApBlockCarousel") { + initFullSlider("add"); + } + hideFormLevel2(); + $globalthis.setFormAction(); + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + $("#ap_loading").hide(); + alert("TECHNICAL ERROR: \n\nDetails:\nError thrown: " + XMLHttpRequest + "\n" + 'Text status: ' + textStatus); + } + }); + }); + if ($("#list-slider").length > 0) { + $("#list-slider").sortable({accept: "div", + update: function () { + var listId = ""; + var sep = ""; + $("#list-slider li").each(function () { + var id = (typeof $(this).attr("id") != "undefined") ? $(this).attr("id") : ""; + if (id) { + listId += sep + id; + sep = "|"; + } + }); + $("#total_slider").val(listId); + } + }); + } + }; + this.initControllInRow = function () { + $globalthis = this; + $('.btn-custom').popover({ + html: true, + content: function () { + $globalthis.currentElement = $('.group-content', $(this).closest('.group-row')); + return $('#addnew-group-form').html(); + } + }); + $('.btn-custom').on('shown.bs.popover', function () { + $('.number-column').click(function () { + widthCol = $(this).data('width'); + classActive = $globalthis.returnWidthClass(); + realValue = widthCol.toString().replace('.', '-'); + $('.column-row', $($globalthis.currentElement)).each(function () { + ObjColumn = $(this).data('form'); + oldClass = ObjColumn[classActive].toString().replace('.', '-'); + if (classActive == "md" || classActive == "lg" || classActive == "xl") { + classColumn = $(this).attr('class').replace('col-xl-' + oldClass, 'col-xl-' + realValue).replace('col-lg-' + oldClass, 'col-lg-' + realValue).replace('col-md-' + oldClass, 'col-md-' + realValue); + ObjColumn.md = ObjColumn.lg = ObjColumn.xl = widthCol; + } else { + classColumn = $(this).attr('class').replace('col-' + classActive + '-' + oldClass, 'col-' + classActive + '-' + realValue); + ObjColumn[classActive] = widthCol; + } + + $(this).attr('class', classColumn); + $(this).data('form', ObjColumn); + $globalthis.getNumberColumnInClass(this, classActive); + }); + }); + }); + + $('.btn-add-column').popover({ + html: true, + content: function () { + $globalthis.currentElement = $('.group-content', $(this).closest('.group-row')); + return $('#addnew-column-form').html(); + } + }); + $('.btn-add-column').on('shown.bs.popover', function () { + }); + + btn_new_widget_group('.btn-new-widget-group'); + + } + this.initIsotopAction = function () { + var $containerWidget = $("#widget_container"); + var $containerModule = $("#module_container"); + var currentTab = "widget"; + // init + $containerWidget.isotope({ + // options + itemSelector: ".item", + layoutMode: "fitRows" + }); + $containerModule.isotope({ + // options + itemSelector: ".item", + layoutMode: "fitRows" + }); + function searchWidget(search) { + var tab = currentTab; + //log(tab); + //log(search); + $("#modal_form .for-" + tab + " .btn").removeClass("is-checked"); + $("#modal_form .for-" + tab + " li:first-child .btn").addClass("is-checked"); + + // Detect and search by name + var container = (tab === "widget" ? $containerWidget : $containerModule); + container.isotope({ + filter: function () { + if (search === "") { + return true; + } else { + var label = $(this).find(".label").text().toLowerCase() + " " + + $(this).find("small i").text().toLowerCase(); + return label.search(search) !== -1; + } + } + }); + } + searchWidget($("#modal_form #txt-search").val().toLowerCase()); + + $("#tab-new-widget").on("click", "a", function () { + currentTab = $(this).attr("aria-controls"); + var search = $("#txt-search").val().toLowerCase(); + var filterValue = $(".for-" + currentTab + " .is-checked").data("filter"); + // Reinit + var container = (currentTab === "widget" ? $containerWidget : $containerModule); + + // Priority is action search, in the case text search is not empty + // will search and reset sub category is Show all + if (filterValue !== "*") { + $(".for-" + currentTab + " .btn").removeClass("is-checked"); + $(".for-" + currentTab + " li:first-child .btn").addClass("is-checked"); + } + setTimeout(function () { + container.isotope({ + // options + itemSelector: ".item", + layoutMode: "fitRows", + filter: function () { + if (search === "") { + // Check selected other category + if (filterValue === "*") { + return true; + } else { + return $(this).data("tag") === filterValue; + } + } else { + var label = $(this).find(".label").text().toLowerCase() + " " + + $(this).find("small i").text().toLowerCase(); + return label.search(search) !== -1; + } + } + }); + }, 100); + }); + $("#modal_form").on("keyup", "#txt-search", function () { + var search = $(this).val().toLowerCase(); + searchWidget(search); + }); + + $(".filters").on("click", "button", function () { + var tab = $(this).closest("ol").data("for"); + var filterValue = filterValue = $(this).data("filter"); + var container = (tab === "widget" ? $containerWidget : $containerModule); + $("#modal_form .for-" + tab + " button").removeClass("is-checked"); + $(this).addClass("is-checked"); + $("#txt-search").val(""); + $("#txt-search").focus(); + container.isotope({ + filter: function () { + if (filterValue === "*") { + return true; + } else { + return $(this).data("tag").search(filterValue) >= 0; + } + } + }); + }); + $(".filters li:first-child button").trigger("click"); + }; + this.hideSomeElement = function () { + $('body', $('.fancybox-iframe').contents()).find("#header").hide(); + $('body', $('.fancybox-iframe').contents()).find("#footer").hide(); + $('body', $('.fancybox-iframe').contents()).find(".page-head, #nav-sidebar ").hide(); + }; + this.showOrHideCheckBox = function (checkbox) { + id = $(checkbox).attr('id'); + if ($(checkbox).is(':checked')) + $('.' + id).show(); + else + $('.' + id).hide(); + }; + this.copyLang = function (element) { + var $globalthis = this; + var reg = new RegExp("_" + $globalthis.lang_id, "g"); + //if(typeof $(element) != undefined && !$(element).hasClass("ignore-lang") && typeof $(element).attr("id") != undefined) { + if (typeof $(element) != undefined && !$(element).hasClass("ignore-lang") && $(element).attr("id")) { + idTemp = $(element).attr("id").replace(reg, ""); + + Object.keys($globalthis.languages).forEach(function (key) { + lang = $globalthis.languages[key]; + if (lang != $globalthis.lang_id && $("#" + idTemp + "_" + lang).val() == "") { + $("#" + idTemp + "_" + lang).val($("#" + idTemp + "_" + $globalthis.lang_id).val()); + } + }); + } + }; + this.saveWidget = function (type) { + var $globalthis = this; + currentE = $globalthis.currentElement; + + var ObjectForm = {form_id: "form_" + $globalthis.getRandomNumber()}; + contentHtml = ""; + + widgetType = ''; + + // FIX : widget AP_RAW_HTML always get content of AP_HTML which created before + $($("#configuration_form").serializeArray()).each(function (i, field) { + if (field.name.substring(0, 2).toLowerCase() == 'ap' && field.value == '1') { + widgetType = field.name; + } + }); + + if (typeof tinyMCE != "undefined" && widgetType != 'ApRawHtml') { + tinyMCE.triggerSave(); + //var mce = tinyMCE.activeEditor.getContent(); + //log(tinyMCE.activeEditor.settings.id); + //$("#" + tinyMCE.activeEditor.settings.id).val(mce); + } + + //update language for other field + $("#configuration_form .lang-" + $globalthis.lang_id).each(function () { + $(this).find('input[type="text"]').each(function () { + $globalthis.copyLang($(this)); + }); + $(this).find('textarea').each(function () { + $globalthis.copyLang($(this)); + }); + }); + + $($("#configuration_form").serializeArray()).each(function (i, field) { + + // SET EMPTY VALUE AFTER UPDATE LANGUAGE FOR OTHER FIELD + if( field.value == '_JS_EMPTY_VALUE_') + { + field.value = ''; + } + + if (field.name.substring(0, 2).toLowerCase() == 'ap' && field.value == '1') { + widgetType = field.name; + } else { + if (field.name == "content_html_" + $globalthis.lang_id) { + contentHtml = field.value.replace(/[\n]/g, "").replace(/[\r]/g, ""); + if (type == "update") { + //$(currentE).find('.html-code').html(contentHtml); + } + } + + var fName = field.name; + if (fName.indexOf('[]') != -1) { + fName = fName.replace('[]', ''); + if (ObjectForm[fName]) { + ObjectForm[fName] += ',' + field.value; + } + else { + ObjectForm[fName] = field.value; + } + } else { + //ObjectForm[fName] = field.value.replace(/\&/g,'_APAMP_').replace(/\'/g,'_APAPOST_').replace(/\"/g,'_APQUOT_').replace(/[\t]/g, "_APTAB_").replace(/[\r]/g, "_APNEWLINE_").replace(/[\n]/g, "_APENTER_").replace(/\[/g, "_APOBRACKET_").replace(/\]/g, "_APCBRACKET_"); + var valTemp = field.value.replace(/\&/g, '_APAMP_') + .replace(/\'/g, '_APAPOST_') + .replace(/\"/g, '_APQUOT_') + .replace(/[\t]/g, "_APTAB_") + .replace(/\[/g, "_APOBRACKET_") + .replace(/[\n]/g, "_APENTER_") + .replace(/[\r]/g, "") + .replace(/[+]/g, "_APPLUS_") + .replace(/\{/g, "_APOCBRACKET_") + .replace(/\}/g, "_APCCBRACKET_") + .replace(/\]/g, "_APCBRACKET_"); + ObjectForm[fName] = valTemp; + } + } + }); + + //for sub tab + if (widgetType.indexOf('ApSub') == 0) { + tmpObjectForm = {}; + tmpObjectForm.form_id = ObjectForm.form_id; + tmpObjectForm.id = ObjectForm.id; + Object.keys($globalthis.languages).forEach(function (key) { + tmpObjectForm["title_" + $globalthis.languages[key]] = ObjectForm["title_" + $globalthis.languages[key]]; + }); + ObjectForm = tmpObjectForm; + oldHref = $(currentE).attr("href").toString().replace('#', ''); + panelFind = '.panel-collapse'; + if (widgetType == 'ApSubAccordion') { + ObjectForm.parent_id = $(currentE).data('form').parent_id; + panelFind = '.panel-collapse'; + } else { + panelFind = '.tab-pane'; + } + $(currentE).html(ObjectForm['title_' + $globalthis.lang_id]); + $(currentE).closest('.widget-row').find(panelFind).each(function () { + if ($(this).attr('id') == oldHref) { + $(this).attr('id', ObjectForm.id); + return false; + } + }); + + $(currentE).attr("href", "#" + ObjectForm.id); + } + if (type == "update") { + // SAVE ACTIVE + //DONGND:: fix can't save tab after update + if (widgetType != "ap_sub_tabs") + { + if ($(currentE).find('.btn-status').first().hasClass("deactive")) { + ObjectForm.active = 0; + } else { + ObjectForm.active = 1; + } + } + + if (widgetType == "ApColumn") { + $globalthis.changeColumnClass(currentE, ObjectForm); + } + if (widgetType == "ApRawHtml") { + $(currentE).data("form", ObjectForm); + $(currentE).find(".html-code").html(htmlentities(contentHtml)); + } else if (widgetType == "ApSubAccordion") { + ObjectForm["parent_id"] = $globalthis.parentId; + $(currentE).data("form", ObjectForm); + } else { + $(currentE).data("form", ObjectForm); + } + + //DONGND:: update name of tab after change + if (widgetType == "ap_sub_tabs") + { + $(currentE).text(ObjectForm['title_' + $globalthis.lang_id]); + } + + //console.log(ObjectForm); + $(".label-tooltip").tooltip(); + return true; + } + dataInfo = $globalthis.shortcodeInfos[widgetType]; + + if (widgetType == "ApTabs") { + widget = $("#default_ApTabs").clone(1); + //DONGND:: remove default tab and default content from tab clone + $(widget).find('li#default_tabnav').remove(); + $(widget).find('div#default_tabcontent').remove(); + widget.removeAttr('id'); + $(".widget-container-heading a", $(widget)).each(function () { + if ($(this).parent().attr("id") != "default_tabnav" && !$(this).parent().hasClass("tab-button")) { + var ObjectTab = {form_id: "form_" + $globalthis.getRandomNumber()}; + tabID = "tab_" + $globalthis.getRandomNumber(); + ObjectTab.id = tabID; + ObjectTab["css_class"] = ""; + ObjectTab["override_folder"] = ""; + //set href for tab a + titleTab = $.trim($(this).html()); + Object.keys($globalthis.languages).forEach(function (key) { + ObjectTab["title_" + $globalthis.languages[key]] = titleTab; + }); + + OldHref = $(this).attr('href').replace('#', ''); + $(this).attr("href", "#" + tabID); + $(this).data("form", ObjectTab); + + $(widget).find('.tab-pane').each(function () { + if ($(this).attr('id') == OldHref) { + $(this).attr('id', tabID); + return false; + } + }); + } + }); + } else if (widgetType == "ApAccordions") { + widget = $("#default_ApAccordions").clone(); + widget.removeAttr('id'); + accIdWraper = "accordion_" + $globalthis.getRandomNumber(); + ObjectForm.id = accIdWraper; + $('.panel-group', $(widget)).attr('id', accIdWraper); + $(".panel-title a", $(widget)).each(function () { + $(this).data('parent', accIdWraper); + accIdSub = "collapse_" + $globalthis.getRandomNumber(); + OldHref = $(this).attr('href').replace('#', ''); + $(this).attr('href', "#" + accIdSub); + $('.panel-collapse', $(this).closest('.panel-default')).attr('id', accIdSub); + var ObjectTab = {form_id: "form_" + $globalthis.getRandomNumber()}; + ObjectTab.parent_id = accIdWraper; + ObjectTab.id = accIdSub; + titleTab = $(this).html(); + Object.keys($globalthis.languages).forEach(function (key) { + ObjectTab["title_" + $globalthis.languages[key]] = titleTab; + }); + $(widget).find('.panel-collapse').each(function () { + if ($(this).attr('id') == OldHref) { + $(this).attr('id', tabID); + return false; + } + }); + + $(this).data("form", ObjectTab); + }); + //$('.panel-collapse', $(widget)).last().collapse(); + } else { + if ($("#default_" + widgetType).length) + widget = $("#default_" + widgetType).clone(1); + else + widget = $("#default_widget").clone(1); + if (widgetType == "ApRawHtml") { + $('.widget-title', $(widget)).remove(); + if ($(widget).find('.html-code').first().length == 0) { + $(".widget-content", $(widget)).append("
    " + htmlentities(contentHtml) + "
    "); + } else { + $(widget).find('.html-code').first().html(htmlentities(contentHtml)); + } + } + widget.removeAttr('id'); + } + + //add new widget in column + if (type == 'column') { + widget.removeAttr('id'); + $(currentE).append(widget); + } else { + column = $("#default_column").clone(1); + column.removeAttr('id'); + objColumn = {form_id: "form_" + $globalthis.getRandomNumber()}; + jQuery.extend(objColumn, $globalthis.getColDefault()); + $(column).data("form", objColumn); + + $('.column-content', $(column)).append(widget); + + group = $("#default_row").clone(); + group.removeAttr('id'); + //var html = $(group).find(".group-controll-right").html(); + //$(group).find(".group-controll-right").html(html); + $(group).data("form", {form_id: "form_" + $globalthis.getRandomNumber(), 'class': 'row'}); + $('.group-content', $(group)).append(column); + $(currentE).before(group); + } + + //if element is widget + if (widgetType) { + $(widget).addClass('widget-icon'); + $('.widget-title', $(widget)).html(dataInfo.label); + $('.widget-title', $(widget)).attr('title', dataInfo.desc); + $('.w-icon', $(widget)).addClass(dataInfo.icon_class).addClass(widgetType); + } + //if element is module + $(widget).data("form", ObjectForm); + $(widget).data("type", widgetType); + $(widget).find(".label-tooltip").tooltip(); + $globalthis.sortable(); + }; + this.returnColValue = function (colNumber, finalVal) { + $globalthis = this; + widthVal = $globalthis.returnWidthClass(); + + startSet = 0; + var colDefault = $globalthis.getColDefault(); + for (j = 0; j < $globalthis.arrayCol.length; j++) { + if ($globalthis.arrayCol[j] == widthVal) { + startSet = 1; + colDefault[$globalthis.arrayCol[j]] = finalVal; + continue; + } + + //default xs = 6-> 2 cols.but we set 2 cols, we have to assign again + if (startSet && ((12 / parseInt(colDefault[$globalthis.arrayCol[j]])) < colNumber)) { + colDefault[$globalthis.arrayCol[j]] = finalVal; + } + } + return colDefault; + }; + this.changeColumnClass = function (element, dataObj) { + var $globalthis = this; + columnClass = 'column-row ' + $globalthis.classWidget; + Object.keys($globalthis.getColDefault()).forEach(function (key) { + columnClass += ' col-' + key + '-' + dataObj[key].toString().replace('.', '-'); + }); + $(element).attr('class', columnClass); + }; + this.getSubWidget = function (container) { + var $globalthis = this; + var widgetList = new Object(); + + $(container).children().each(function (iWidget) { + var objWidget = new Object(); + objWidget.params = $(this).data('form'); + if($.isEmptyObject( objWidget.params ) ) + { + $(this).css('background-color', '#ff6f6f'); + // Dont have param -> dont save + $globalthis.isValid = false; + }else{ + $(this).css("background-color", ""); + } + objWidget.type = $(this).data('type'); + + //if it is special widget - load sub widget + if ($(this).find('.subwidget-content').length) { + objWidget.widgets = new Object(); + iSubWidget = 0 + + $(this).find('.widget-container-heading a').each(function () { + if ($(this).parent().attr("id") != "default_tabnav" && !$(this).parent().hasClass("tab-button")) { + + var objSubWidget = new Object(); + objSubWidget.params = $(this).data('form'); + element = $($(this).attr('href')).find('.subwidget-content').first(); + objSubWidget.widgets = $globalthis.getSubWidget(element); + + objWidget.widgets[iSubWidget] = objSubWidget; + iSubWidget++; + } + }); + } + widgetList[iWidget] = objWidget; + }); + return widgetList; + }; + this.getHookSubmit = function (group, isEscape) { + var $globalthis = this; + //group object - contain column + var objGroup = new Object(); + objGroup.params = $(group).data('form'); + objGroup.columns = new Object(); + //find column in this group + $('.column-row', $(group)).each(function (iColumn) { + var objColumn = new Object(); + objColumn.params = $(this).data('form'); + //pass widget for each column + objColumn.widgets = $globalthis.getSubWidget($(this).find('.column-content').first()); + //pass column for each group + objGroup.columns[iColumn] = objColumn; + }); + + //pass group for each hook + return objGroup; + }; + this.submitForm = function () { + var $globalthis = this; + //DONGND: check save submit + if(typeof checkSaveSubmit != 'undefined' && checkSaveSubmit == 0) + { + // SUBMIT FORM - AJAX + $("#page-header-desc-appagebuilder-save").removeAttr("onclick"); + $(document).on("click", "#page-header-desc-appagebuilder-save", function () { + //filter all group + $("#ap_loading").show(); + url = $globalthis.ajaxHomeUrl + '&ajax=1&action=saveData&id_profile=' + $('#current_profile').data('id'); + //form object + var objects = new Object(); + var isValid = true; + $('.hook-wrapper').each(function (iHook) { + //hook object contain group + var objHook = new Object(); + objHook.name = $(this).data("hook"); + + // Get position id + var select = $(this).closest(".position-cover").find(".dropdown ul"); + objHook.position = $(select).data("position"); + objHook.position_id = $(select).data("id"); + if (!objHook.position_id) { + //alert($(select).data("blank-error")); + isValid = false; + //return false; + } + + objHook.groups = {}; + $('.group-row', $(this)).each(function (iGroup) { + objHook.groups[iGroup] = $globalthis.getHookSubmit(this, true); + }); + //set hook to object + objects[iHook] = objHook; + }); + + //DONGND: enable save multithreading + if(checkSaveMultithreading == 1) + { + var i = 0; + doLoop(isValid); + } + else + { + data = 'dataForm=' + JSON.stringify(objects); + $.ajax({ + type: "POST", + headers: {"cache-control": "no-cache"}, + url: url, + async: true, + cache: false, + data: data, + dataType: 'json', + cache: false, + success: function (json) { + $("#ap_loading").hide(); + if (json && json.hasError == true){ + alert(json.errors); + }else{ + if (!isValid) { + window.location.reload(true); + } + else + { + showSuccessMessage('Update successful'); + } + } + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + $("#ap_loading").hide(); + alert("TECHNICAL ERROR: \n\nDetails:\nError thrown: " + XMLHttpRequest + "\n" + 'Text status: ' + textStatus); + } + }); + }; + + //DONGND: function run save multithreading + function doLoop(isValid) { + var temp_obj = new Object(); + temp_obj[i] = objects[i]; + data = 'dataForm=' + JSON.stringify(temp_obj); + if(i+1 == Object.keys(objects).length) + { + data += '&dataLast=1'; + }; + + if(i==0) + { + data += '&dataFirst=1'; + }; + + $.ajax({ + type: "POST", + headers: {"cache-control": "no-cache"}, + url: url, + async: true, + cache: false, + data: data, + dataType: 'json', + cache: false, + success: function (json) { + if (json && json.hasError == true){ + $("#ap_loading").hide(); + alert(json.errors); + }else{ + i++; + if(i< Object.keys(objects).length) + doLoop(isValid); + if(i == Object.keys(objects).length) + { + $("#ap_loading").hide(); + if (!isValid) { + window.location.reload(true); + } + else + { + showSuccessMessage('Update successful'); + } + } + } + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + $("#ap_loading").hide(); + alert("TECHNICAL ERROR: \n\nDetails:\nError thrown: " + XMLHttpRequest + "\n" + 'Text status: ' + textStatus); + } + }); + }; + return false; + }); + } + else + { + // SUBMIT FORM - Normal + $("#page-header-desc-appagebuilder-save").removeAttr("onclick"); + $(document).on("click", "#page-header-desc-appagebuilder-save", function () { + var objects = new Object(); + $globalthis.isValid = true; + $('.hook-wrapper').each(function (iHook) { + //hook object contain group + var objHook = new Object(); + objHook.name = $(this).data("hook"); + + // Get position id + var select = $(this).closest(".position-cover").find(".dropdown ul"); + objHook.position = $(select).data("position"); + objHook.position_id = $(select).data("id"); + // Tuan Vu : comment this code because In new bank profile doen't have position_id + //if (!objHook.position_id) { + //$globalthis.isValid = false; + //} + + objHook.groups = {}; + $('.group-row', $(this)).each(function (iGroup) { + objHook.groups[iGroup] = $globalthis.getHookSubmit(this, true); + }); + //set hook to object + objects[iHook] = objHook; + }); + //console.log(objects); + $('#data_profile').val(JSON.stringify(objects)); + $('#data_id_profile').val($('#current_profile').data('id')); + + if($globalthis.isValid == true) + { + $("#form_data_profile button").click(); + }else{ + alert('A widget has error, please reload this profile.'); + } + }); + }; + + //DONGND:: submit shortcode + $(document).on("click", ".shortcode_save_btn, .shortcode_save_stay_btn", function () { + + if ($(this).hasClass('shortcode_save_stay_btn')) + { + $('#stay_page').val(1); + } + else + { + $('#stay_page').val(0); + } + // console.log($globalthis); + // $globalthis.isValid = true; + var objHook = new Object(); + objHook.groups = {}; + // console.log($('.group-row')); + $('.hook-wrapper .group-row').each(function (iGroup) { + + objHook.groups[iGroup] = $globalthis.getHookSubmit(this, true); + }); + // console.log(objHook); + $('#shortcode_content').val(JSON.stringify(objHook)); + + $('#appagebuilder_shortcode_form').submit(); + return false; + }); + + $(document).on("click", ".position-cover .list-position .position-name", function () { + var select = $(this).closest("ul"); + var isRunning = (typeof $(select).attr("isRunning") != "undefined") ? $(select).attr("isRunning") : ""; + if (isRunning.length > 0) { + return; + } + $(select).attr("isRunning", "running"); + + var id = parseInt($(this).data("id")); + var cover = $(select).closest(".position-cover"); + $("#ap_loading").show(); + $.ajax({ + type: "POST", + headers: {"cache-control": "no-cache"}, + url: $globalthis.ajaxHomeUrl, + async: true, + dataType: 'json', + cache: false, + data: { + "id": id, + "action": "selectPosition", + "position": $(select).data("position"), + "id_profile": $('#current_profile').data('id') + }, + success: function (json) { + $("#ap_loading").hide(); + if (json && json.hasError == true){ + alert(json.errors); + }else{ + $(cover).html(json.html); + $globalthis.reInstallEvent(json.data); + btn_new_widget_group('.btn-new-widget-group'); + } + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + $("#ap_loading").hide(); + alert("TECHNICAL ERROR: \n\nDetails:\nError thrown: " + XMLHttpRequest + "\n" + 'Text status: ' + textStatus); + }, + complete: function () { + $(select).attr("isRunning", ""); + } + }); + return false; + }); + + $(document).on("click", ".box-edit-position .btn-save", function () { + var btn = $(this); + var mode = $(this).closest(".box-edit-position").data("mode"); + var position = $(this).closest(".box-edit-position").data("position"); + var name = $.trim($(this).closest(".box-edit-position").find(".edit-name").val()); + var id = $(this).closest(".box-edit-position").data("id"); + var cover = $(this).closest(".position-cover"); + $("#ap_loading").show(); + $.ajax({ + type: "POST", + dataType: "Json", + headers: {"cache-control": "no-cache"}, + url: $globalthis.ajaxHomeUrl, + async: true, + cache: false, + data: { + "id": id, + "name": name, + "mode": mode, + "action": "processPosition", + "position": position, + "id_profile": $('#current_profile').data('id') + }, + success: function (json) { + $("#ap_loading").hide(); + if (json && json.hasError == true){ + alert(json.errors); + }else{ + if (mode == "new" || mode == "duplicate") { + $(cover).html(json.html); + $globalthis.reInstallEvent(json.data); + } + // Update name after changed + else { + $(cover).find(".dropdown .lbl-name").text(name); + $(btn).closest(".box-edit-position").addClass("hide"); + } + btn_new_widget_group('.btn-new-widget-group'); + } + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + $("#ap_loading").hide(); + alert("TECHNICAL ERROR: \n\nDetails:\nError thrown: " + XMLHttpRequest + "\n" + 'Text status: ' + textStatus); + }, + complete: function () { + $("#ap_loading").hide(); + } + }); + //$(this).closest(".box-edit-position").addClass("hide"); + }); + + $(document).on("click", ".position-cover .list-position .icon-edit, .add-new-position", function (e) { + var boxEdit = $(this).closest(".dropdown").find(".box-edit-position"); + var input = $(boxEdit).find(".edit-name"); + $(boxEdit).removeClass("hide"); + $(boxEdit).attr("data-mode", $(this).hasClass("add-new-position") ? "new" : "edit"); + $(boxEdit).attr("data-position", $(this).closest("ul").data("position")); + $(boxEdit).attr("data-id", $(this).data("id")); + $(this).closest(".dropdown").removeClass("open"); + + var span = $(this).closest("a").find("span"); + input.val(span.text()); + input.focus(); + e.stopPropagation(); + return false; + }); + //icon-edit + $(document).on("click", ".box-edit-position .btn-default", function () { + $(this).closest(".box-edit-position").addClass("hide"); + //var id = "#dropdown-" + $(this).closest(".box-edit-position").data("position"); + //log(id); + $("#dropdown-header").trigger("click"); + }); + + $(document).on("click", ".position-cover .list-position .icon-paste", function (e) { + var boxEdit = $(this).closest(".dropdown").find(".box-edit-position"); + var input = $(boxEdit).find(".edit-name"); + $(boxEdit).removeClass("hide"); + $(boxEdit).attr("data-mode", "duplicate"); + $(boxEdit).attr("data-position", $(this).closest("ul").data("position")); + $(boxEdit).attr("data-id", $(this).data("id")); + $(this).closest(".dropdown").removeClass("open"); + + var span = $(this).closest("a").find("span"); + input.val($(this).data("temp") + " " + span.text()); + input.focus(); + e.stopPropagation(); + return false; + + var boxEdit = $(this).closest(".dropdown").find(".box-edit-position"); + var input = $(boxEdit).find(".edit-name"); + $(boxEdit).removeClass("hide"); + $(boxEdit).attr("mode", "duplicate"); + $(boxEdit).attr("id", $(this).data("id")); + $(this).closest(".dropdown").removeClass("open"); + + var span = $(this).closest("a").find("span"); + input.val(span.text()); + input.focus(); + e.stopPropagation(); + return false; + return false; + }); + }; + this.reInstallEvent = function (dataForm) { + var $globalthis = this; + $globalthis.initDataFrom(dataForm); + $globalthis.setGroupAction(); + $globalthis.sortable(); + $(".label-tooltip").tooltip(); + //$globalthis.setButtonAction(); + //$globalthis.submitForm(); + } + this.initColumnSetting = function () { + var $globalthis = this; + var classActive = $globalthis.returnWidthClass(); + $(".column-row").each(function () { + $globalthis.getNumberColumnInClass(this, classActive); + }); + } + this.getNumberColumnInClass = function (obj, type) { + var cls = $(obj).attr("class").split(" "); + var len = cls.length; + var result = ""; + for (var i = 0; i < len; i++) { + if (cls[i].search("col-" + type) >= 0) { + result = cls[i]; + break; + } + } + var temp = result.replace("col-" + type + "-", ""); + $(obj).find(".pull-right .btn-group .btn span:first-child").attr("class", "width-val ap-w-" + temp); + var group = $(obj).find("ul.dropdown-menu-right"); + $(group).find("li").removeClass("selected"); + $(group).find(".col-" + temp).addClass("selected"); + } + //THIS IS VERY IMPORTANT TO KEEP AT THE END + return this; + }; +})(jQuery); + +/** + * FIX : cant focus to textbox of popup TinyMCE + * http://screencast.com/t/9r6kLtiTMR8S + */ +$(document).on('focusin', function (e) { + if ($(e.target).closest(".mce-window").length) { + e.stopImmediatePropagation(); + } +}); + +/** + * Fixed case : ajax load html, doesnt have event popover + */ +function btn_new_widget_group() { + $('.btn-new-widget-group').popover({ + html: true, + content: function () { + $globalthis.currentElement = $(this).closest('.hook-content-footer'); + //$globalthis.currentElement = $('.group-content',$(this).closest('.group-row')); + return $('#addnew-widget-group-form').html(); + } + }); +} \ No newline at end of file diff --git a/modules/appagebuilder/js/admin/index.php b/modules/appagebuilder/js/admin/index.php new file mode 100644 index 00000000..6bf70e95 --- /dev/null +++ b/modules/appagebuilder/js/admin/index.php @@ -0,0 +1,36 @@ + +* @copyright 2007-2012 PrestaShop SA +* @version Release: $Revision: 13573 $ +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/modules/appagebuilder/js/admin/isotope.pkgd.min.js b/modules/appagebuilder/js/admin/isotope.pkgd.min.js new file mode 100644 index 00000000..2fda1adf --- /dev/null +++ b/modules/appagebuilder/js/admin/isotope.pkgd.min.js @@ -0,0 +1,8 @@ +/** + * @Website: http://isotope.metafizzy.co + * @author Metafizzy + * @copyright 2011–2015 Isotope PACKAGED v2.0.1 + * @description: Filter & sort magical layouts + */ +(function(t){function e(){}function i(t){function i(e){e.prototype.option||(e.prototype.option=function(e){t.isPlainObject(e)&&(this.options=t.extend(!0,this.options,e))})}function n(e,i){t.fn[e]=function(n){if("string"==typeof n){for(var s=o.call(arguments,1),a=0,u=this.length;u>a;a++){var p=this[a],h=t.data(p,e);if(h)if(t.isFunction(h[n])&&"_"!==n.charAt(0)){var f=h[n].apply(h,s);if(void 0!==f)return f}else r("no such method '"+n+"' for "+e+" instance");else r("cannot call methods on "+e+" prior to initialization; "+"attempted to call '"+n+"'")}return this}return this.each(function(){var o=t.data(this,e);o?(o.option(n),o._init()):(o=new i(this,n),t.data(this,e,o))})}}if(t){var r="undefined"==typeof console?e:function(t){console.error(t)};return t.bridget=function(t,e){i(e),n(t,e)},t.bridget}}var o=Array.prototype.slice;"function"==typeof define&&define.amd?define("jquery-bridget/jquery.bridget",["jquery"],i):i(t.jQuery)})(window),function(t){function e(e){var i=t.event;return i.target=i.target||i.srcElement||e,i}var i=document.documentElement,o=function(){};i.addEventListener?o=function(t,e,i){t.addEventListener(e,i,!1)}:i.attachEvent&&(o=function(t,i,o){t[i+o]=o.handleEvent?function(){var i=e(t);o.handleEvent.call(o,i)}:function(){var i=e(t);o.call(t,i)},t.attachEvent("on"+i,t[i+o])});var n=function(){};i.removeEventListener?n=function(t,e,i){t.removeEventListener(e,i,!1)}:i.detachEvent&&(n=function(t,e,i){t.detachEvent("on"+e,t[e+i]);try{delete t[e+i]}catch(o){t[e+i]=void 0}});var r={bind:o,unbind:n};"function"==typeof define&&define.amd?define("eventie/eventie",r):"object"==typeof exports?module.exports=r:t.eventie=r}(this),function(t){function e(t){"function"==typeof t&&(e.isReady?t():r.push(t))}function i(t){var i="readystatechange"===t.type&&"complete"!==n.readyState;if(!e.isReady&&!i){e.isReady=!0;for(var o=0,s=r.length;s>o;o++){var a=r[o];a()}}}function o(o){return o.bind(n,"DOMContentLoaded",i),o.bind(n,"readystatechange",i),o.bind(t,"load",i),e}var n=t.document,r=[];e.isReady=!1,"function"==typeof define&&define.amd?(e.isReady="function"==typeof requirejs,define("doc-ready/doc-ready",["eventie/eventie"],o)):t.docReady=o(t.eventie)}(this),function(){function t(){}function e(t,e){for(var i=t.length;i--;)if(t[i].listener===e)return i;return-1}function i(t){return function(){return this[t].apply(this,arguments)}}var o=t.prototype,n=this,r=n.EventEmitter;o.getListeners=function(t){var e,i,o=this._getEvents();if(t instanceof RegExp){e={};for(i in o)o.hasOwnProperty(i)&&t.test(i)&&(e[i]=o[i])}else e=o[t]||(o[t]=[]);return e},o.flattenListeners=function(t){var e,i=[];for(e=0;t.length>e;e+=1)i.push(t[e].listener);return i},o.getListenersAsObject=function(t){var e,i=this.getListeners(t);return i instanceof Array&&(e={},e[t]=i),e||i},o.addListener=function(t,i){var o,n=this.getListenersAsObject(t),r="object"==typeof i;for(o in n)n.hasOwnProperty(o)&&-1===e(n[o],i)&&n[o].push(r?i:{listener:i,once:!1});return this},o.on=i("addListener"),o.addOnceListener=function(t,e){return this.addListener(t,{listener:e,once:!0})},o.once=i("addOnceListener"),o.defineEvent=function(t){return this.getListeners(t),this},o.defineEvents=function(t){for(var e=0;t.length>e;e+=1)this.defineEvent(t[e]);return this},o.removeListener=function(t,i){var o,n,r=this.getListenersAsObject(t);for(n in r)r.hasOwnProperty(n)&&(o=e(r[n],i),-1!==o&&r[n].splice(o,1));return this},o.off=i("removeListener"),o.addListeners=function(t,e){return this.manipulateListeners(!1,t,e)},o.removeListeners=function(t,e){return this.manipulateListeners(!0,t,e)},o.manipulateListeners=function(t,e,i){var o,n,r=t?this.removeListener:this.addListener,s=t?this.removeListeners:this.addListeners;if("object"!=typeof e||e instanceof RegExp)for(o=i.length;o--;)r.call(this,e,i[o]);else for(o in e)e.hasOwnProperty(o)&&(n=e[o])&&("function"==typeof n?r.call(this,o,n):s.call(this,o,n));return this},o.removeEvent=function(t){var e,i=typeof t,o=this._getEvents();if("string"===i)delete o[t];else if(t instanceof RegExp)for(e in o)o.hasOwnProperty(e)&&t.test(e)&&delete o[e];else delete this._events;return this},o.removeAllListeners=i("removeEvent"),o.emitEvent=function(t,e){var i,o,n,r,s=this.getListenersAsObject(t);for(n in s)if(s.hasOwnProperty(n))for(o=s[n].length;o--;)i=s[n][o],i.once===!0&&this.removeListener(t,i.listener),r=i.listener.apply(this,e||[]),r===this._getOnceReturnValue()&&this.removeListener(t,i.listener);return this},o.trigger=i("emitEvent"),o.emit=function(t){var e=Array.prototype.slice.call(arguments,1);return this.emitEvent(t,e)},o.setOnceReturnValue=function(t){return this._onceReturnValue=t,this},o._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},o._getEvents=function(){return this._events||(this._events={})},t.noConflict=function(){return n.EventEmitter=r,t},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return t}):"object"==typeof module&&module.exports?module.exports=t:this.EventEmitter=t}.call(this),function(t){function e(t){if(t){if("string"==typeof o[t])return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e,n=0,r=i.length;r>n;n++)if(e=i[n]+t,"string"==typeof o[e])return e}}var i="Webkit Moz ms Ms O".split(" "),o=document.documentElement.style;"function"==typeof define&&define.amd?define("get-style-property/get-style-property",[],function(){return e}):"object"==typeof exports?module.exports=e:t.getStyleProperty=e}(window),function(t){function e(t){var e=parseFloat(t),i=-1===t.indexOf("%")&&!isNaN(e);return i&&e}function i(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0,i=s.length;i>e;e++){var o=s[e];t[o]=0}return t}function o(t){function o(t){if("string"==typeof t&&(t=document.querySelector(t)),t&&"object"==typeof t&&t.nodeType){var o=r(t);if("none"===o.display)return i();var n={};n.width=t.offsetWidth,n.height=t.offsetHeight;for(var h=n.isBorderBox=!(!p||!o[p]||"border-box"!==o[p]),f=0,d=s.length;d>f;f++){var l=s[f],c=o[l];c=a(t,c);var y=parseFloat(c);n[l]=isNaN(y)?0:y}var m=n.paddingLeft+n.paddingRight,g=n.paddingTop+n.paddingBottom,v=n.marginLeft+n.marginRight,_=n.marginTop+n.marginBottom,I=n.borderLeftWidth+n.borderRightWidth,L=n.borderTopWidth+n.borderBottomWidth,z=h&&u,S=e(o.width);S!==!1&&(n.width=S+(z?0:m+I));var b=e(o.height);return b!==!1&&(n.height=b+(z?0:g+L)),n.innerWidth=n.width-(m+I),n.innerHeight=n.height-(g+L),n.outerWidth=n.width+v,n.outerHeight=n.height+_,n}}function a(t,e){if(n||-1===e.indexOf("%"))return e;var i=t.style,o=i.left,r=t.runtimeStyle,s=r&&r.left;return s&&(r.left=t.currentStyle.left),i.left=e,e=i.pixelLeft,i.left=o,s&&(r.left=s),e}var u,p=t("boxSizing");return function(){if(p){var t=document.createElement("div");t.style.width="200px",t.style.padding="1px 2px 3px 4px",t.style.borderStyle="solid",t.style.borderWidth="1px 2px 3px 4px",t.style[p]="border-box";var i=document.body||document.documentElement;i.appendChild(t);var o=r(t);u=200===e(o.width),i.removeChild(t)}}(),o}var n=t.getComputedStyle,r=n?function(t){return n(t,null)}:function(t){return t.currentStyle},s=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"];"function"==typeof define&&define.amd?define("get-size/get-size",["get-style-property/get-style-property"],o):"object"==typeof exports?module.exports=o(require("get-style-property")):t.getSize=o(t.getStyleProperty)}(window),function(t,e){function i(t,e){return t[a](e)}function o(t){if(!t.parentNode){var e=document.createDocumentFragment();e.appendChild(t)}}function n(t,e){o(t);for(var i=t.parentNode.querySelectorAll(e),n=0,r=i.length;r>n;n++)if(i[n]===t)return!0;return!1}function r(t,e){return o(t),i(t,e)}var s,a=function(){if(e.matchesSelector)return"matchesSelector";for(var t=["webkit","moz","ms","o"],i=0,o=t.length;o>i;i++){var n=t[i],r=n+"MatchesSelector";if(e[r])return r}}();if(a){var u=document.createElement("div"),p=i(u,"div");s=p?i:r}else s=n;"function"==typeof define&&define.amd?define("matches-selector/matches-selector",[],function(){return s}):window.matchesSelector=s}(this,Element.prototype),function(t){function e(t,e){for(var i in e)t[i]=e[i];return t}function i(t){for(var e in t)return!1;return e=null,!0}function o(t){return t.replace(/([A-Z])/g,function(t){return"-"+t.toLowerCase()})}function n(t,n,r){function a(t,e){t&&(this.element=t,this.layout=e,this.position={x:0,y:0},this._create())}var u=r("transition"),p=r("transform"),h=u&&p,f=!!r("perspective"),d={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"otransitionend",transition:"transitionend"}[u],l=["transform","transition","transitionDuration","transitionProperty"],c=function(){for(var t={},e=0,i=l.length;i>e;e++){var o=l[e],n=r(o);n&&n!==o&&(t[o]=n)}return t}();e(a.prototype,t.prototype),a.prototype._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},a.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},a.prototype.getSize=function(){this.size=n(this.element)},a.prototype.css=function(t){var e=this.element.style;for(var i in t){var o=c[i]||i;e[o]=t[i]}},a.prototype.getPosition=function(){var t=s(this.element),e=this.layout.options,i=e.isOriginLeft,o=e.isOriginTop,n=parseInt(t[i?"left":"right"],10),r=parseInt(t[o?"top":"bottom"],10);n=isNaN(n)?0:n,r=isNaN(r)?0:r;var a=this.layout.size;n-=i?a.paddingLeft:a.paddingRight,r-=o?a.paddingTop:a.paddingBottom,this.position.x=n,this.position.y=r},a.prototype.layoutPosition=function(){var t=this.layout.size,e=this.layout.options,i={};e.isOriginLeft?(i.left=this.position.x+t.paddingLeft+"px",i.right=""):(i.right=this.position.x+t.paddingRight+"px",i.left=""),e.isOriginTop?(i.top=this.position.y+t.paddingTop+"px",i.bottom=""):(i.bottom=this.position.y+t.paddingBottom+"px",i.top=""),this.css(i),this.emitEvent("layout",[this])};var y=f?function(t,e){return"translate3d("+t+"px, "+e+"px, 0)"}:function(t,e){return"translate("+t+"px, "+e+"px)"};a.prototype._transitionTo=function(t,e){this.getPosition();var i=this.position.x,o=this.position.y,n=parseInt(t,10),r=parseInt(e,10),s=n===this.position.x&&r===this.position.y;if(this.setPosition(t,e),s&&!this.isTransitioning)return this.layoutPosition(),void 0;var a=t-i,u=e-o,p={},h=this.layout.options;a=h.isOriginLeft?a:-a,u=h.isOriginTop?u:-u,p.transform=y(a,u),this.transition({to:p,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},a.prototype.goTo=function(t,e){this.setPosition(t,e),this.layoutPosition()},a.prototype.moveTo=h?a.prototype._transitionTo:a.prototype.goTo,a.prototype.setPosition=function(t,e){this.position.x=parseInt(t,10),this.position.y=parseInt(e,10)},a.prototype._nonTransition=function(t){this.css(t.to),t.isCleaning&&this._removeStyles(t.to);for(var e in t.onTransitionEnd)t.onTransitionEnd[e].call(this)},a.prototype._transition=function(t){if(!parseFloat(this.layout.options.transitionDuration))return this._nonTransition(t),void 0;var e=this._transn;for(var i in t.onTransitionEnd)e.onEnd[i]=t.onTransitionEnd[i];for(i in t.to)e.ingProperties[i]=!0,t.isCleaning&&(e.clean[i]=!0);if(t.from){this.css(t.from);var o=this.element.offsetHeight;o=null}this.enableTransition(t.to),this.css(t.to),this.isTransitioning=!0};var m=p&&o(p)+",opacity";a.prototype.enableTransition=function(){this.isTransitioning||(this.css({transitionProperty:m,transitionDuration:this.layout.options.transitionDuration}),this.element.addEventListener(d,this,!1))},a.prototype.transition=a.prototype[u?"_transition":"_nonTransition"],a.prototype.onwebkitTransitionEnd=function(t){this.ontransitionend(t)},a.prototype.onotransitionend=function(t){this.ontransitionend(t)};var g={"-webkit-transform":"transform","-moz-transform":"transform","-o-transform":"transform"};a.prototype.ontransitionend=function(t){if(t.target===this.element){var e=this._transn,o=g[t.propertyName]||t.propertyName;if(delete e.ingProperties[o],i(e.ingProperties)&&this.disableTransition(),o in e.clean&&(this.element.style[t.propertyName]="",delete e.clean[o]),o in e.onEnd){var n=e.onEnd[o];n.call(this),delete e.onEnd[o]}this.emitEvent("transitionEnd",[this])}},a.prototype.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(d,this,!1),this.isTransitioning=!1},a.prototype._removeStyles=function(t){var e={};for(var i in t)e[i]="";this.css(e)};var v={transitionProperty:"",transitionDuration:""};return a.prototype.removeTransitionStyles=function(){this.css(v)},a.prototype.removeElem=function(){this.element.parentNode.removeChild(this.element),this.emitEvent("remove",[this])},a.prototype.remove=function(){if(!u||!parseFloat(this.layout.options.transitionDuration))return this.removeElem(),void 0;var t=this;this.on("transitionEnd",function(){return t.removeElem(),!0}),this.hide()},a.prototype.reveal=function(){delete this.isHidden,this.css({display:""});var t=this.layout.options;this.transition({from:t.hiddenStyle,to:t.visibleStyle,isCleaning:!0})},a.prototype.hide=function(){this.isHidden=!0,this.css({display:""});var t=this.layout.options;this.transition({from:t.visibleStyle,to:t.hiddenStyle,isCleaning:!0,onTransitionEnd:{opacity:function(){this.isHidden&&this.css({display:"none"})}}})},a.prototype.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},a}var r=t.getComputedStyle,s=r?function(t){return r(t,null)}:function(t){return t.currentStyle};"function"==typeof define&&define.amd?define("outlayer/item",["eventEmitter/EventEmitter","get-size/get-size","get-style-property/get-style-property"],n):(t.Outlayer={},t.Outlayer.Item=n(t.EventEmitter,t.getSize,t.getStyleProperty))}(window),function(t){function e(t,e){for(var i in e)t[i]=e[i];return t}function i(t){return"[object Array]"===f.call(t)}function o(t){var e=[];if(i(t))e=t;else if(t&&"number"==typeof t.length)for(var o=0,n=t.length;n>o;o++)e.push(t[o]);else e.push(t);return e}function n(t,e){var i=l(e,t);-1!==i&&e.splice(i,1)}function r(t){return t.replace(/(.)([A-Z])/g,function(t,e,i){return e+"-"+i}).toLowerCase()}function s(i,s,f,l,c,y){function m(t,i){if("string"==typeof t&&(t=a.querySelector(t)),!t||!d(t))return u&&u.error("Bad "+this.constructor.namespace+" element: "+t),void 0;this.element=t,this.options=e({},this.constructor.defaults),this.option(i);var o=++g;this.element.outlayerGUID=o,v[o]=this,this._create(),this.options.isInitLayout&&this.layout()}var g=0,v={};return m.namespace="outlayer",m.Item=y,m.defaults={containerStyle:{position:"relative"},isInitLayout:!0,isOriginLeft:!0,isOriginTop:!0,isResizeBound:!0,isResizingContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}},e(m.prototype,f.prototype),m.prototype.option=function(t){e(this.options,t)},m.prototype._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),e(this.element.style,this.options.containerStyle),this.options.isResizeBound&&this.bindResize()},m.prototype.reloadItems=function(){this.items=this._itemize(this.element.children)},m.prototype._itemize=function(t){for(var e=this._filterFindItemElements(t),i=this.constructor.Item,o=[],n=0,r=e.length;r>n;n++){var s=e[n],a=new i(s,this);o.push(a)}return o},m.prototype._filterFindItemElements=function(t){t=o(t);for(var e=this.options.itemSelector,i=[],n=0,r=t.length;r>n;n++){var s=t[n];if(d(s))if(e){c(s,e)&&i.push(s);for(var a=s.querySelectorAll(e),u=0,p=a.length;p>u;u++)i.push(a[u])}else i.push(s)}return i},m.prototype.getItemElements=function(){for(var t=[],e=0,i=this.items.length;i>e;e++)t.push(this.items[e].element);return t},m.prototype.layout=function(){this._resetLayout(),this._manageStamps();var t=void 0!==this.options.isLayoutInstant?this.options.isLayoutInstant:!this._isLayoutInited;this.layoutItems(this.items,t),this._isLayoutInited=!0},m.prototype._init=m.prototype.layout,m.prototype._resetLayout=function(){this.getSize()},m.prototype.getSize=function(){this.size=l(this.element)},m.prototype._getMeasurement=function(t,e){var i,o=this.options[t];o?("string"==typeof o?i=this.element.querySelector(o):d(o)&&(i=o),this[t]=i?l(i)[e]:o):this[t]=0},m.prototype.layoutItems=function(t,e){t=this._getItemsForLayout(t),this._layoutItems(t,e),this._postLayout()},m.prototype._getItemsForLayout=function(t){for(var e=[],i=0,o=t.length;o>i;i++){var n=t[i];n.isIgnored||e.push(n)}return e},m.prototype._layoutItems=function(t,e){function i(){o.emitEvent("layoutComplete",[o,t])}var o=this;if(!t||!t.length)return i(),void 0;this._itemsOn(t,"layout",i);for(var n=[],r=0,s=t.length;s>r;r++){var a=t[r],u=this._getItemLayoutPosition(a);u.item=a,u.isInstant=e||a.isLayoutInstant,n.push(u)}this._processLayoutQueue(n)},m.prototype._getItemLayoutPosition=function(){return{x:0,y:0}},m.prototype._processLayoutQueue=function(t){for(var e=0,i=t.length;i>e;e++){var o=t[e];this._positionItem(o.item,o.x,o.y,o.isInstant)}},m.prototype._positionItem=function(t,e,i,o){o?t.goTo(e,i):t.moveTo(e,i)},m.prototype._postLayout=function(){this.resizeContainer()},m.prototype.resizeContainer=function(){if(this.options.isResizingContainer){var t=this._getContainerSize();t&&(this._setContainerMeasure(t.width,!0),this._setContainerMeasure(t.height,!1))}},m.prototype._getContainerSize=h,m.prototype._setContainerMeasure=function(t,e){if(void 0!==t){var i=this.size;i.isBorderBox&&(t+=e?i.paddingLeft+i.paddingRight+i.borderLeftWidth+i.borderRightWidth:i.paddingBottom+i.paddingTop+i.borderTopWidth+i.borderBottomWidth),t=Math.max(t,0),this.element.style[e?"width":"height"]=t+"px"}},m.prototype._itemsOn=function(t,e,i){function o(){return n++,n===r&&i.call(s),!0}for(var n=0,r=t.length,s=this,a=0,u=t.length;u>a;a++){var p=t[a];p.on(e,o)}},m.prototype.ignore=function(t){var e=this.getItem(t);e&&(e.isIgnored=!0)},m.prototype.unignore=function(t){var e=this.getItem(t);e&&delete e.isIgnored},m.prototype.stamp=function(t){if(t=this._find(t)){this.stamps=this.stamps.concat(t);for(var e=0,i=t.length;i>e;e++){var o=t[e];this.ignore(o)}}},m.prototype.unstamp=function(t){if(t=this._find(t))for(var e=0,i=t.length;i>e;e++){var o=t[e];n(o,this.stamps),this.unignore(o)}},m.prototype._find=function(t){return t?("string"==typeof t&&(t=this.element.querySelectorAll(t)),t=o(t)):void 0},m.prototype._manageStamps=function(){if(this.stamps&&this.stamps.length){this._getBoundingRect();for(var t=0,e=this.stamps.length;e>t;t++){var i=this.stamps[t];this._manageStamp(i)}}},m.prototype._getBoundingRect=function(){var t=this.element.getBoundingClientRect(),e=this.size;this._boundingRect={left:t.left+e.paddingLeft+e.borderLeftWidth,top:t.top+e.paddingTop+e.borderTopWidth,right:t.right-(e.paddingRight+e.borderRightWidth),bottom:t.bottom-(e.paddingBottom+e.borderBottomWidth)}},m.prototype._manageStamp=h,m.prototype._getElementOffset=function(t){var e=t.getBoundingClientRect(),i=this._boundingRect,o=l(t),n={left:e.left-i.left-o.marginLeft,top:e.top-i.top-o.marginTop,right:i.right-e.right-o.marginRight,bottom:i.bottom-e.bottom-o.marginBottom};return n},m.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},m.prototype.bindResize=function(){this.isResizeBound||(i.bind(t,"resize",this),this.isResizeBound=!0)},m.prototype.unbindResize=function(){this.isResizeBound&&i.unbind(t,"resize",this),this.isResizeBound=!1},m.prototype.onresize=function(){function t(){e.resize(),delete e.resizeTimeout}this.resizeTimeout&&clearTimeout(this.resizeTimeout);var e=this;this.resizeTimeout=setTimeout(t,100)},m.prototype.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},m.prototype.needsResizeLayout=function(){var t=l(this.element),e=this.size&&t;return e&&t.innerWidth!==this.size.innerWidth},m.prototype.addItems=function(t){var e=this._itemize(t);return e.length&&(this.items=this.items.concat(e)),e},m.prototype.appended=function(t){var e=this.addItems(t);e.length&&(this.layoutItems(e,!0),this.reveal(e))},m.prototype.prepended=function(t){var e=this._itemize(t);if(e.length){var i=this.items.slice(0);this.items=e.concat(i),this._resetLayout(),this._manageStamps(),this.layoutItems(e,!0),this.reveal(e),this.layoutItems(i)}},m.prototype.reveal=function(t){var e=t&&t.length;if(e)for(var i=0;e>i;i++){var o=t[i];o.reveal()}},m.prototype.hide=function(t){var e=t&&t.length;if(e)for(var i=0;e>i;i++){var o=t[i];o.hide()}},m.prototype.getItem=function(t){for(var e=0,i=this.items.length;i>e;e++){var o=this.items[e];if(o.element===t)return o}},m.prototype.getItems=function(t){if(t&&t.length){for(var e=[],i=0,o=t.length;o>i;i++){var n=t[i],r=this.getItem(n);r&&e.push(r)}return e}},m.prototype.remove=function(t){t=o(t);var e=this.getItems(t);if(e&&e.length){this._itemsOn(e,"remove",function(){this.emitEvent("removeComplete",[this,e])});for(var i=0,r=e.length;r>i;i++){var s=e[i];s.remove(),n(s,this.items)}}},m.prototype.destroy=function(){var t=this.element.style;t.height="",t.position="",t.width="";for(var e=0,i=this.items.length;i>e;e++){var o=this.items[e];o.destroy()}this.unbindResize(),delete this.element.outlayerGUID,p&&p.removeData(this.element,this.constructor.namespace)},m.data=function(t){var e=t&&t.outlayerGUID;return e&&v[e]},m.create=function(t,i){function o(){m.apply(this,arguments)}return Object.create?o.prototype=Object.create(m.prototype):e(o.prototype,m.prototype),o.prototype.constructor=o,o.defaults=e({},m.defaults),e(o.defaults,i),o.prototype.settings={},o.namespace=t,o.data=m.data,o.Item=function(){y.apply(this,arguments)},o.Item.prototype=new y,s(function(){for(var e=r(t),i=a.querySelectorAll(".js-"+e),n="data-"+e+"-options",s=0,h=i.length;h>s;s++){var f,d=i[s],l=d.getAttribute(n);try{f=l&&JSON.parse(l)}catch(c){u&&u.error("Error parsing "+n+" on "+d.nodeName.toLowerCase()+(d.id?"#"+d.id:"")+": "+c);continue}var y=new o(d,f);p&&p.data(d,t,y)}}),p&&p.bridget&&p.bridget(t,o),o},m.Item=y,m}var a=t.document,u=t.console,p=t.jQuery,h=function(){},f=Object.prototype.toString,d="object"==typeof HTMLElement?function(t){return t instanceof HTMLElement}:function(t){return t&&"object"==typeof t&&1===t.nodeType&&"string"==typeof t.nodeName},l=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var i=0,o=t.length;o>i;i++)if(t[i]===e)return i;return-1};"function"==typeof define&&define.amd?define("outlayer/outlayer",["eventie/eventie","doc-ready/doc-ready","eventEmitter/EventEmitter","get-size/get-size","matches-selector/matches-selector","./item"],s):t.Outlayer=s(t.eventie,t.docReady,t.EventEmitter,t.getSize,t.matchesSelector,t.Outlayer.Item)}(window),function(t){function e(t){function e(){t.Item.apply(this,arguments)}e.prototype=new t.Item,e.prototype._create=function(){this.id=this.layout.itemGUID++,t.Item.prototype._create.call(this),this.sortData={}},e.prototype.updateSortData=function(){if(!this.isIgnored){this.sortData.id=this.id,this.sortData["original-order"]=this.id,this.sortData.random=Math.random();var t=this.layout.options.getSortData,e=this.layout._sorters;for(var i in t){var o=e[i];this.sortData[i]=o(this.element,this)}}};var i=e.prototype.destroy;return e.prototype.destroy=function(){i.apply(this,arguments),this.css({display:""})},e}"function"==typeof define&&define.amd?define("isotope/js/item",["outlayer/outlayer"],e):(t.Isotope=t.Isotope||{},t.Isotope.Item=e(t.Outlayer))}(window),function(t){function e(t,e){function i(t){this.isotope=t,t&&(this.options=t.options[this.namespace],this.element=t.element,this.items=t.filteredItems,this.size=t.size)}return function(){function t(t){return function(){return e.prototype[t].apply(this.isotope,arguments)}}for(var o=["_resetLayout","_getItemLayoutPosition","_manageStamp","_getContainerSize","_getElementOffset","needsResizeLayout"],n=0,r=o.length;r>n;n++){var s=o[n];i.prototype[s]=t(s)}}(),i.prototype.needsVerticalResizeLayout=function(){var e=t(this.isotope.element),i=this.isotope.size&&e;return i&&e.innerHeight!==this.isotope.size.innerHeight},i.prototype._getMeasurement=function(){this.isotope._getMeasurement.apply(this,arguments)},i.prototype.getColumnWidth=function(){this.getSegmentSize("column","Width")},i.prototype.getRowHeight=function(){this.getSegmentSize("row","Height")},i.prototype.getSegmentSize=function(t,e){var i=t+e,o="outer"+e;if(this._getMeasurement(i,o),!this[i]){var n=this.getFirstItemSize();this[i]=n&&n[o]||this.isotope.size["inner"+e]}},i.prototype.getFirstItemSize=function(){var e=this.isotope.filteredItems[0];return e&&e.element&&t(e.element)},i.prototype.layout=function(){this.isotope.layout.apply(this.isotope,arguments)},i.prototype.getSize=function(){this.isotope.getSize(),this.size=this.isotope.size},i.modes={},i.create=function(t,e){function o(){i.apply(this,arguments)}return o.prototype=new i,e&&(o.options=e),o.prototype.namespace=t,i.modes[t]=o,o},i}"function"==typeof define&&define.amd?define("isotope/js/layout-mode",["get-size/get-size","outlayer/outlayer"],e):(t.Isotope=t.Isotope||{},t.Isotope.LayoutMode=e(t.getSize,t.Outlayer))}(window),function(t){function e(t,e){var o=t.create("masonry");return o.prototype._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns();var t=this.cols;for(this.colYs=[];t--;)this.colYs.push(0);this.maxY=0},o.prototype.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var t=this.items[0],i=t&&t.element;this.columnWidth=i&&e(i).outerWidth||this.containerWidth}this.columnWidth+=this.gutter,this.cols=Math.floor((this.containerWidth+this.gutter)/this.columnWidth),this.cols=Math.max(this.cols,1)},o.prototype.getContainerWidth=function(){var t=this.options.isFitWidth?this.element.parentNode:this.element,i=e(t);this.containerWidth=i&&i.innerWidth},o.prototype._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,o=e&&1>e?"round":"ceil",n=Math[o](t.size.outerWidth/this.columnWidth);n=Math.min(n,this.cols);for(var r=this._getColGroup(n),s=Math.min.apply(Math,r),a=i(r,s),u={x:this.columnWidth*a,y:s},p=s+t.size.outerHeight,h=this.cols+1-r.length,f=0;h>f;f++)this.colYs[a+f]=p;return u},o.prototype._getColGroup=function(t){if(2>t)return this.colYs;for(var e=[],i=this.cols+1-t,o=0;i>o;o++){var n=this.colYs.slice(o,o+t);e[o]=Math.max.apply(Math,n)}return e},o.prototype._manageStamp=function(t){var i=e(t),o=this._getElementOffset(t),n=this.options.isOriginLeft?o.left:o.right,r=n+i.outerWidth,s=Math.floor(n/this.columnWidth);s=Math.max(0,s);var a=Math.floor(r/this.columnWidth);a-=r%this.columnWidth?0:1,a=Math.min(this.cols-1,a);for(var u=(this.options.isOriginTop?o.top:o.bottom)+i.outerHeight,p=s;a>=p;p++)this.colYs[p]=Math.max(u,this.colYs[p])},o.prototype._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this.options.isFitWidth&&(t.width=this._getContainerFitWidth()),t},o.prototype._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},o.prototype.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!==this.containerWidth},o}var i=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var i=0,o=t.length;o>i;i++){var n=t[i];if(n===e)return i}return-1};"function"==typeof define&&define.amd?define("masonry/masonry",["outlayer/outlayer","get-size/get-size"],e):t.Masonry=e(t.Outlayer,t.getSize)}(window),function(t){function e(t,e){for(var i in e)t[i]=e[i];return t}function i(t,i){var o=t.create("masonry"),n=o.prototype._getElementOffset,r=o.prototype.layout,s=o.prototype._getMeasurement;e(o.prototype,i.prototype),o.prototype._getElementOffset=n,o.prototype.layout=r,o.prototype._getMeasurement=s;var a=o.prototype.measureColumns;o.prototype.measureColumns=function(){this.items=this.isotope.filteredItems,a.call(this)};var u=o.prototype._manageStamp;return o.prototype._manageStamp=function(){this.options.isOriginLeft=this.isotope.options.isOriginLeft,this.options.isOriginTop=this.isotope.options.isOriginTop,u.apply(this,arguments)},o}"function"==typeof define&&define.amd?define("isotope/js/layout-modes/masonry",["../layout-mode","masonry/masonry"],i):i(t.Isotope.LayoutMode,t.Masonry)}(window),function(t){function e(t){var e=t.create("fitRows");return e.prototype._resetLayout=function(){this.x=0,this.y=0,this.maxY=0},e.prototype._getItemLayoutPosition=function(t){t.getSize(),0!==this.x&&t.size.outerWidth+this.x>this.isotope.size.innerWidth&&(this.x=0,this.y=this.maxY);var e={x:this.x,y:this.y};return this.maxY=Math.max(this.maxY,this.y+t.size.outerHeight),this.x+=t.size.outerWidth,e},e.prototype._getContainerSize=function(){return{height:this.maxY}},e}"function"==typeof define&&define.amd?define("isotope/js/layout-modes/fit-rows",["../layout-mode"],e):e(t.Isotope.LayoutMode)}(window),function(t){function e(t){var e=t.create("vertical",{horizontalAlignment:0});return e.prototype._resetLayout=function(){this.y=0},e.prototype._getItemLayoutPosition=function(t){t.getSize();var e=(this.isotope.size.innerWidth-t.size.outerWidth)*this.options.horizontalAlignment,i=this.y;return this.y+=t.size.outerHeight,{x:e,y:i}},e.prototype._getContainerSize=function(){return{height:this.y}},e}"function"==typeof define&&define.amd?define("isotope/js/layout-modes/vertical",["../layout-mode"],e):e(t.Isotope.LayoutMode)}(window),function(t){function e(t,e){for(var i in e)t[i]=e[i];return t}function i(t){return"[object Array]"===h.call(t)}function o(t){var e=[];if(i(t))e=t;else if(t&&"number"==typeof t.length)for(var o=0,n=t.length;n>o;o++)e.push(t[o]);else e.push(t);return e}function n(t,e){var i=f(e,t);-1!==i&&e.splice(i,1)}function r(t,i,r,u,h){function f(t,e){return function(i,o){for(var n=0,r=t.length;r>n;n++){var s=t[n],a=i.sortData[s],u=o.sortData[s];if(a>u||u>a){var p=void 0!==e[s]?e[s]:e,h=p?1:-1;return(a>u?1:-1)*h}}return 0}}var d=t.create("isotope",{layoutMode:"masonry",isJQueryFiltering:!0,sortAscending:!0});d.Item=u,d.LayoutMode=h,d.prototype._create=function(){this.itemGUID=0,this._sorters={},this._getSorters(),t.prototype._create.call(this),this.modes={},this.filteredItems=this.items,this.sortHistory=["original-order"];for(var e in h.modes)this._initLayoutMode(e)},d.prototype.reloadItems=function(){this.itemGUID=0,t.prototype.reloadItems.call(this)},d.prototype._itemize=function(){for(var e=t.prototype._itemize.apply(this,arguments),i=0,o=e.length;o>i;i++){var n=e[i];n.id=this.itemGUID++}return this._updateItemsSortData(e),e},d.prototype._initLayoutMode=function(t){var i=h.modes[t],o=this.options[t]||{};this.options[t]=i.options?e(i.options,o):o,this.modes[t]=new i(this)},d.prototype.layout=function(){return!this._isLayoutInited&&this.options.isInitLayout?(this.arrange(),void 0):(this._layout(),void 0)},d.prototype._layout=function(){var t=this._getIsInstant();this._resetLayout(),this._manageStamps(),this.layoutItems(this.filteredItems,t),this._isLayoutInited=!0},d.prototype.arrange=function(t){this.option(t),this._getIsInstant(),this.filteredItems=this._filter(this.items),this._sort(),this._layout()},d.prototype._init=d.prototype.arrange,d.prototype._getIsInstant=function(){var t=void 0!==this.options.isLayoutInstant?this.options.isLayoutInstant:!this._isLayoutInited;return this._isInstant=t,t},d.prototype._filter=function(t){function e(){f.reveal(n),f.hide(r)}var i=this.options.filter;i=i||"*";for(var o=[],n=[],r=[],s=this._getFilterTest(i),a=0,u=t.length;u>a;a++){var p=t[a];if(!p.isIgnored){var h=s(p);h&&o.push(p),h&&p.isHidden?n.push(p):h||p.isHidden||r.push(p)}}var f=this;return this._isInstant?this._noTransition(e):e(),o},d.prototype._getFilterTest=function(t){return s&&this.options.isJQueryFiltering?function(e){return s(e.element).is(t)}:"function"==typeof t?function(e){return t(e.element)}:function(e){return r(e.element,t)}},d.prototype.updateSortData=function(t){this._getSorters(),t=o(t); +var e=this.getItems(t);e=e.length?e:this.items,this._updateItemsSortData(e)},d.prototype._getSorters=function(){var t=this.options.getSortData;for(var e in t){var i=t[e];this._sorters[e]=l(i)}},d.prototype._updateItemsSortData=function(t){for(var e=0,i=t.length;i>e;e++){var o=t[e];o.updateSortData()}};var l=function(){function t(t){if("string"!=typeof t)return t;var i=a(t).split(" "),o=i[0],n=o.match(/^\[(.+)\]$/),r=n&&n[1],s=e(r,o),u=d.sortDataParsers[i[1]];return t=u?function(t){return t&&u(s(t))}:function(t){return t&&s(t)}}function e(t,e){var i;return i=t?function(e){return e.getAttribute(t)}:function(t){var i=t.querySelector(e);return i&&p(i)}}return t}();d.sortDataParsers={parseInt:function(t){return parseInt(t,10)},parseFloat:function(t){return parseFloat(t)}},d.prototype._sort=function(){var t=this.options.sortBy;if(t){var e=[].concat.apply(t,this.sortHistory),i=f(e,this.options.sortAscending);this.filteredItems.sort(i),t!==this.sortHistory[0]&&this.sortHistory.unshift(t)}},d.prototype._mode=function(){var t=this.options.layoutMode,e=this.modes[t];if(!e)throw Error("No layout mode: "+t);return e.options=this.options[t],e},d.prototype._resetLayout=function(){t.prototype._resetLayout.call(this),this._mode()._resetLayout()},d.prototype._getItemLayoutPosition=function(t){return this._mode()._getItemLayoutPosition(t)},d.prototype._manageStamp=function(t){this._mode()._manageStamp(t)},d.prototype._getContainerSize=function(){return this._mode()._getContainerSize()},d.prototype.needsResizeLayout=function(){return this._mode().needsResizeLayout()},d.prototype.appended=function(t){var e=this.addItems(t);if(e.length){var i=this._filterRevealAdded(e);this.filteredItems=this.filteredItems.concat(i)}},d.prototype.prepended=function(t){var e=this._itemize(t);if(e.length){var i=this.items.slice(0);this.items=e.concat(i),this._resetLayout(),this._manageStamps();var o=this._filterRevealAdded(e);this.layoutItems(i),this.filteredItems=o.concat(this.filteredItems)}},d.prototype._filterRevealAdded=function(t){var e=this._noTransition(function(){return this._filter(t)});return this.layoutItems(e,!0),this.reveal(e),t},d.prototype.insert=function(t){var e=this.addItems(t);if(e.length){var i,o,n=e.length;for(i=0;n>i;i++)o=e[i],this.element.appendChild(o.element);var r=this._filter(e);for(this._noTransition(function(){this.hide(r)}),i=0;n>i;i++)e[i].isLayoutInstant=!0;for(this.arrange(),i=0;n>i;i++)delete e[i].isLayoutInstant;this.reveal(r)}};var c=d.prototype.remove;return d.prototype.remove=function(t){t=o(t);var e=this.getItems(t);if(c.call(this,t),e&&e.length)for(var i=0,r=e.length;r>i;i++){var s=e[i];n(s,this.filteredItems)}},d.prototype.shuffle=function(){for(var t=0,e=this.items.length;e>t;t++){var i=this.items[t];i.sortData.random=Math.random()}this.options.sortBy="random",this._sort(),this._layout()},d.prototype._noTransition=function(t){var e=this.options.transitionDuration;this.options.transitionDuration=0;var i=t.call(this);return this.options.transitionDuration=e,i},d.prototype.getFilteredItemElements=function(){for(var t=[],e=0,i=this.filteredItems.length;i>e;e++)t.push(this.filteredItems[e].element);return t},d}var s=t.jQuery,a=String.prototype.trim?function(t){return t.trim()}:function(t){return t.replace(/^\s+|\s+$/g,"")},u=document.documentElement,p=u.textContent?function(t){return t.textContent}:function(t){return t.innerText},h=Object.prototype.toString,f=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var i=0,o=t.length;o>i;i++)if(t[i]===e)return i;return-1};"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size","matches-selector/matches-selector","isotope/js/item","isotope/js/layout-mode","isotope/js/layout-modes/masonry","isotope/js/layout-modes/fit-rows","isotope/js/layout-modes/vertical"],r):t.Isotope=r(t.Outlayer,t.getSize,t.matchesSelector,t.Isotope.Item,t.Isotope.LayoutMode)}(window); \ No newline at end of file diff --git a/modules/appagebuilder/js/admin/product-list.js b/modules/appagebuilder/js/admin/product-list.js new file mode 100644 index 00000000..4ade4d7e --- /dev/null +++ b/modules/appagebuilder/js/admin/product-list.js @@ -0,0 +1,97 @@ +/** + * @Website: apollotheme.com - prestashop template provider + * @author Apollotheme + * @copyright 2007-2018 Apollotheme + * @description: + */ +$(document).ready(function() { + //only for product generate + + $('.plist-eedit').click(function(){ + element = $(this).data('element'); + $.fancybox.open([{ + type: 'iframe', + href : ($('#appagebuilder_products_form').length?$('#appagebuilder_products_form').attr('action'):$('#appagebuilder_details_form').attr('action')) + '&pelement=' + element, + afterLoad:function(){ + if( $('body',$('.fancybox-iframe').contents()).find("#main").length ){ + hideSomeElement(); + $('.fancybox-iframe').load( hideSomeElement ); + }else { + $('body',$('.fancybox-iframe').contents()).find("#psException").html('
    Can not find this element
    '); + } + }, + afterClose: function (event, ui) { + } + }], { + padding: 10 + }); + }); + + $('.element-list .plist-element').draggable({ + connectToSortable: ".product-container .content", + revert: "true", + helper: "clone", + stop: function() { + setProFormAction(); + setSortAble(); + } + }); + + $('#saveAndStay').click(function(){ + $('input[name=submitAddappagebuilder_productsAndStay]').val('1'); + genreateForm(); + $('#appagebuilder_products_form').submit(); + return false; + }); + + setProFormAction(); + setSortAble(); +}); + +function genreateForm(){ + //generate grid first + var ObjectFrom = {}; + ObjectFrom.gridLeft = returnObjElemnt('.ap_proGrid .gridLeft-block-content'); + ObjectFrom.gridRight = returnObjElemnt('.ap_proGrid .gridRight-block-content'); + $('input[name=params]').val(JSON.stringify(ObjectFrom)); +} + +function returnObjElemnt(element){ + var Object = {}; + $(element).children().each(function(iElement){ + var Obj = {}; + Obj.name = $(this).data('element'); + + if($(this).hasClass('functional_buttons')){ + Obj.element = returnObjElemnt($('.content', $(this))); + } + if($(this).hasClass('code')){ + Obj.code = replaceSpecialString($('textarea', $(this)).val()); + } + Object[iElement] = Obj; + }); + return Object; +} + +function hideSomeElement(){ + $('body',$('.fancybox-iframe').contents()).addClass("page-sidebar-closed"); +} + +function setSortAble(){ + $( ".product-container .content" ).sortable({ + connectWith: ".content", + }); +} +function setProFormAction(){ + $('.plist-code').click(function(){ + textAre = $(this).closest('.plist-element').find('textarea').first(); + if(textAre.attr('rows') == 20) + $(textAre).attr('rows',5); + else + $(textAre).attr('rows',20); + }); + + $('.plist-eremove').click(function(){ + $(this).closest('.plist-element').remove(); + }); +} \ No newline at end of file diff --git a/modules/appagebuilder/js/admin/setting.js b/modules/appagebuilder/js/admin/setting.js new file mode 100644 index 00000000..083c689d --- /dev/null +++ b/modules/appagebuilder/js/admin/setting.js @@ -0,0 +1,142 @@ +/** + * @Website: apollotheme.com - prestashop template provider + * @author Apollotheme + * @copyright 2007-2018 Apollotheme + * @description: + */ +function proccessData(id) { + var list = $.trim($(id).val()).split(","); + var result = ""; + var sep = ""; + for(var i = 0; i < list.length; i++) { + if($.trim(list[i])) { + result += sep + $.trim(list[i]); + sep = ","; + } + } + $(id).val(result); +} +$(document).ready(function() { + $('.panel-content-builder').slideUp(); + $('span.open-content').click(function(){ + $(this).closest('.panel').find('.panel-content-builder').slideToggle(); + }); + + // SHOW FULL input html + $(".ap-html-full").closest( ".col-lg-9.col-lg-offset-3" ).removeClass("col-lg-9 col-lg-offset-3"); + + //DONGND:: hide home config with theme of leotheme, redirect to profile page + if ($('#psthemecusto').length && (typeof ap_check_theme_name != 'undefined')) + { + $('#psthemecusto .panel').hide(); + $('#psthemecusto').append('
    '+ap_profile_txt_redirect+': '+ap_profile_url+'
    '); + } +}); +function compareListHooks(oldHooks, newHooks) { + //console.log(oldHooks); + //console.log(newHooks); + isEqual = true; + if(oldHooks.length > 0 && newHooks.length > 0) { + for(var i = 0; i < oldHooks.length; i++) { + var isSubLook = false; + for(var j = 0; j < newHooks.length; j++) { + if(oldHooks[i] === newHooks[j]) { + newHooks.splice(j, 1); + //console.log(newHooks); + isSubLook = true; + break; + } + } + if(!isSubLook) { + return false; + } + } + } + return isEqual; +} + +$(function() { + + // SHOW MENU 'Ap Module Configuration' - BEGIN + if( (typeof(js_ap_controller) != 'undefined') && (js_ap_controller == 'module_configuration')){ + $('#subtab-AdminApPageBuilder').addClass('active'); + $('#subtab-AdminApPageBuilderModule').addClass('active'); + $('#subtab-AdminParentModulesSf').removeClass('active'); + } + // SHOW MENU 'Ap Module Configuration' - END + + // Hide RESUME at left menu, BO + if( (typeof(js_ap_dev) != 'undefined') && (js_ap_dev == 1)){ +// $('#tab-AdminDashboard').hide(); + $('.onboarding-navbar').hide(); + } + + $("#hook_header_old").val($("#HEADER_HOOK").val()); + $("#hook_content_old").val($("#CONTENT_HOOK").val()); + $("#hook_footer_old").val($("#FOOTER_HOOK").val()); + $("#hook_product_old").val($("#PRODUCT_HOOK").val()); + + $(".list-all-hooks a").click(function() { + var newHook = $.trim($(this).text()); + var id = $("#position-hook-select").val(); + id = id ? id : "#HEADER_HOOK"; + var listHook = $.trim($(id).val()); + if(listHook.search(newHook) < 0) { + listHook += (listHook ? "," : "") + newHook; + $(id).val(listHook); + } else { + alert("This hook is existed"); + } + }); + $("#HEADER_HOOK, #CONTENT_HOOK, #FOOTER_HOOK, #PRODUCT_HOOK").focus(function() { + var id = "#" + $(this).attr("id"); + $("#position-hook-select").val(id); + }); + $("#btn-save-appagebuilder").click(function(e) { + $isChange = false; + proccessData("#HEADER_HOOK"); + proccessData("#CONTENT_HOOK"); + proccessData("#FOOTER_HOOK"); + proccessData("#PRODUCT_HOOK"); + // Check change config hooks + var oldHook = $.trim($("#hook_header_old").val()).split(","); + var currentHook = $.trim($("#HEADER_HOOK").val()).split(","); + if(oldHook.length != currentHook.length || !compareListHooks(oldHook, currentHook)) { + $isChange = true; + } + oldHook = $.trim($("#hook_content_old").val()).split(","); + currentHook = $.trim($("#CONTENT_HOOK").val()).split(","); + if(oldHook.length != currentHook.length || !compareListHooks(oldHook, currentHook)) { + $isChange = true; + } + oldHook = $.trim($("#hook_footer_old").val()).split(","); + currentHook = $.trim($("#FOOTER_HOOK").val()).split(","); + if(oldHook.length != currentHook.length || !compareListHooks(oldHook, currentHook)) { + $isChange = true; + } + oldHook = $.trim($("#hook_product_old").val()).split(","); + currentHook = $.trim($("#PRODUCT_HOOK").val()).split(","); + if(oldHook.length != currentHook.length || !compareListHooks(oldHook, currentHook)) { + $isChange = true; + } + if($isChange) { + if(!confirm($("#message_confirm").val())) { + e.stopPropagation(); + return false; + } + $("#is_change").val("is_change"); + } + + }); + + $("#modal_form").on("click", ".btn-savewidget", function() { + // Is form add new module to appagebuilder + if($("#modal_form").find(".form_ap_module").length > 0) { + // Validate select hook + if(!$("#select-hook").val()) { + alert($("#select-hook-error").val()); + return false; + } + } + }); +}); \ No newline at end of file diff --git a/modules/appagebuilder/js/admin/themeeditor.js b/modules/appagebuilder/js/admin/themeeditor.js new file mode 100644 index 00000000..38dd4dbf --- /dev/null +++ b/modules/appagebuilder/js/admin/themeeditor.js @@ -0,0 +1,230 @@ +/** + * @copyright Commercial License By LeoTheme.Com + * @email leotheme.com + * @visit http://www.leotheme.com + */ +$(document).ready(function() { + $("#leo-customize .btn-show").click(function() { + $("body").toggleClass("off-customize"); + }); + $('#myCustomTab a').click(function(e) { + e.preventDefault(); + $(this).tab('show'); + }) + $('#myCustomTab a:first').tab('show'); + $("#custom-accordion .accordion-group:first .accordion-body").addClass('in'); + $(".bg-config").hide(); + + setBackGroundAction(); + setPatternActive(); + + $(".clear-bg").click(function() { + var $parent = $(this).parent(); + var $input = $(".input-setting", $parent); + if ($input.val('')) { + if ($parent.hasClass("background-images")) { + $('.bi-wrapper > div', $parent).removeClass('active'); + $($input.data('selector'), $("#main-preview iframe").contents()).css($input.data('attrs'), 'none'); + $('ul select', $parent).each(function(){ + $($input.data('selector'), $("#main-preview iframe").contents()).css($(this).data('attrs'), ''); + }); + $('ul select', $parent).val(""); + $('ul.bg-config', $parent).hide(); + } else { + $input.attr('style', '') + } + $($input.data('selector'), $("#main-preview iframe").contents()).css($input.data('attrs'), 'inherit'); + + } + $input.val(''); + }); + + + /** + * FORM SUBMIT + */ + $("#form").submit(function() { + $('.input-setting').each(function() { + if ($(this).data("match")) { + var val = $(this).data('selector') + "|" + $(this).data('attrs'); + $(this).parent().append(''); + if($(this).data('attrs') == "background-image"){ + $("select",$(this).closest(".background-images")).each(function(){ + // if($(this).val()){ + val = $(this).data('selector') + "|" + $(this).data('attrs'); + $(this).closest(".background-images").append(''); + //} + }); + } + } + }); + return true; + }); + $("#main-preview iframe").ready(function() { + $('.accordion-group input.input-setting').each(function() { + var input = this; + $(input).attr('readonly', 'readonly'); + $(input).ColorPicker({ + onChange: function(hsb, hex, rgb) { + $(input).css('backgroundColor', '#' + hex); + $(input).val(hex); + if ($(input).data('selector')) { + $("#main-preview iframe").contents().find($(input).data('selector')).css($(input).data('attrs'), "#" + $(input).val()) + } + } + }); + }); + $('.accordion-group select.input-setting').change(function() { + var input = this; + if ($(input).data('selector')) { + var ex = $(input).data('attrs') == 'font-size' ? 'px' : ""; + $("#main-preview iframe").contents().find($(input).data('selector')).css($(input).data('attrs'), $(input).val() + ex); + } + }); + }) + + $(".show-for-existed").hide(); + $("#saved-files").change(function() { + setPatternActive(); + if ($(this).val()) { + $(".show-for-notexisted").hide(); + $(".show-for-existed").show(); + } else { + $(".show-for-notexisted").show(); + $(".show-for-existed").hide(); + $("#main-preview iframe").contents().find("#customize-theme").remove(); + return; + } + var url = customizeFolderURL + $(this).val() + ".json?rand=" + Math.random(); + + $.getJSON(url, function(data) { + var items = data; + if (items) { + $('#customize-body .accordion-group').each(function() { + var i = 0; + $("input, select", this).each(function() { + if ($(this).data('match')) { + if (items[$(this).data('match')] && items[$(this).data('match')][i]) { + var el = items[$(this).data('match')][i]; + $(this).val(el.val); + if (el.val == '') { + $(this).css('background', "inherit"); + } + else { + if(el.attr == "background-image"){ + $(this).parent().find("div.pull-left").each(function(){ + if($(this).data("val") == el.val) + $(this).addClass('active'); + }); + }else if(el.attr == "background-color"){ + $(this).css('background', "#" + el.val); // SET BACKGROUND FOR INPUT + }else if(el.attr == "color"){ + $(this).css('background', "#" + el.val); // SET BACKGROUND FOR INPUT + }else { + $(this).closest("ul").show(); + } + } + if(el.attr == "background-color") + $(this).ColorPickerSetColor(el.val); // SET BACKGROUND FOR INPUT + if(el.attr == "color") + $(this).ColorPickerSetColor(el.val); // SET BACKGROUND FOR INPUT + } + i++; + } + }); + + }); + } + }); + + $("#main-preview iframe").contents().find("#customize-theme").remove(); + if ($(this).val()) { + var _link = $(''); + _link.attr('href', customizeFolderURL + $(this).val() + ".css?rand=" + Math.random()); + $("#main-preview iframe").contents().find("head").append(_link); + } + }); + + $("#main-preview iframe").load(function() { + if ($("#main-preview iframe").contents().find(".paneltool.editortool").length) { + $("#main-preview iframe").contents().find(".paneltool.editortool").hide(); + } + }); + $("#upload_pattern").click(function(e){ + e.preventDefault(); + $.fancybox.open([ + { + type: 'iframe', + href : $(this).attr("href"), + afterLoad:function(){ + hideSomeElement(); + }, + afterClose: function (event, ui) { + refressImage(); + } + } + ], { + padding: 10 + }); + + }); + var hideSomeElement = function(){ + $('body',$('.fancybox-iframe').contents()).find("#header").hide(); + $('body',$('.fancybox-iframe').contents()).find("#footer").hide(); + $('body',$('.fancybox-iframe').contents()).find(".page-head, #nav-sidebar ").hide(); + //$('body',$('.fancybox-iframe').contents()).find("#content.bootstrap").css( 'padding',0).css('margin',0); + }; +}); + +var refressImage = function(){ + $.ajax({ + type: 'GET', + url: $("#upload_pattern").attr("href")+ '&ajax=1&action=reloadBackground&sortBy=name', + data: '', + dataType: 'json', + cache: false, // @todo see a way to use cache and to add a timestamps parameter to refresh cache each 10 minutes for example + success: function(data) + { + $('.bi-wrapper').html(data); + setBackGroundAction(); + } + }); +} + +var setBackGroundAction = function(){ + /** + * BACKGROUND-IMAGE SELECTION + */ + $(".background-images").each(function() { + var $parent = this; + var $input = $(".input-setting", $parent); + $(".bi-wrapper > div", this).click(function() { + $(".bg-config",$parent).show(); + $input.val($(this).data('val')); + $('.bi-wrapper > div', $parent).removeClass('active'); + $(this).addClass('active'); + + if ($input.data('selector')) { + $($input.data('selector'), $("#main-preview iframe").contents()).css($input.data('attrs'), 'url(' + $(this).data('image') + ')'); + } + + }); + $(".bg-config select", this).change(function(){ + if ($input.data('selector')) { + $($input.data('selector'), $("#main-preview iframe").contents()).css($(this).data('attrs'), $(this).val()); + } + }); + }); +} + +var setPatternActive = function() +{ + if( $("#saved-files").val() == $("#saved-files").attr('active') && $("#saved-files").val() != '') + { + $("input[name=active][value=" + 1 + "]").prop('checked', true); + }else if ($('#saved-files option').size() == 1){ + $("input[name=active][value=" + 1 + "]").prop('checked', true); + }else{ + $("input[name=active][value=" + 0 + "]").prop('checked', true); + } +} \ No newline at end of file diff --git a/modules/appagebuilder/js/colorpicker/index.php b/modules/appagebuilder/js/colorpicker/index.php new file mode 100644 index 00000000..dfbb709d --- /dev/null +++ b/modules/appagebuilder/js/colorpicker/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; \ No newline at end of file diff --git a/modules/appagebuilder/js/colorpicker/js/colorpicker.js b/modules/appagebuilder/js/colorpicker/js/colorpicker.js new file mode 100644 index 00000000..3d0d2593 --- /dev/null +++ b/modules/appagebuilder/js/colorpicker/js/colorpicker.js @@ -0,0 +1,484 @@ +/** + * + * Color picker + * Author: Stefan Petre www.eyecon.ro + * + * Dual licensed under the MIT and GPL licenses + * + */ +(function ($) { + var ColorPicker = function () { + var + ids = {}, + inAction, + charMin = 65, + visible, + tpl = '
    ', + defaults = { + eventName: 'click', + onShow: function () {}, + onBeforeShow: function(){}, + onHide: function () {}, + onChange: function () {}, + onSubmit: function () {}, + color: 'ff0000', + livePreview: true, + flat: false + }, + fillRGBFields = function (hsb, cal) { + var rgb = HSBToRGB(hsb); + $(cal).data('colorpicker').fields + .eq(1).val(rgb.r).end() + .eq(2).val(rgb.g).end() + .eq(3).val(rgb.b).end(); + }, + fillHSBFields = function (hsb, cal) { + $(cal).data('colorpicker').fields + .eq(4).val(hsb.h).end() + .eq(5).val(hsb.s).end() + .eq(6).val(hsb.b).end(); + }, + fillHexFields = function (hsb, cal) { + $(cal).data('colorpicker').fields + .eq(0).val(HSBToHex(hsb)).end(); + }, + setSelector = function (hsb, cal) { + $(cal).data('colorpicker').selector.css('backgroundColor', '#' + HSBToHex({h: hsb.h, s: 100, b: 100})); + $(cal).data('colorpicker').selectorIndic.css({ + left: parseInt(150 * hsb.s/100, 10), + top: parseInt(150 * (100-hsb.b)/100, 10) + }); + }, + setHue = function (hsb, cal) { + $(cal).data('colorpicker').hue.css('top', parseInt(150 - 150 * hsb.h/360, 10)); + }, + setCurrentColor = function (hsb, cal) { + $(cal).data('colorpicker').currentColor.css('backgroundColor', '#' + HSBToHex(hsb)); + }, + setNewColor = function (hsb, cal) { + $(cal).data('colorpicker').newColor.css('backgroundColor', '#' + HSBToHex(hsb)); + }, + keyDown = function (ev) { + var pressedKey = ev.charCode || ev.keyCode || -1; + if ((pressedKey > charMin && pressedKey <= 90) || pressedKey == 32) { + return false; + } + var cal = $(this).parent().parent(); + if (cal.data('colorpicker').livePreview === true) { + change.apply(this); + } + }, + change = function (ev) { + var cal = $(this).parent().parent(), col; + if (this.parentNode.className.indexOf('_hex') > 0) { + cal.data('colorpicker').color = col = HexToHSB(fixHex(this.value)); + } else if (this.parentNode.className.indexOf('_hsb') > 0) { + cal.data('colorpicker').color = col = fixHSB({ + h: parseInt(cal.data('colorpicker').fields.eq(4).val(), 10), + s: parseInt(cal.data('colorpicker').fields.eq(5).val(), 10), + b: parseInt(cal.data('colorpicker').fields.eq(6).val(), 10) + }); + } else { + cal.data('colorpicker').color = col = RGBToHSB(fixRGB({ + r: parseInt(cal.data('colorpicker').fields.eq(1).val(), 10), + g: parseInt(cal.data('colorpicker').fields.eq(2).val(), 10), + b: parseInt(cal.data('colorpicker').fields.eq(3).val(), 10) + })); + } + if (ev) { + fillRGBFields(col, cal.get(0)); + fillHexFields(col, cal.get(0)); + fillHSBFields(col, cal.get(0)); + } + setSelector(col, cal.get(0)); + setHue(col, cal.get(0)); + setNewColor(col, cal.get(0)); + cal.data('colorpicker').onChange.apply(cal, [col, HSBToHex(col), HSBToRGB(col)]); + }, + blur = function (ev) { + var cal = $(this).parent().parent(); + cal.data('colorpicker').fields.parent().removeClass('colorpicker_focus'); + }, + focus = function () { + charMin = this.parentNode.className.indexOf('_hex') > 0 ? 70 : 65; + $(this).parent().parent().data('colorpicker').fields.parent().removeClass('colorpicker_focus'); + $(this).parent().addClass('colorpicker_focus'); + }, + downIncrement = function (ev) { + var field = $(this).parent().find('input').focus(); + var current = { + el: $(this).parent().addClass('colorpicker_slider'), + max: this.parentNode.className.indexOf('_hsb_h') > 0 ? 360 : (this.parentNode.className.indexOf('_hsb') > 0 ? 100 : 255), + y: ev.pageY, + field: field, + val: parseInt(field.val(), 10), + preview: $(this).parent().parent().data('colorpicker').livePreview + }; + $(document).bind('mouseup', current, upIncrement); + $(document).bind('mousemove', current, moveIncrement); + }, + moveIncrement = function (ev) { + ev.data.field.val(Math.max(0, Math.min(ev.data.max, parseInt(ev.data.val + ev.pageY - ev.data.y, 10)))); + if (ev.data.preview) { + change.apply(ev.data.field.get(0), [true]); + } + return false; + }, + upIncrement = function (ev) { + change.apply(ev.data.field.get(0), [true]); + ev.data.el.removeClass('colorpicker_slider').find('input').focus(); + $(document).unbind('mouseup', upIncrement); + $(document).unbind('mousemove', moveIncrement); + return false; + }, + downHue = function (ev) { + var current = { + cal: $(this).parent(), + y: $(this).offset().top + }; + current.preview = current.cal.data('colorpicker').livePreview; + $(document).bind('mouseup', current, upHue); + $(document).bind('mousemove', current, moveHue); + }, + moveHue = function (ev) { + change.apply( + ev.data.cal.data('colorpicker') + .fields + .eq(4) + .val(parseInt(360*(150 - Math.max(0,Math.min(150,(ev.pageY - ev.data.y))))/150, 10)) + .get(0), + [ev.data.preview] + ); + return false; + }, + upHue = function (ev) { + fillRGBFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0)); + fillHexFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0)); + $(document).unbind('mouseup', upHue); + $(document).unbind('mousemove', moveHue); + return false; + }, + downSelector = function (ev) { + var current = { + cal: $(this).parent(), + pos: $(this).offset() + }; + current.preview = current.cal.data('colorpicker').livePreview; + $(document).bind('mouseup', current, upSelector); + $(document).bind('mousemove', current, moveSelector); + }, + moveSelector = function (ev) { + change.apply( + ev.data.cal.data('colorpicker') + .fields + .eq(6) + .val(parseInt(100*(150 - Math.max(0,Math.min(150,(ev.pageY - ev.data.pos.top))))/150, 10)) + .end() + .eq(5) + .val(parseInt(100*(Math.max(0,Math.min(150,(ev.pageX - ev.data.pos.left))))/150, 10)) + .get(0), + [ev.data.preview] + ); + return false; + }, + upSelector = function (ev) { + fillRGBFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0)); + fillHexFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0)); + $(document).unbind('mouseup', upSelector); + $(document).unbind('mousemove', moveSelector); + return false; + }, + enterSubmit = function (ev) { + $(this).addClass('colorpicker_focus'); + }, + leaveSubmit = function (ev) { + $(this).removeClass('colorpicker_focus'); + }, + clickSubmit = function (ev) { + var cal = $(this).parent(); + var col = cal.data('colorpicker').color; + cal.data('colorpicker').origColor = col; + setCurrentColor(col, cal.get(0)); + cal.data('colorpicker').onSubmit(col, HSBToHex(col), HSBToRGB(col), cal.data('colorpicker').el); + }, + show = function (ev) { + var cal = $('#' + $(this).data('colorpickerId')); + cal.data('colorpicker').onBeforeShow.apply(this, [cal.get(0)]); + var pos = $(this).offset(); + var viewPort = getViewport(); + var top = pos.top + this.offsetHeight; + var left = pos.left; + if (top + 176 > viewPort.t + viewPort.h) { + top -= this.offsetHeight + 176; + } + if (left + 356 > viewPort.l + viewPort.w) { + left -= 356; + } + cal.css({left: left + 'px', top: top + 'px'}); + if (cal.data('colorpicker').onShow.apply(this, [cal.get(0)]) != false) { + cal.show(); + } + $(document).bind('mousedown', {cal: cal}, hide); + return false; + }, + hide = function (ev) { + if (!isChildOf(ev.data.cal.get(0), ev.target, ev.data.cal.get(0))) { + if (ev.data.cal.data('colorpicker').onHide.apply(this, [ev.data.cal.get(0)]) != false) { + ev.data.cal.hide(); + } + $(document).unbind('mousedown', hide); + } + }, + isChildOf = function(parentEl, el, container) { + if (parentEl == el) { + return true; + } + if (parentEl.contains) { + return parentEl.contains(el); + } + if ( parentEl.compareDocumentPosition ) { + return !!(parentEl.compareDocumentPosition(el) & 16); + } + var prEl = el.parentNode; + while(prEl && prEl != container) { + if (prEl == parentEl) + return true; + prEl = prEl.parentNode; + } + return false; + }, + getViewport = function () { + var m = document.compatMode == 'CSS1Compat'; + return { + l : window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft), + t : window.pageYOffset || (m ? document.documentElement.scrollTop : document.body.scrollTop), + w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth), + h : window.innerHeight || (m ? document.documentElement.clientHeight : document.body.clientHeight) + }; + }, + fixHSB = function (hsb) { + return { + h: Math.min(360, Math.max(0, hsb.h)), + s: Math.min(100, Math.max(0, hsb.s)), + b: Math.min(100, Math.max(0, hsb.b)) + }; + }, + fixRGB = function (rgb) { + return { + r: Math.min(255, Math.max(0, rgb.r)), + g: Math.min(255, Math.max(0, rgb.g)), + b: Math.min(255, Math.max(0, rgb.b)) + }; + }, + fixHex = function (hex) { + var len = 6 - hex.length; + if (len > 0) { + var o = []; + for (var i=0; i -1) ? hex.substring(1) : hex), 16); + return {r: hex >> 16, g: (hex & 0x00FF00) >> 8, b: (hex & 0x0000FF)}; + }, + HexToHSB = function (hex) { + return RGBToHSB(HexToRGB(hex)); + }, + RGBToHSB = function (rgb) { + var hsb = { + h: 0, + s: 0, + b: 0 + }; + var min = Math.min(rgb.r, rgb.g, rgb.b); + var max = Math.max(rgb.r, rgb.g, rgb.b); + var delta = max - min; + hsb.b = max; + if (max != 0) { + + } + hsb.s = max != 0 ? 255 * delta / max : 0; + if (hsb.s != 0) { + if (rgb.r == max) { + hsb.h = (rgb.g - rgb.b) / delta; + } else if (rgb.g == max) { + hsb.h = 2 + (rgb.b - rgb.r) / delta; + } else { + hsb.h = 4 + (rgb.r - rgb.g) / delta; + } + } else { + hsb.h = -1; + } + hsb.h *= 60; + if (hsb.h < 0) { + hsb.h += 360; + } + hsb.s *= 100/255; + hsb.b *= 100/255; + return hsb; + }, + HSBToRGB = function (hsb) { + var rgb = {}; + var h = Math.round(hsb.h); + var s = Math.round(hsb.s*255/100); + var v = Math.round(hsb.b*255/100); + if(s == 0) { + rgb.r = rgb.g = rgb.b = v; + } else { + var t1 = v; + var t2 = (255-s)*v/255; + var t3 = (t1-t2)*(h%60)/60; + if(h==360) h = 0; + if(h<60) {rgb.r=t1; rgb.b=t2; rgb.g=t2+t3} + else if(h<120) {rgb.g=t1; rgb.b=t2; rgb.r=t1-t3} + else if(h<180) {rgb.g=t1; rgb.r=t2; rgb.b=t2+t3} + else if(h<240) {rgb.b=t1; rgb.r=t2; rgb.g=t1-t3} + else if(h<300) {rgb.b=t1; rgb.g=t2; rgb.r=t2+t3} + else if(h<360) {rgb.r=t1; rgb.g=t2; rgb.b=t1-t3} + else {rgb.r=0; rgb.g=0; rgb.b=0} + } + return {r:Math.round(rgb.r), g:Math.round(rgb.g), b:Math.round(rgb.b)}; + }, + RGBToHex = function (rgb) { + var hex = [ + rgb.r.toString(16), + rgb.g.toString(16), + rgb.b.toString(16) + ]; + $.each(hex, function (nr, val) { + if (val.length == 1) { + hex[nr] = '0' + val; + } + }); + return hex.join(''); + }, + HSBToHex = function (hsb) { + return RGBToHex(HSBToRGB(hsb)); + }, + restoreOriginal = function () { + var cal = $(this).parent(); + var col = cal.data('colorpicker').origColor; + cal.data('colorpicker').color = col; + fillRGBFields(col, cal.get(0)); + fillHexFields(col, cal.get(0)); + fillHSBFields(col, cal.get(0)); + setSelector(col, cal.get(0)); + setHue(col, cal.get(0)); + setNewColor(col, cal.get(0)); + }; + return { + init: function (opt) { + opt = $.extend({}, defaults, opt||{}); + if (typeof opt.color == 'string') { + opt.color = HexToHSB(opt.color); + } else if (opt.color.r != undefined && opt.color.g != undefined && opt.color.b != undefined) { + opt.color = RGBToHSB(opt.color); + } else if (opt.color.h != undefined && opt.color.s != undefined && opt.color.b != undefined) { + opt.color = fixHSB(opt.color); + } else { + return this; + } + return this.each(function () { + if (!$(this).data('colorpickerId')) { + var options = $.extend({}, opt); + options.origColor = opt.color; + var id = 'collorpicker_' + parseInt(Math.random() * 1000); + $(this).data('colorpickerId', id); + var cal = $(tpl).attr('id', id); + if (options.flat) { + cal.appendTo(this).show(); + } else { + cal.appendTo(document.body); + } + options.fields = cal + .find('input') + .bind('keyup', keyDown) + .bind('change', change) + .bind('blur', blur) + .bind('focus', focus); + cal + .find('span').bind('mousedown', downIncrement).end() + .find('>div.colorpicker_current_color').bind('click', restoreOriginal); + options.selector = cal.find('div.colorpicker_color').bind('mousedown', downSelector); + options.selectorIndic = options.selector.find('div div'); + options.el = this; + options.hue = cal.find('div.colorpicker_hue div'); + cal.find('div.colorpicker_hue').bind('mousedown', downHue); + options.newColor = cal.find('div.colorpicker_new_color'); + options.currentColor = cal.find('div.colorpicker_current_color'); + cal.data('colorpicker', options); + cal.find('div.colorpicker_submit') + .bind('mouseenter', enterSubmit) + .bind('mouseleave', leaveSubmit) + .bind('click', clickSubmit); + fillRGBFields(options.color, cal.get(0)); + fillHSBFields(options.color, cal.get(0)); + fillHexFields(options.color, cal.get(0)); + setHue(options.color, cal.get(0)); + setSelector(options.color, cal.get(0)); + setCurrentColor(options.color, cal.get(0)); + setNewColor(options.color, cal.get(0)); + if (options.flat) { + cal.css({ + position: 'relative', + display: 'block' + }); + } else { + $(this).bind(options.eventName, show); + } + } + }); + }, + showPicker: function() { + return this.each( function () { + if ($(this).data('colorpickerId')) { + show.apply(this); + } + }); + }, + hidePicker: function() { + return this.each( function () { + if ($(this).data('colorpickerId')) { + $('#' + $(this).data('colorpickerId')).hide(); + } + }); + }, + setColor: function(col) { + if (typeof col == 'string') { + col = HexToHSB(col); + } else if (col.r != undefined && col.g != undefined && col.b != undefined) { + col = RGBToHSB(col); + } else if (col.h != undefined && col.s != undefined && col.b != undefined) { + col = fixHSB(col); + } else { + return this; + } + return this.each(function(){ + if ($(this).data('colorpickerId')) { + var cal = $('#' + $(this).data('colorpickerId')); + cal.data('colorpicker').color = col; + cal.data('colorpicker').origColor = col; + fillRGBFields(col, cal.get(0)); + fillHSBFields(col, cal.get(0)); + fillHexFields(col, cal.get(0)); + setHue(col, cal.get(0)); + setSelector(col, cal.get(0)); + setCurrentColor(col, cal.get(0)); + setNewColor(col, cal.get(0)); + } + }); + } + }; + }(); + $.fn.extend({ + ColorPicker: ColorPicker.init, + ColorPickerHide: ColorPicker.hidePicker, + ColorPickerShow: ColorPicker.showPicker, + ColorPickerSetColor: ColorPicker.setColor + }); +})(jQuery); \ No newline at end of file diff --git a/modules/appagebuilder/js/colorpicker/js/eye.js b/modules/appagebuilder/js/colorpicker/js/eye.js new file mode 100644 index 00000000..c0af68d0 --- /dev/null +++ b/modules/appagebuilder/js/colorpicker/js/eye.js @@ -0,0 +1,33 @@ +/** + * @copyright Commercial License By LeoTheme.Com + * @email leotheme.com + * @visit http://www.leotheme.com + */ +(function($){ + var EYE = window.EYE = function() { + var _registered = { + init: [] + }; + return { + init: function() { + $.each(_registered.init, function(nr, fn){ + fn.call(); + }); + }, + extend: function(prop) { + for (var i in prop) { + if (prop[i] != undefined) { + this[i] = prop[i]; + } + } + }, + register: function(fn, type) { + if (!_registered[type]) { + _registered[type] = []; + } + _registered[type].push(fn); + } + }; + }(); + $(EYE.init); +})(jQuery); diff --git a/modules/appagebuilder/js/colorpicker/js/index.php b/modules/appagebuilder/js/colorpicker/js/index.php new file mode 100644 index 00000000..dfbb709d --- /dev/null +++ b/modules/appagebuilder/js/colorpicker/js/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2014 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; \ No newline at end of file diff --git a/modules/appagebuilder/js/colorpicker/js/layout.js b/modules/appagebuilder/js/colorpicker/js/layout.js new file mode 100644 index 00000000..723bb065 --- /dev/null +++ b/modules/appagebuilder/js/colorpicker/js/layout.js @@ -0,0 +1,72 @@ +/** + * @copyright Commercial License By LeoTheme.Com + * @email leotheme.com + * @visit http://www.leotheme.com + */ +(function($){ + var initLayout = function() { + var hash = window.location.hash.replace('#', ''); + var currentTab = $('ul.navigationTabs a') + .bind('click', showTab) + .filter('a[rel=' + hash + ']'); + if (currentTab.size() == 0) { + currentTab = $('ul.navigationTabs a:first'); + } + showTab.apply(currentTab.get(0)); + $('#colorpickerHolder').ColorPicker({flat: true}); + $('#colorpickerHolder2').ColorPicker({ + flat: true, + color: '#00ff00', + onSubmit: function(hsb, hex, rgb) { + $('#colorSelector2 div').css('backgroundColor', '#' + hex); + } + }); + $('#colorpickerHolder2>div').css('position', 'absolute'); + var widt = false; + $('#colorSelector2').bind('click', function() { + $('#colorpickerHolder2').stop().animate({height: widt ? 0 : 173}, 500); + widt = !widt; + }); + $('#colorpickerField1, #colorpickerField2, #colorpickerField3').ColorPicker({ + onSubmit: function(hsb, hex, rgb, el) { + $(el).val(hex); + $(el).ColorPickerHide(); + }, + onBeforeShow: function () { + $(this).ColorPickerSetColor(this.value); + } + }) + .bind('keyup', function(){ + $(this).ColorPickerSetColor(this.value); + }); + $('#colorSelector').ColorPicker({ + color: '#0000ff', + onShow: function (colpkr) { + $(colpkr).fadeIn(500); + return false; + }, + onHide: function (colpkr) { + $(colpkr).fadeOut(500); + return false; + }, + onChange: function (hsb, hex, rgb) { + $('#colorSelector div').css('backgroundColor', '#' + hex); + } + }); + }; + + var showTab = function(e) { + var tabIndex = $('ul.navigationTabs a') + .removeClass('active') + .index(this); + $(this) + .addClass('active') + .blur(); + $('div.tab') + .hide() + .eq(tabIndex) + .show(); + }; + + EYE.register(initLayout, 'init'); +})(jQuery) \ No newline at end of file diff --git a/modules/appagebuilder/js/colorpicker/js/leo.jquery.colorpicker.js b/modules/appagebuilder/js/colorpicker/js/leo.jquery.colorpicker.js new file mode 100644 index 00000000..85342b9f --- /dev/null +++ b/modules/appagebuilder/js/colorpicker/js/leo.jquery.colorpicker.js @@ -0,0 +1,569 @@ +/* + * @Website: apollotheme.com - prestashop template provider + * @author Apollotheme + * @copyright 2007-2018 Apollotheme + * @description: + */ +/* + mColorPicker + Version: 1.0 r34 + + Copyright (c) 2010 Meta100 LLC. + http://www.meta100.com/ + + Licensed under the MIT license + http://www.opensource.org/licenses/mit-license.php +*/ + +// After this script loads set: +// $.fn.mColorPicker.init.replace = '.myclass' +// to have this script apply to input.myclass, +// instead of the default input[type=color] +// To turn of automatic operation and run manually set: +// $.fn.mColorPicker.init.replace = false +// To use manually call like any other jQuery plugin +// $('input.foo').mColorPicker({options}) +// options: +// imageFolder - Change to move image location. +// swatches - Initial colors in the swatch, must an array of 10 colors. +// init: +// $.fn.mColorPicker.init.enhancedSwatches - Turn of saving and loading of swatch to cookies. +// $.fn.mColorPicker.init.allowTransparency - Turn off transperancy as a color option. +// $.fn.mColorPicker.init.showLogo - Turn on/off the meta100 logo (You don't really want to turn it off, do you?). + +(function($){ + + var $o; + + $.fn.mColorPicker = function(options) { + + $o = $.extend($.fn.mColorPicker.defaults, options); + + if ($o.swatches.length < 10) $o.swatches = $.fn.mColorPicker.defaults.swatches + if ($("div#mColorPicker").length < 1) $.fn.mColorPicker.drawPicker(); + + if ($('#css_disabled_color_picker').length < 1) $('head').prepend(''); + + $(document).on('keyup', '.mColorPicker', function () { + + try { + + $(this).css({ + 'background-color': $(this).val() + }).css({ + 'color': $.fn.mColorPicker.textColor($(this).css('background-color')) + }).trigger('change'); + } catch (r) {} + }); + + $(document).on('click', '.mColorPickerTrigger', function () { + + $.fn.mColorPicker.colorShow($(this).attr('id').replace('icp_', '')); + }); + + this.each(function () { + + $.fn.mColorPicker.drawPickerTriggers($(this)); + }); + + return this; + }; + + $.fn.mColorPicker.currentColor = false; + $.fn.mColorPicker.currentValue = false; + $.fn.mColorPicker.color = false; + + $.fn.mColorPicker.init = { + replace: '[type=color]', + index: 0, + enhancedSwatches: true, + allowTransparency: false, + checkRedraw: 'DOMUpdated', // Change to 'ajaxSuccess' for ajax only or false if not needed + liveEvents: false, + showLogo: false + }; + + $.fn.mColorPicker.defaults = { + imageFolder: baseDir + 'img/admin/', + swatches: [ + "#ffffff", + "#ffff00", + "#00ff00", + "#00ffff", + "#0000ff", + "#ff00ff", + "#ff0000", + "#4c2b11", + "#3b3b3b", + "#000000" + ] + }; + + $.fn.mColorPicker.liveEvents = function() { + + $.fn.mColorPicker.init.liveEvents = true; + + if ($.fn.mColorPicker.init.checkRedraw && $.fn.mColorPicker.init.replace) { + + $(document).bind($.fn.mColorPicker.init.checkRedraw + '.mColorPicker', function () { + + $('input[data-mcolorpicker!="true"]').filter(function() { + + return ($.fn.mColorPicker.init.replace == '[type=color]')? this.getAttribute("type") == 'color': $(this).is($.fn.mColorPicker.init.replace); + }).mColorPicker(); + }); + } + }; + + $.fn.mColorPicker.drawPickerTriggers = function ($t) { + + if ($t[0].nodeName.toLowerCase() != 'input') return false; + + var id = $t.attr('id') || 'color_' + $.fn.mColorPicker.init.index++, + hidden = false; + + $t.attr('id', id); + + if ($t.attr('text') == 'hidden' || $t.attr('data-text') == 'hidden') hidden = true; + + var color = $t.val(), + width = ($t.width() > 0)? $t.width(): parseInt($t.css('width'), 10), + height = ($t.height())? $t.height(): parseInt($t.css('height'), 10), + flt = $t.css('float'), + image = (color == 'transparent')? "url('" + $o.imageFolder + "/grid.gif')": '', + colorPicker = ''; + + $('body').append(''); + $('span#color_work_area').append($t.clone(true)); + colorPicker = $('span#color_work_area').html().replace(/type="color"/gi, '').replace(/input /gi, (hidden)? 'input type="hidden"': 'input type="text"'); + $('span#color_work_area').html('').remove(); + $t.after( + (hidden)? ' ': '' + ).after(colorPicker).remove(); + + if (hidden) { + + $('#icp_' + id).css({ + 'background-color': color, + 'background-image': image, + 'display': 'inline-block' + }).attr( + 'class', $('#' + id).attr('class') + ).addClass( + 'mColorPickerTrigger' + ); + } else { + + $('#' + id).css({ + 'background-color': color, + 'background-image': image + }).css({ + 'color': $.fn.mColorPicker.textColor($('#' + id).css('background-color')) + }).after( + '' + ).addClass('mColorPickerInput'); + } + + $('#icp_' + id).attr('data-mcolorpicker', 'true'); + + $('#' + id).addClass('mColorPicker'); + + return $('#' + id); + }; + + $.fn.mColorPicker.drawPicker = function () { + + $(document.createElement("div")).attr( + "id","mColorPicker" + ).css( + 'display','none' + ).html( + '
    ' + ).appendTo("body"); + + $(document.createElement("div")).attr("id","mColorPickerBg").css({ + 'display': 'none' + }).appendTo("body"); + + for (n = 9; n > -1; n--) { + + $(document.createElement("div")).attr({ + 'id': 'cell' + n, + 'class': "mPastColor" + ((n > 0)? ' mNoLeftBorder': '') + }).html( + ' ' + ).prependTo("#mColorPickerSwatches"); + } + + $('#mColorPicker').css({ + 'border':'1px solid #ccc', + 'color':'#fff', + 'z-index':999998, + 'width':'194px', + 'height':'184px', + 'font-size':'12px', + 'font-family':'times' + }); + + $('.mPastColor').css({ + 'height':'18px', + 'width':'18px', + 'border':'1px solid #000', + 'float':'left' + }); + + $('#colorPreview').css({ + 'height':'50px' + }); + + $('.mNoLeftBorder').css({ + 'border-left':0 + }); + + $('.mClear').css({ + 'clear':'both' + }); + + $('#mColorPickerWrapper').css({ + 'position':'relative', + 'border':'solid 1px gray', + 'z-index':999999 + }); + + $('#mColorPickerImg').css({ + 'height':'128px', + 'width':'192px', + 'border':0, + 'cursor':'crosshair', + 'background-image':"url('" + $o.imageFolder + "colorpicker.png')" + }); + + $('#mColorPickerImgGray').css({ + 'height':'8px', + 'width':'192px', + 'border':0, + 'cursor':'crosshair', + 'background-image':"url('" + $o.imageFolder + "graybar.jpg')" + }); + + $('#mColorPickerInput').css({ + 'border':'solid 1px gray', + 'font-size':'10pt', + 'margin':'3px', + 'width':'80px' + }); + + $('#mColorPickerImgGrid').css({ + 'border':0, + 'height':'20px', + 'width':'20px', + 'vertical-align':'text-bottom' + }); + + $('#mColorPickerSwatches').css({ + 'border-right':'1px solid #000' + }); + + $('#mColorPickerFooter').css({ + 'background-image':"url('" + $o.imageFolder + "grid.gif')", + 'position': 'relative', + 'height':'26px' + }); + + if ($.fn.mColorPicker.init.allowTransparency) $('#mColorPickerFooter').prepend('transparent'); + if ($.fn.mColorPicker.init.showLogo) $('#mColorPickerFooter').prepend('Meta100 - Designing Fun'); + + $("#mColorPickerBg").click($.fn.mColorPicker.closePicker); + + var swatch = $.fn.mColorPicker.getCookie('swatches'), + i = 0; + + if (typeof swatch == 'string') swatch = swatch.split('||'); + if (swatch == null || $.fn.mColorPicker.init.enhancedSwatches || swatch.length < 10) swatch = $o.swatches; + + $(".mPastColor").each(function() { + + $(this).css('background-color', swatch[i++].toLowerCase()); + }); + }; + + $.fn.mColorPicker.closePicker = function () { + + $(".mColor, .mPastColor, #mColorPickerInput, #mColorPickerWrapper").unbind(); + $("#mColorPickerBg").hide(); + $("#mColorPicker").fadeOut() + }; + + $.fn.mColorPicker.colorShow = function (id) { + + var $e = $("#icp_" + id); + pos = $e.offset(), + $i = $("#" + id); + hex = $i.attr('data-hex') || $i.attr('hex'), + pickerTop = pos.top + $e.outerHeight(), + pickerLeft = pos.left, + $d = $(document), + $m = $("#mColorPicker"); + + if ($i.attr('disabled')) return false; + + // KEEP COLOR PICKER IN VIEWPORT + if (pickerTop + $m.height() > $d.height()) pickerTop = pos.top - $m.height(); + if (pickerLeft + $m.width() > $d.width()) pickerLeft = pos.left - $m.width() + $e.outerWidth(); + + $m.css({ + 'top':(pickerTop) + "px", + 'left':(pickerLeft) + "px", + 'position':'absolute' + }).fadeIn("fast"); + + $("#mColorPickerBg").css({ + 'z-index':999990, + 'background':'black', + 'opacity': .01, + 'position':'absolute', + 'top':0, + 'left':0, + 'width': parseInt($d.width(), 10) + 'px', + 'height': parseInt($d.height(), 10) + 'px' + }).show(); + + var def = $i.val(); + + $('#colorPreview span').text(def); + $('#colorPreview').css('background', def); + $('#color').val(def); + + if ($('#' + id).attr('data-text')) $.fn.mColorPicker.currentColor = $e.css('background-color'); + else $.fn.mColorPicker.currentColor = $i.css('background-color'); + + if (hex == 'true') $.fn.mColorPicker.currentColor = $.fn.mColorPicker.RGBtoHex($.fn.mColorPicker.currentColor); + + $("#mColorPickerInput").val($.fn.mColorPicker.currentColor); + + $('.mColor, .mPastColor').bind('mousemove', function(e) { + + var offset = $(this).offset(); + + $.fn.mColorPicker.color = $(this).css("background-color"); + + if ($(this).hasClass('mPastColor') && hex == 'true') $.fn.mColorPicker.color = $.fn.mColorPicker.RGBtoHex($.fn.mColorPicker.color); + else if ($(this).hasClass('mPastColor') && hex != 'true') $.fn.mColorPicker.color = $.fn.mColorPicker.hexToRGB($.fn.mColorPicker.color); + else if ($(this).attr('id') == 'mColorPickerTransparent') $.fn.mColorPicker.color = 'transparent'; + else if (!$(this).hasClass('mPastColor')) $.fn.mColorPicker.color = $.fn.mColorPicker.whichColor(e.pageX - offset.left, e.pageY - offset.top + (($(this).attr('id') == 'mColorPickerImgGray')? 128: 0), hex); + + $.fn.mColorPicker.setInputColor(id, $.fn.mColorPicker.color); + }).click(function() { + + $.fn.mColorPicker.colorPicked(id); + }); + + $('#mColorPickerInput').bind('keyup', function (e) { + + try { + + $.fn.mColorPicker.color = $('#mColorPickerInput').val(); + $.fn.mColorPicker.setInputColor(id, $.fn.mColorPicker.color); + + if (e.which == 13) $.fn.mColorPicker.colorPicked(id); + } catch (r) {} + + }).bind('blur', function () { + + $.fn.mColorPicker.setInputColor(id, $.fn.mColorPicker.currentColor); + }); + + $('#mColorPickerWrapper').bind('mouseleave', function () { + + $.fn.mColorPicker.setInputColor(id, $.fn.mColorPicker.currentColor); + }); + }; + + $.fn.mColorPicker.setInputColor = function (id, color) { + + var image = (color == 'transparent')? "url('" + $o.imageFolder + "grid.gif')": '', + textColor = $.fn.mColorPicker.textColor(color); + + if ($('#' + id).attr('data-text') || $('#' + id).attr('text')) $("#icp_" + id).css({'background-color': color, 'background-image': image}); + $("#" + id).val(color).css({'background-color': color, 'background-image': image, 'color' : textColor}).trigger('change'); + $("#mColorPickerInput").val(color); + }; + + $.fn.mColorPicker.textColor = function (val) { + + if (typeof val == 'undefined' || val == 'transparent') return "black"; + val = $.fn.mColorPicker.RGBtoHex(val); + return (parseInt(val.substr(1, 2), 16) + parseInt(val.substr(3, 2), 16) + parseInt(val.substr(5, 2), 16) < 400)? 'white': 'black'; + }; + + $.fn.mColorPicker.setCookie = function (name, value, days) { + + var cookie_string = name + "=" + escape(value), + expires = new Date(); + expires.setDate(expires.getDate() + days); + cookie_string += "; expires=" + expires.toGMTString(); + + document.cookie = cookie_string; + }; + + $.fn.mColorPicker.getCookie = function (name) { + + var results = document.cookie.match ( '(^|;) ?' + name + '=([^;]*)(;|$)' ); + + if (results) return (unescape(results[2])); + else return null; + }; + + $.fn.mColorPicker.colorPicked = function (id) { + + $.fn.mColorPicker.closePicker(); + + if ($.fn.mColorPicker.init.enhancedSwatches) $.fn.mColorPicker.addToSwatch(); + + $("#" + id).trigger('colorpicked'); + }; + + $.fn.mColorPicker.addToSwatch = function (color) { + + var swatch = [] + i = 0; + + if (typeof color == 'string') $.fn.mColorPicker.color = color.toLowerCase(); + + $.fn.mColorPicker.currentValue = $.fn.mColorPicker.currentColor = $.fn.mColorPicker.color; + + if ($.fn.mColorPicker.color != 'transparent') swatch[0] = $.fn.mColorPicker.color.toLowerCase(); + + $('.mPastColor').each(function() { + + $.fn.mColorPicker.color = $(this).css('background-color').toLowerCase(); + + if ($.fn.mColorPicker.color != swatch[0] && $.fn.mColorPicker.RGBtoHex($.fn.mColorPicker.color) != swatch[0] && $.fn.mColorPicker.hexToRGB($.fn.mColorPicker.color) != swatch[0] && swatch.length < 10) swatch[swatch.length] = $.fn.mColorPicker.color; + + $(this).css('background-color', swatch[i++]) + }); + + if ($.fn.mColorPicker.init.enhancedSwatches) $.fn.mColorPicker.setCookie('swatches', swatch.join('||'), 365); + }; + + $.fn.mColorPicker.whichColor = function (x, y, hex) { + + var colorR = colorG = colorB = 255; + + if (x < 32) { + + colorG = x * 8; + colorB = 0; + } else if (x < 64) { + + colorR = 256 - (x - 32 ) * 8; + colorB = 0; + } else if (x < 96) { + + colorR = 0; + colorB = (x - 64) * 8; + } else if (x < 128) { + + colorR = 0; + colorG = 256 - (x - 96) * 8; + } else if (x < 160) { + + colorR = (x - 128) * 8; + colorG = 0; + } else { + + colorG = 0; + colorB = 256 - (x - 160) * 8; + } + + if (y < 64) { + + colorR += (256 - colorR) * (64 - y) / 64; + colorG += (256 - colorG) * (64 - y) / 64; + colorB += (256 - colorB) * (64 - y) / 64; + } else if (y <= 128) { + + colorR -= colorR * (y - 64) / 64; + colorG -= colorG * (y - 64) / 64; + colorB -= colorB * (y - 64) / 64; + } else if (y > 128) { + + colorR = colorG = colorB = 256 - ( x / 192 * 256 ); + } + + colorR = Math.round(Math.min(colorR, 255)); + colorG = Math.round(Math.min(colorG, 255)); + colorB = Math.round(Math.min(colorB, 255)); + + if (hex == 'true') { + + colorR = colorR.toString(16); + colorG = colorG.toString(16); + colorB = colorB.toString(16); + + if (colorR.length < 2) colorR = 0 + colorR; + if (colorG.length < 2) colorG = 0 + colorG; + if (colorB.length < 2) colorB = 0 + colorB; + + return "#" + colorR + colorG + colorB; + } + + return "rgb(" + colorR + ', ' + colorG + ', ' + colorB + ')'; + }; + + $.fn.mColorPicker.RGBtoHex = function (color) { + + color = color.toLowerCase(); + + if (typeof color == 'undefined') return ''; + if (color.indexOf('#') > -1 && color.length > 6) return color; + if (color.indexOf('rgb') < 0) return color; + + if (color.indexOf('#') > -1) { + + return '#' + color.substr(1, 1) + color.substr(1, 1) + color.substr(2, 1) + color.substr(2, 1) + color.substr(3, 1) + color.substr(3, 1); + } + + var hexArray = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"], + decToHex = "#", + code1 = 0; + + color = color.replace(/[^0-9,]/g, '').split(","); + + for (var n = 0; n < color.length; n++) { + + code1 = Math.floor(color[n] / 16); + decToHex += hexArray[code1] + hexArray[color[n] - code1 * 16]; + } + + return decToHex; + }; + + $.fn.mColorPicker.hexToRGB = function (color) { + + color = color.toLowerCase(); + + if (typeof color == 'undefined') return ''; + if (color.indexOf('rgb') > -1) return color; + if (color.indexOf('#') < 0) return color; + + var c = color.replace('#', ''); + + if (c.length < 6) c = c.substr(0, 1) + c.substr(0, 1) + c.substr(1, 1) + c.substr(1, 1) + c.substr(2, 1) + c.substr(2, 1); + + return 'rgb(' + parseInt(c.substr(0, 2), 16) + ', ' + parseInt(c.substr(2, 2), 16) + ', ' + parseInt(c.substr(4, 2), 16) + ')'; + }; + + $(document).ready(function () { + + if ($.fn.mColorPicker.init.replace) { + + $('input[data-mcolorpicker!="true"]').filter(function() { + + return ($.fn.mColorPicker.init.replace == '[type=color]')? this.getAttribute("type") == 'color': $(this).is($.fn.mColorPicker.init.replace); + }).mColorPicker(); + + $.fn.mColorPicker.liveEvents(); + } + }); +})(jQuery); diff --git a/modules/appagebuilder/js/colorpicker/js/utils.js b/modules/appagebuilder/js/colorpicker/js/utils.js new file mode 100644 index 00000000..6937febe --- /dev/null +++ b/modules/appagebuilder/js/colorpicker/js/utils.js @@ -0,0 +1,251 @@ +/** + * @copyright Commercial License By LeoTheme.Com + * @email leotheme.com + * @visit http://www.leotheme.com + */ +(function($) { +EYE.extend({ + getPosition : function(e, forceIt) + { + var x = 0; + var y = 0; + var es = e.style; + var restoreStyles = false; + if (forceIt && jQuery.curCSS(e,'display') == 'none') { + var oldVisibility = es.visibility; + var oldPosition = es.position; + restoreStyles = true; + es.visibility = 'hidden'; + es.display = 'block'; + es.position = 'absolute'; + } + var el = e; + if (el.getBoundingClientRect) { // IE + var box = el.getBoundingClientRect(); + x = box.left + Math.max(document.documentElement.scrollLeft, document.body.scrollLeft) - 2; + y = box.top + Math.max(document.documentElement.scrollTop, document.body.scrollTop) - 2; + } else { + x = el.offsetLeft; + y = el.offsetTop; + el = el.offsetParent; + if (e != el) { + while (el) { + x += el.offsetLeft; + y += el.offsetTop; + el = el.offsetParent; + } + } + if (jQuery.browser.safari && jQuery.curCSS(e, 'position') == 'absolute' ) { + x -= document.body.offsetLeft; + y -= document.body.offsetTop; + } + el = e.parentNode; + while (el && el.tagName.toUpperCase() != 'BODY' && el.tagName.toUpperCase() != 'HTML') + { + if (jQuery.curCSS(el, 'display') != 'inline') { + x -= el.scrollLeft; + y -= el.scrollTop; + } + el = el.parentNode; + } + } + if (restoreStyles == true) { + es.display = 'none'; + es.position = oldPosition; + es.visibility = oldVisibility; + } + return {x:x, y:y}; + }, + getSize : function(e) + { + var w = parseInt(jQuery.curCSS(e,'width'), 10); + var h = parseInt(jQuery.curCSS(e,'height'), 10); + var wb = 0; + var hb = 0; + if (jQuery.curCSS(e, 'display') != 'none') { + wb = e.offsetWidth; + hb = e.offsetHeight; + } else { + var es = e.style; + var oldVisibility = es.visibility; + var oldPosition = es.position; + es.visibility = 'hidden'; + es.display = 'block'; + es.position = 'absolute'; + wb = e.offsetWidth; + hb = e.offsetHeight; + es.display = 'none'; + es.position = oldPosition; + es.visibility = oldVisibility; + } + return {w:w, h:h, wb:wb, hb:hb}; + }, + getClient : function(e) + { + var h, w; + if (e) { + w = e.clientWidth; + h = e.clientHeight; + } else { + var de = document.documentElement; + w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth; + h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight; + } + return {w:w,h:h}; + }, + getScroll : function (e) + { + var t=0, l=0, w=0, h=0, iw=0, ih=0; + if (e && e.nodeName.toLowerCase() != 'body') { + t = e.scrollTop; + l = e.scrollLeft; + w = e.scrollWidth; + h = e.scrollHeight; + } else { + if (document.documentElement) { + t = document.documentElement.scrollTop; + l = document.documentElement.scrollLeft; + w = document.documentElement.scrollWidth; + h = document.documentElement.scrollHeight; + } else if (document.body) { + t = document.body.scrollTop; + l = document.body.scrollLeft; + w = document.body.scrollWidth; + h = document.body.scrollHeight; + } + if (typeof pageYOffset != 'undefined') { + t = pageYOffset; + l = pageXOffset; + } + iw = self.innerWidth||document.documentElement.clientWidth||document.body.clientWidth||0; + ih = self.innerHeight||document.documentElement.clientHeight||document.body.clientHeight||0; + } + return { t: t, l: l, w: w, h: h, iw: iw, ih: ih }; + }, + getMargins : function(e, toInteger) + { + var t = jQuery.curCSS(e,'marginTop') || ''; + var r = jQuery.curCSS(e,'marginRight') || ''; + var b = jQuery.curCSS(e,'marginBottom') || ''; + var l = jQuery.curCSS(e,'marginLeft') || ''; + if (toInteger) + return { + t: parseInt(t, 10)||0, + r: parseInt(r, 10)||0, + b: parseInt(b, 10)||0, + l: parseInt(l, 10) + }; + else + return {t: t, r: r, b: b, l: l}; + }, + getPadding : function(e, toInteger) + { + var t = jQuery.curCSS(e,'paddingTop') || ''; + var r = jQuery.curCSS(e,'paddingRight') || ''; + var b = jQuery.curCSS(e,'paddingBottom') || ''; + var l = jQuery.curCSS(e,'paddingLeft') || ''; + if (toInteger) + return { + t: parseInt(t, 10)||0, + r: parseInt(r, 10)||0, + b: parseInt(b, 10)||0, + l: parseInt(l, 10) + }; + else + return {t: t, r: r, b: b, l: l}; + }, + getBorder : function(e, toInteger) + { + var t = jQuery.curCSS(e,'borderTopWidth') || ''; + var r = jQuery.curCSS(e,'borderRightWidth') || ''; + var b = jQuery.curCSS(e,'borderBottomWidth') || ''; + var l = jQuery.curCSS(e,'borderLeftWidth') || ''; + if (toInteger) + return { + t: parseInt(t, 10)||0, + r: parseInt(r, 10)||0, + b: parseInt(b, 10)||0, + l: parseInt(l, 10)||0 + }; + else + return {t: t, r: r, b: b, l: l}; + }, + traverseDOM : function(nodeEl, func) + { + func(nodeEl); + nodeEl = nodeEl.firstChild; + while(nodeEl){ + EYE.traverseDOM(nodeEl, func); + nodeEl = nodeEl.nextSibling; + } + }, + getInnerWidth : function(el, scroll) { + var offsetW = el.offsetWidth; + return scroll ? Math.max(el.scrollWidth,offsetW) - offsetW + el.clientWidth:el.clientWidth; + }, + getInnerHeight : function(el, scroll) { + var offsetH = el.offsetHeight; + return scroll ? Math.max(el.scrollHeight,offsetH) - offsetH + el.clientHeight:el.clientHeight; + }, + getExtraWidth : function(el) { + if($.boxModel) + return (parseInt($.curCSS(el, 'paddingLeft'))||0) + + (parseInt($.curCSS(el, 'paddingRight'))||0) + + (parseInt($.curCSS(el, 'borderLeftWidth'))||0) + + (parseInt($.curCSS(el, 'borderRightWidth'))||0); + return 0; + }, + getExtraHeight : function(el) { + if($.boxModel) + return (parseInt($.curCSS(el, 'paddingTop'))||0) + + (parseInt($.curCSS(el, 'paddingBottom'))||0) + + (parseInt($.curCSS(el, 'borderTopWidth'))||0) + + (parseInt($.curCSS(el, 'borderBottomWidth'))||0); + return 0; + }, + isChildOf: function(parentEl, el, container) { + if (parentEl == el) { + return true; + } + if (!el || !el.nodeType || el.nodeType != 1) { + return false; + } + if (parentEl.contains && !$.browser.safari) { + return parentEl.contains(el); + } + if ( parentEl.compareDocumentPosition ) { + return !!(parentEl.compareDocumentPosition(el) & 16); + } + var prEl = el.parentNode; + while(prEl && prEl != container) { + if (prEl == parentEl) + return true; + prEl = prEl.parentNode; + } + return false; + }, + centerEl : function(el, axis) + { + var clientScroll = EYE.getScroll(); + var size = EYE.getSize(el); + if (!axis || axis == 'vertically') + $(el).css( + { + top: clientScroll.t + ((Math.min(clientScroll.h,clientScroll.ih) - size.hb)/2) + 'px' + } + ); + if (!axis || axis == 'horizontally') + $(el).css( + { + left: clientScroll.l + ((Math.min(clientScroll.w,clientScroll.iw) - size.wb)/2) + 'px' + } + ); + } +}); +if (!$.easing.easeout) { + $.easing.easeout = function(p, n, firstNum, delta, duration) { + return -delta * ((n=n/duration-1)*n*n*n - 1) + firstNum; + }; +} + +})(jQuery); \ No newline at end of file diff --git a/modules/appagebuilder/js/countdown.js b/modules/appagebuilder/js/countdown.js new file mode 100644 index 00000000..1bc7f1ef --- /dev/null +++ b/modules/appagebuilder/js/countdown.js @@ -0,0 +1,74 @@ +/** + * @copyright Commercial License By LeoTheme.Com + * @email leotheme.com + * @visit http://www.leotheme.com + */ + +(function(){ + $.fn.lofCountDown = function( options ) { + return this.each(function() { + // get instance of the lofCountDown. + new $.lofCountDown( this, options ); + }); + } + $.lofCountDown = function( obj, options ){ + + this.options = $.extend({ + autoStart : true, + LeadingZero:true, + DisplayFormat:"
    %%D%% Days
    %%H%% Hours
    %%M%% Minutes
    %%S%% Seconds
    ", + FinishMessage:"Expired", + CountActive:true, + TargetDate:null + }, options || {} ); + if( this.options.TargetDate == null || this.options.TargetDate == '' ){ + return ; + } + this.timer = null; + this.element = obj; + this.CountStepper = -1; + this.CountStepper = Math.ceil(this.CountStepper); + this.SetTimeOutPeriod = (Math.abs(this.CountStepper)-1)*1000 + 990; + var dthen = new Date(this.options.TargetDate); + var dnow = new Date(); + if( this.CountStepper > 0 ) { + ddiff = new Date(dnow-dthen); + } + else { + ddiff = new Date(dthen-dnow); + } + gsecs = Math.floor(ddiff.valueOf()/1000); + this.CountBack(gsecs, this); + + }; + $.lofCountDown.fn = $.lofCountDown.prototype; + $.lofCountDown.fn.extend = $.lofCountDown.extend = $.extend; + $.lofCountDown.fn.extend({ + calculateDate:function( secs, num1, num2 ){ + var s = ((Math.floor(secs/num1))%num2).toString(); + if ( this.options.LeadingZero && s.length < 2) { + s = "0" + s; + } + return "" + s + ""; + }, + CountBack:function( secs, self ){ + if (secs < 0) { + self.element.innerHTML = '
    '+self.options.FinishMessage+"
    "; + return; + } + clearInterval(self.timer); + DisplayStr = self.options.DisplayFormat.replace(/%%D%%/g, self.calculateDate( secs,86400,100000) ); + DisplayStr = DisplayStr.replace(/%%H%%/g, self.calculateDate(secs,3600,24)); + DisplayStr = DisplayStr.replace(/%%M%%/g, self.calculateDate(secs,60,60)); + DisplayStr = DisplayStr.replace(/%%S%%/g, self.calculateDate(secs,1,60)); + self.element.innerHTML = DisplayStr; + if (self.options.CountActive) { + self.timer = null; + self.timer = setTimeout( function(){ + self.CountBack((secs+self.CountStepper),self); + },( self.SetTimeOutPeriod ) ); + } + } + + }) +})(jQuery) \ No newline at end of file diff --git a/modules/appagebuilder/js/flashmediaelement-cdn.swf b/modules/appagebuilder/js/flashmediaelement-cdn.swf new file mode 100644 index 00000000..37f5ebe3 Binary files /dev/null and b/modules/appagebuilder/js/flashmediaelement-cdn.swf differ diff --git a/modules/appagebuilder/js/flashmediaelement.swf b/modules/appagebuilder/js/flashmediaelement.swf new file mode 100644 index 00000000..d22899a9 Binary files /dev/null and b/modules/appagebuilder/js/flashmediaelement.swf differ diff --git a/modules/appagebuilder/js/imagesloaded.pkgd.min.js b/modules/appagebuilder/js/imagesloaded.pkgd.min.js new file mode 100644 index 00000000..e443a77d --- /dev/null +++ b/modules/appagebuilder/js/imagesloaded.pkgd.min.js @@ -0,0 +1,7 @@ +/*! + * imagesLoaded PACKAGED v4.1.4 + * JavaScript is all like "You images are done yet or what?" + * MIT License + */ + +!function(e,t){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",t):"object"==typeof module&&module.exports?module.exports=t():e.EvEmitter=t()}("undefined"!=typeof window?window:this,function(){function e(){}var t=e.prototype;return t.on=function(e,t){if(e&&t){var i=this._events=this._events||{},n=i[e]=i[e]||[];return n.indexOf(t)==-1&&n.push(t),this}},t.once=function(e,t){if(e&&t){this.on(e,t);var i=this._onceEvents=this._onceEvents||{},n=i[e]=i[e]||{};return n[t]=!0,this}},t.off=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){var n=i.indexOf(t);return n!=-1&&i.splice(n,1),this}},t.emitEvent=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){i=i.slice(0),t=t||[];for(var n=this._onceEvents&&this._onceEvents[e],o=0;o +* @copyright 2007-2012 PrestaShop SA +* @version Release: $Revision: 13573 $ +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; \ No newline at end of file diff --git a/modules/appagebuilder/js/instafeed.min.js b/modules/appagebuilder/js/instafeed.min.js new file mode 100644 index 00000000..06db9f1c --- /dev/null +++ b/modules/appagebuilder/js/instafeed.min.js @@ -0,0 +1,172 @@ +/** + * @Website: apollotheme.com - prestashop template provider + * @author Apollotheme + * @copyright 2007-2018 Apollotheme + * @description: + */ + +(function() { + var e; + e = function() { + function e(e, t) { + var n, r; + this.options = {target: "instafeed", get: "popular", resolution: "thumbnail", sortBy: "none", links: !0, mock: !1, useHttp: !1}; + if (typeof e == "object") + for (n in e) + r = e[n], this.options[n] = r; + this.context = t != null ? t : this, this.unique = this._genKey() + } + return e.prototype.hasNext = function() { + return typeof this.context.nextUrl == "string" && this.context.nextUrl.length > 0 + }, e.prototype.next = function() { + return this.hasNext() ? this.run(this.context.nextUrl) : !1 + }, e.prototype.run = function(t) { + var n, r, i; + if (typeof this.options.clientId != "string" && typeof this.options.accessToken != "string") + throw new Error("Missing clientId or accessToken."); + if (typeof this.options.accessToken != "string" && typeof this.options.clientId != "string") + throw new Error("Missing clientId or accessToken."); + return this.options.before != null && typeof this.options.before == "function" && this.options.before.call(this), typeof document != "undefined" && document !== null && (i = document.createElement("script"), i.id = "instafeed-fetcher", i.src = t || this._buildUrl(), n = document.getElementsByTagName("head"), n[0].appendChild(i), r = "instafeedCache" + this.unique, window[r] = new e(this.options, this), window[r].unique = this.unique), !0 + }, e.prototype.parse = function(e) { + var t, n, r, i, s, o, u, a, f, l, c, h, p, d, v, m, g, y, b, w, E, S, x, T, N, C, k, L, A, O, M, _, D; + if (typeof e != "object") { + if (this.options.error != null && typeof this.options.error == "function") + return this.options.error.call(this, "Invalid JSON data"), !1; + throw new Error("Invalid JSON response") + } + if (e.meta.code !== 200) { + if (this.options.error != null && typeof this.options.error == "function") + return this.options.error.call(this, e.meta.error_message), !1; + throw new Error("Error from Instagram: " + e.meta.error_message) + } + if (e.data.length === 0) { + if (this.options.error != null && typeof this.options.error == "function") + return this.options.error.call(this, "No images were returned from Instagram"), !1; + throw new Error("No images were returned from Instagram") + } + this.options.success != null && typeof this.options.success == "function" && this.options.success.call(this, e), this.context.nextUrl = "", e.pagination != null && (this.context.nextUrl = e.pagination.next_url); + if (this.options.sortBy !== "none") { + this.options.sortBy === "random" ? M = ["", "random"] : M = this.options.sortBy.split("-"), O = M[0] === "least" ? !0 : !1; + switch (M[1]) { + case"random": + e.data.sort(function() { + return.5 - Math.random() + }); + break; + case"recent": + e.data = this._sortBy(e.data, "created_time", O); + break; + case"liked": + e.data = this._sortBy(e.data, "likes.count", O); + break; + case"commented": + e.data = this._sortBy(e.data, "comments.count", O); + break; + default: + throw new Error("Invalid option for sortBy: '" + this.options.sortBy + "'.") + } + } + if (typeof document != "undefined" && document !== null && this.options.mock === !1) { + m = e.data, A = parseInt(this.options.limit, 10), this.options.limit != null && m.length > A && (m = m.slice(0, A)), u = document.createDocumentFragment(), this.options.filter != null && typeof this.options.filter == "function" && (m = this._filter(m, this.options.filter)); + if (this.options.template != null && typeof this.options.template == "string") { + f = "", d = "", w = "", D = document.createElement("div"); + for (c = 0, N = m.length; c < N; c++) { + h = m[c], p = h.images[this.options.resolution]; + if (typeof p != "object") + throw o = "No image found for resolution: " + this.options.resolution + ".", new Error(o); + E = p.width, y = p.height, b = "square", E > y && (b = "landscape"), E < y && (b = "portrait"), v = p.url, l = window.location.protocol.indexOf("http") >= 0, l && !this.options.useHttp && (v = v.replace(/https?:\/\//, "//")), d = this._makeTemplate(this.options.template, {model: h, id: h.id, link: h.link, type: h.type, image: v, width: E, height: y, orientation: b, caption: this._getObjectProperty(h, "caption.text"), likes: h.likes.count, comments: h.comments.count, location: this._getObjectProperty(h, "location.name")}), f += d + } + D.innerHTML = f, i = [], r = 0, n = D.childNodes.length; + while (r < n) + i.push(D.childNodes[r]), r += 1; + for (x = 0, C = i.length; x < C; x++) + L = i[x], u.appendChild(L) + } else + for (T = 0, k = m.length; T < k; T++) { + h = m[T], g = document.createElement("img"), p = h.images[this.options.resolution]; + if (typeof p != "object") + throw o = "No image found for resolution: " + this.options.resolution + ".", new Error(o); + v = p.url, l = window.location.protocol.indexOf("http") >= 0, l && !this.options.useHttp && (v = v.replace(/https?:\/\//, "//")), g.src = v, this.options.links === !0 ? (t = document.createElement("a"), t.href = h.link, t.appendChild(g), u.appendChild(t)) : (t = document.createElement("a"), t.href = this.options.links, t.appendChild(g), u.appendChild(t)) + } + _ = this.options.target, typeof _ == "string" && (_ = document.getElementById(_)); + if (_ == null) + throw o = 'No element with id="' + this.options.target + '" on page.', new Error(o); + _.appendChild(u), a = document.getElementsByTagName("head")[0], a.removeChild(document.getElementById("instafeed-fetcher")), S = "instafeedCache" + this.unique, window[S] = void 0; + try { + delete window[S] + } catch (P) { + s = P + } + } + return this.options.after != null && typeof this.options.after == "function" && this.options.after.call(this), !0 + }, e.prototype._buildUrl = function() { + var e, t, n; + e = "https://api.instagram.com/v1"; + switch (this.options.get) { + case"popular": + t = "media/popular"; + break; + case"tagged": + if (!this.options.tagName) + throw new Error("No tag name specified. Use the 'tagName' option."); + t = "tags/" + this.options.tagName + "/media/recent"; + break; + case"location": + if (!this.options.locationId) + throw new Error("No location specified. Use the 'locationId' option."); + t = "locations/" + this.options.locationId + "/media/recent"; + break; + case"user": + if (!this.options.userId) + throw new Error("No user specified. Use the 'userId' option."); + t = "users/" + this.options.userId + "/media/recent"; + break; + default: + throw new Error("Invalid option for get: '" + this.options.get + "'.") + } + return n = e + "/" + t, this.options.accessToken != null ? n += "?access_token=" + this.options.accessToken : n += "?client_id=" + this.options.clientId, this.options.limit != null && (n += "&count=" + this.options.limit), n += "&callback=instafeedCache" + this.unique + ".parse", n + }, e.prototype._genKey = function() { + var e; + return e = function() { + return((1 + Math.random()) * 65536 | 0).toString(16).substring(1) + }, "" + e() + e() + e() + e() + }, e.prototype._makeTemplate = function(e, t) { + var n, r, i, s, o; + r = /(?:\{{2})([\w\[\]\.]+)(?:\}{2})/, n = e; + while (r.test(n)) + s = n.match(r)[1], o = (i = this._getObjectProperty(t, s)) != null ? i : "", n = n.replace(r, function() { + return"" + o + }); + return n + }, e.prototype._getObjectProperty = function(e, t) { + var n, r; + t = t.replace(/\[(\w+)\]/g, ".$1"), r = t.split("."); + while (r.length) { + n = r.shift(); + if (!(e != null && n in e)) + return null; + e = e[n] + } + return e + }, e.prototype._sortBy = function(e, t, n) { + var r; + return r = function(e, r) { + var i, s; + return i = this._getObjectProperty(e, t), s = this._getObjectProperty(r, t), n ? i > s ? 1 : -1 : i < s ? 1 : -1 + }, e.sort(r.bind(this)), e + }, e.prototype._filter = function(e, t) { + var n, r, i, s, o; + n = [], r = function(e) { + if (t(e)) + return n.push(e) + }; + for (i = 0, o = e.length; i < o; i++) + s = e[i], r(s); + return n + }, e + }(), function(e, t) { + return typeof define == "function" && define.amd ? define([], t) : typeof module == "object" && module.exports ? module.exports = t() : e.Instafeed = t() + }(this, function() { + return e + }) +}).call(this); \ No newline at end of file diff --git a/modules/appagebuilder/js/jquery-ui-1.10.3.custom.min.js b/modules/appagebuilder/js/jquery-ui-1.10.3.custom.min.js new file mode 100644 index 00000000..97f9da14 --- /dev/null +++ b/modules/appagebuilder/js/jquery-ui-1.10.3.custom.min.js @@ -0,0 +1,6 @@ +/*! jQuery UI - v1.10.3 - 2013-08-29 +* http://jqueryui.com +* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.sortable.js +* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */ + +(function(e,t){function i(t,i){var a,n,r,o=t.nodeName.toLowerCase();return"area"===o?(a=t.parentNode,n=a.name,t.href&&n&&"map"===a.nodeName.toLowerCase()?(r=e("img[usemap=#"+n+"]")[0],!!r&&s(r)):!1):(/input|select|textarea|button|object/.test(o)?!t.disabled:"a"===o?t.href||i:i)&&s(t)}function s(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}var a=0,n=/^ui-id-\d+$/;e.ui=e.ui||{},e.extend(e.ui,{version:"1.10.3",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({focus:function(t){return function(i,s){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),s&&s.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),scrollParent:function(){var t;return t=e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(i){if(i!==t)return this.css("zIndex",i);if(this.length)for(var s,a,n=e(this[0]);n.length&&n[0]!==document;){if(s=n.css("position"),("absolute"===s||"relative"===s||"fixed"===s)&&(a=parseInt(n.css("zIndex"),10),!isNaN(a)&&0!==a))return a;n=n.parent()}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++a)})},removeUniqueId:function(){return this.each(function(){n.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,s){return!!e.data(t,s[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var s=e.attr(t,"tabindex"),a=isNaN(s);return(a||s>=0)&&i(t,!a)}}),e("").outerWidth(1).jquery||e.each(["Width","Height"],function(i,s){function a(t,i,s,a){return e.each(n,function(){i-=parseFloat(e.css(t,"padding"+this))||0,s&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),a&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var n="Width"===s?["Left","Right"]:["Top","Bottom"],r=s.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+s]=function(i){return i===t?o["inner"+s].call(this):this.each(function(){e(this).css(r,a(this,i)+"px")})},e.fn["outer"+s]=function(t,i){return"number"!=typeof t?o["outer"+s].call(this,t):this.each(function(){e(this).css(r,a(this,t,!0,i)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.support.selectstart="onselectstart"in document.createElement("div"),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,i,s){var a,n=e.ui[t].prototype;for(a in s)n.plugins[a]=n.plugins[a]||[],n.plugins[a].push([i,s[a]])},call:function(e,t,i){var s,a=e.plugins[t];if(a&&e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType)for(s=0;a.length>s;s++)e.options[a[s][0]]&&a[s][1].apply(e.element,i)}},hasScroll:function(t,i){if("hidden"===e(t).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",a=!1;return t[s]>0?!0:(t[s]=1,a=t[s]>0,t[s]=0,a)}})})(jQuery);(function(e,t){var i=0,s=Array.prototype.slice,n=e.cleanData;e.cleanData=function(t){for(var i,s=0;null!=(i=t[s]);s++)try{e(i).triggerHandler("remove")}catch(a){}n(t)},e.widget=function(i,s,n){var a,r,o,h,l={},u=i.split(".")[0];i=i.split(".")[1],a=u+"-"+i,n||(n=s,s=e.Widget),e.expr[":"][a.toLowerCase()]=function(t){return!!e.data(t,a)},e[u]=e[u]||{},r=e[u][i],o=e[u][i]=function(e,i){return this._createWidget?(arguments.length&&this._createWidget(e,i),t):new o(e,i)},e.extend(o,r,{version:n.version,_proto:e.extend({},n),_childConstructors:[]}),h=new s,h.options=e.widget.extend({},h.options),e.each(n,function(i,n){return e.isFunction(n)?(l[i]=function(){var e=function(){return s.prototype[i].apply(this,arguments)},t=function(e){return s.prototype[i].apply(this,e)};return function(){var i,s=this._super,a=this._superApply;return this._super=e,this._superApply=t,i=n.apply(this,arguments),this._super=s,this._superApply=a,i}}(),t):(l[i]=n,t)}),o.prototype=e.widget.extend(h,{widgetEventPrefix:r?h.widgetEventPrefix:i},l,{constructor:o,namespace:u,widgetName:i,widgetFullName:a}),r?(e.each(r._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete r._childConstructors):s._childConstructors.push(o),e.widget.bridge(i,o)},e.widget.extend=function(i){for(var n,a,r=s.call(arguments,1),o=0,h=r.length;h>o;o++)for(n in r[o])a=r[o][n],r[o].hasOwnProperty(n)&&a!==t&&(i[n]=e.isPlainObject(a)?e.isPlainObject(i[n])?e.widget.extend({},i[n],a):e.widget.extend({},a):a);return i},e.widget.bridge=function(i,n){var a=n.prototype.widgetFullName||i;e.fn[i]=function(r){var o="string"==typeof r,h=s.call(arguments,1),l=this;return r=!o&&h.length?e.widget.extend.apply(null,[r].concat(h)):r,o?this.each(function(){var s,n=e.data(this,a);return n?e.isFunction(n[r])&&"_"!==r.charAt(0)?(s=n[r].apply(n,h),s!==n&&s!==t?(l=s&&s.jquery?l.pushStack(s.get()):s,!1):t):e.error("no such method '"+r+"' for "+i+" widget instance"):e.error("cannot call methods on "+i+" prior to initialization; "+"attempted to call method '"+r+"'")}):this.each(function(){var t=e.data(this,a);t?t.option(r||{})._init():e.data(this,a,new n(r,this))}),l}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
    ",options:{disabled:!1,create:null},_createWidget:function(t,s){s=e(s||this.defaultElement||this)[0],this.element=e(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),s!==this&&(e.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===s&&this.destroy()}}),this.document=e(s.style?s.ownerDocument:s.document||s),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(i,s){var n,a,r,o=i;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof i)if(o={},n=i.split("."),i=n.shift(),n.length){for(a=o[i]=e.widget.extend({},this.options[i]),r=0;n.length-1>r;r++)a[n[r]]=a[n[r]]||{},a=a[n[r]];if(i=n.pop(),s===t)return a[i]===t?null:a[i];a[i]=s}else{if(s===t)return this.options[i]===t?null:this.options[i];o[i]=s}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!t).attr("aria-disabled",t),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(i,s,n){var a,r=this;"boolean"!=typeof i&&(n=s,s=i,i=!1),n?(s=a=e(s),this.bindings=this.bindings.add(s)):(n=s,s=this.element,a=this.widget()),e.each(n,function(n,o){function h(){return i||r.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?r[o]:o).apply(r,arguments):t}"string"!=typeof o&&(h.guid=o.guid=o.guid||h.guid||e.guid++);var l=n.match(/^(\w+)\s*(.*)$/),u=l[1]+r.eventNamespace,c=l[2];c?a.delegate(c,u,h):s.bind(u,h)})},_off:function(e,t){t=(t||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.unbind(t).undelegate(t)},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var n,a,r=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],a=i.originalEvent)for(n in a)n in i||(i[n]=a[n]);return this.element.trigger(i,s),!(e.isFunction(r)&&r.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,n,a){"string"==typeof n&&(n={effect:n});var r,o=n?n===!0||"number"==typeof n?i:n.effect||i:t;n=n||{},"number"==typeof n&&(n={duration:n}),r=!e.isEmptyObject(n),n.complete=a,n.delay&&s.delay(n.delay),r&&e.effects&&e.effects.effect[o]?s[t](n):o!==t&&s[o]?s[o](n.duration,n.easing,a):s.queue(function(i){e(this)[t](),a&&a.call(s[0]),i()})}})})(jQuery);(function(e){var t=!1;e(document).mouseup(function(){t=!1}),e.widget("ui.mouse",{version:"1.10.3",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(i){return!0===e.data(i.target,t.widgetName+".preventClickEvent")?(e.removeData(i.target,t.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):undefined}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(i){if(!t){this._mouseStarted&&this._mouseUp(i),this._mouseDownEvent=i;var s=this,n=1===i.which,a="string"==typeof this.options.cancel&&i.target.nodeName?e(i.target).closest(this.options.cancel).length:!1;return n&&!a&&this._mouseCapture(i)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){s.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(i)&&this._mouseDelayMet(i)&&(this._mouseStarted=this._mouseStart(i)!==!1,!this._mouseStarted)?(i.preventDefault(),!0):(!0===e.data(i.target,this.widgetName+".preventClickEvent")&&e.removeData(i.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return s._mouseMove(e)},this._mouseUpDelegate=function(e){return s._mouseUp(e)},e(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),i.preventDefault(),t=!0,!0)):!0}},_mouseMove:function(t){return e.ui.ie&&(!document.documentMode||9>document.documentMode)&&!t.button?this._mouseUp(t):this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){return e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})})(jQuery);(function(e){e.widget("ui.draggable",e.ui.mouse,{version:"1.10.3",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"!==this.options.helper||/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy()},_mouseCapture:function(t){var i=this.options;return this.helper||i.disabled||e(t.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(t),this.handle?(e(i.iframeFix===!0?"iframe":i.iframeFix).each(function(){e("
    ").css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(e(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(t){var i=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offsetParent=this.helper.offsetParent(),this.offsetParentCssPosition=this.offsetParent.css("position"),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.offset.scroll=!1,e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_mouseDrag:function(t,i){if("fixed"===this.offsetParentCssPosition&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",t,s)===!1)return this._mouseUp({}),!1;this.position=s.position}return this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var i=this,s=!1;return e.ui.ddmanager&&!this.options.dropBehaviour&&(s=e.ui.ddmanager.drop(this,t)),this.dropped&&(s=this.dropped,this.dropped=!1),"original"!==this.options.helper||e.contains(this.element[0].ownerDocument,this.element[0])?("invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",t)!==!1&&i._clear()}):this._trigger("stop",t)!==!1&&this._clear(),!1):!1},_mouseUp:function(t){return e("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){return this.options.handle?!!e(t.target).closest(this.element.find(this.options.handle)).length:!0},_createHelper:function(t){var i=this.options,s=e.isFunction(i.helper)?e(i.helper.apply(this.element[0],[t])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return s.parents("body").length||s.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s[0]===this.element[0]||/(fixed|absolute)/.test(s.css("position"))||s.css("position","absolute"),s},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){var t=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&e.ui.ie)&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var e=this.element.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,s,n=this.options;return n.containment?"window"===n.containment?(this.containment=[e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,e(window).scrollLeft()+e(window).width()-this.helperProportions.width-this.margins.left,e(window).scrollTop()+(e(window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],undefined):"document"===n.containment?(this.containment=[0,0,e(document).width()-this.helperProportions.width-this.margins.left,(e(document).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],undefined):n.containment.constructor===Array?(this.containment=n.containment,undefined):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=e(n.containment),s=i[0],s&&(t="hidden"!==i.css("overflow"),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(t?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(t?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=i),undefined):(this.containment=null,undefined)},_convertPositionTo:function(t,i){i||(i=this.position);var s="absolute"===t?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent;return this.offset.scroll||(this.offset.scroll={top:n.scrollTop(),left:n.scrollLeft()}),{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():this.offset.scroll.top)*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():this.offset.scroll.left)*s}},_generatePosition:function(t){var i,s,n,a,o=this.options,r="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=t.pageX,l=t.pageY;return this.offset.scroll||(this.offset.scroll={top:r.scrollTop(),left:r.scrollLeft()}),this.originalPosition&&(this.containment&&(this.relative_container?(s=this.relative_container.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,t.pageX-this.offset.click.lefti[2]&&(h=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),o.grid&&(n=o.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/o.grid[1])*o.grid[1]:this.originalPageY,l=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-o.grid[1]:n+o.grid[1]:n,a=o.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/o.grid[0])*o.grid[0]:this.originalPageX,h=i?a-this.offset.click.left>=i[0]||a-this.offset.click.left>i[2]?a:a-this.offset.click.left>=i[0]?a-o.grid[0]:a+o.grid[0]:a)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(t,i,s){return s=s||this._uiHash(),e.ui.plugin.call(this,t,[i,s]),"drag"===t&&(this.positionAbs=this._convertPositionTo("absolute")),e.Widget.prototype._trigger.call(this,t,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),e.ui.plugin.add("draggable","connectToSortable",{start:function(t,i){var s=e(this).data("ui-draggable"),n=s.options,a=e.extend({},i,{item:s.element});s.sortables=[],e(n.connectToSortable).each(function(){var i=e.data(this,"ui-sortable");i&&!i.options.disabled&&(s.sortables.push({instance:i,shouldRevert:i.options.revert}),i.refreshPositions(),i._trigger("activate",t,a))})},stop:function(t,i){var s=e(this).data("ui-draggable"),n=e.extend({},i,{item:s.element});e.each(s.sortables,function(){this.instance.isOver?(this.instance.isOver=0,s.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=this.shouldRevert),this.instance._mouseStop(t),this.instance.options.helper=this.instance.options._helper,"original"===s.options.helper&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",t,n))})},drag:function(t,i){var s=e(this).data("ui-draggable"),n=this;e.each(s.sortables,function(){var a=!1,o=this;this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(a=!0,e.each(s.sortables,function(){return this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this!==o&&this.instance._intersectsWith(this.instance.containerCache)&&e.contains(o.instance.element[0],this.instance.element[0])&&(a=!1),a})),a?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=e(n).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return i.helper[0]},t.target=this.instance.currentItem[0],this.instance._mouseCapture(t,!0),this.instance._mouseStart(t,!0,!0),this.instance.offset.click.top=s.offset.click.top,this.instance.offset.click.left=s.offset.click.left,this.instance.offset.parent.left-=s.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=s.offset.parent.top-this.instance.offset.parent.top,s._trigger("toSortable",t),s.dropped=this.instance.element,s.currentItem=s.element,this.instance.fromOutside=s),this.instance.currentItem&&this.instance._mouseDrag(t)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",t,this.instance._uiHash(this.instance)),this.instance._mouseStop(t,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),s._trigger("fromSortable",t),s.dropped=!1)})}}),e.ui.plugin.add("draggable","cursor",{start:function(){var t=e("body"),i=e(this).data("ui-draggable").options;t.css("cursor")&&(i._cursor=t.css("cursor")),t.css("cursor",i.cursor)},stop:function(){var t=e(this).data("ui-draggable").options;t._cursor&&e("body").css("cursor",t._cursor)}}),e.ui.plugin.add("draggable","opacity",{start:function(t,i){var s=e(i.helper),n=e(this).data("ui-draggable").options;s.css("opacity")&&(n._opacity=s.css("opacity")),s.css("opacity",n.opacity)},stop:function(t,i){var s=e(this).data("ui-draggable").options;s._opacity&&e(i.helper).css("opacity",s._opacity)}}),e.ui.plugin.add("draggable","scroll",{start:function(){var t=e(this).data("ui-draggable");t.scrollParent[0]!==document&&"HTML"!==t.scrollParent[0].tagName&&(t.overflowOffset=t.scrollParent.offset())},drag:function(t){var i=e(this).data("ui-draggable"),s=i.options,n=!1;i.scrollParent[0]!==document&&"HTML"!==i.scrollParent[0].tagName?(s.axis&&"x"===s.axis||(i.overflowOffset.top+i.scrollParent[0].offsetHeight-t.pageY=0;c--)r=p.snapElements[c].left,h=r+p.snapElements[c].width,l=p.snapElements[c].top,u=l+p.snapElements[c].height,r-m>v||g>h+m||l-m>y||b>u+m||!e.contains(p.snapElements[c].item.ownerDocument,p.snapElements[c].item)?(p.snapElements[c].snapping&&p.options.snap.release&&p.options.snap.release.call(p.element,t,e.extend(p._uiHash(),{snapItem:p.snapElements[c].item})),p.snapElements[c].snapping=!1):("inner"!==f.snapMode&&(s=m>=Math.abs(l-y),n=m>=Math.abs(u-b),a=m>=Math.abs(r-v),o=m>=Math.abs(h-g),s&&(i.position.top=p._convertPositionTo("relative",{top:l-p.helperProportions.height,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:u,left:0}).top-p.margins.top),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r-p.helperProportions.width}).left-p.margins.left),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:h}).left-p.margins.left)),d=s||n||a||o,"outer"!==f.snapMode&&(s=m>=Math.abs(l-b),n=m>=Math.abs(u-y),a=m>=Math.abs(r-g),o=m>=Math.abs(h-v),s&&(i.position.top=p._convertPositionTo("relative",{top:l,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:u-p.helperProportions.height,left:0}).top-p.margins.top),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r}).left-p.margins.left),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:h-p.helperProportions.width}).left-p.margins.left)),!p.snapElements[c].snapping&&(s||n||a||o||d)&&p.options.snap.snap&&p.options.snap.snap.call(p.element,t,e.extend(p._uiHash(),{snapItem:p.snapElements[c].item})),p.snapElements[c].snapping=s||n||a||o||d)}}),e.ui.plugin.add("draggable","stack",{start:function(){var t,i=this.data("ui-draggable").options,s=e.makeArray(e(i.stack)).sort(function(t,i){return(parseInt(e(t).css("zIndex"),10)||0)-(parseInt(e(i).css("zIndex"),10)||0)});s.length&&(t=parseInt(e(s[0]).css("zIndex"),10)||0,e(s).each(function(i){e(this).css("zIndex",t+i)}),this.css("zIndex",t+s.length))}}),e.ui.plugin.add("draggable","zIndex",{start:function(t,i){var s=e(i.helper),n=e(this).data("ui-draggable").options;s.css("zIndex")&&(n._zIndex=s.css("zIndex")),s.css("zIndex",n.zIndex)},stop:function(t,i){var s=e(this).data("ui-draggable").options;s._zIndex&&e(i.helper).css("zIndex",s._zIndex)}})})(jQuery);(function(t){function e(t,e,i){return t>e&&e+i>t}function i(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))}t.widget("ui.sortable",t.ui.mouse,{version:"1.10.3",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_create:function(){var t=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?"x"===t.axis||i(this.items[0].item):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_setOption:function(e,i){"disabled"===e?(this.options[e]=i,this.widget().toggleClass("ui-sortable-disabled",!!i)):t.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(e,i){var s=null,n=!1,a=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(e),t(e.target).parents().each(function(){return t.data(this,a.widgetName+"-item")===a?(s=t(this),!1):undefined}),t.data(e.target,a.widgetName+"-item")===a&&(s=t(e.target)),s?!this.options.handle||i||(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(e,i,s){var n,a,o=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,o.cursorAt&&this._adjustOffsetFromHelper(o.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),o.containment&&this._setContainment(),o.cursor&&"auto"!==o.cursor&&(a=this.document.find("body"),this.storedCursor=a.css("cursor"),a.css("cursor",o.cursor),this.storedStylesheet=t("").appendTo(a)),o.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",o.opacity)),o.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",o.zIndex)),this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!o.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,a,o=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY=0;i--)if(s=this.items[i],n=s.item[0],a=this._intersectsWithPointer(s),a&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===a?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===a?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),a=this.options.axis,o={};a&&"x"!==a||(o.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollLeft)),a&&"y"!==a||(o.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(o,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,a=t.left,o=a+t.width,r=t.top,h=r+t.height,l=this.offset.click.top,c=this.offset.click.left,u="x"===this.options.axis||s+l>r&&h>s+l,d="y"===this.options.axis||e+c>a&&o>e+c,p=u&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?p:e+this.helperProportions.width/2>a&&o>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var i="x"===this.options.axis||e(this.positionAbs.top+this.offset.click.top,t.top,t.height),s="y"===this.options.axis||e(this.positionAbs.left+this.offset.click.left,t.left,t.width),n=i&&s,a=this._getDragVerticalDirection(),o=this._getDragHorizontalDirection();return n?this.floating?o&&"right"===o||"down"===a?2:1:a&&("down"===a?2:1):!1},_intersectsWithSides:function(t){var i=e(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),s=e(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),n=this._getDragVerticalDirection(),a=this._getDragHorizontalDirection();return this.floating&&a?"right"===a&&s||"left"===a&&!s:n&&("down"===n&&i||"up"===n&&!i)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){var i,s,n,a,o=[],r=[],h=this._connectWith();if(h&&e)for(i=h.length-1;i>=0;i--)for(n=t(h[i]),s=n.length-1;s>=0;s--)a=t.data(n[s],this.widgetFullName),a&&a!==this&&!a.options.disabled&&r.push([t.isFunction(a.options.items)?a.options.items.call(a.element):t(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a]);for(r.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),i=r.length-1;i>=0;i--)r[i][0].each(function(){o.push(this)});return t(o)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,a,o,r,h,l,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i]),s=n.length-1;s>=0;s--)a=t.data(n[s],this.widgetFullName),a&&a!==this&&!a.options.disabled&&(u.push([t.isFunction(a.options.items)?a.options.items.call(a.element[0],e,{item:this.currentItem}):t(a.options.items,a.element),a]),this.containers.push(a));for(i=u.length-1;i>=0;i--)for(o=u[i][1],r=u[i][0],s=0,l=r.length;l>s;s++)h=t(r[s]),h.data(this.widgetName+"-item",o),c.push({item:h,instance:o,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,a;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),a=n.offset(),s.left=a.left,s.top=a.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)a=this.containers[i].element.offset(),this.containers[i].containerCache.left=a.left,this.containers[i].containerCache.top=a.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t("<"+s+">",e.document[0]).addClass(i||e.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tr"===s?e.currentItem.children().each(function(){t(" ",e.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(n)}):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_contactContainers:function(s){var n,a,o,r,h,l,c,u,d,p,f=null,m=null;for(n=this.containers.length-1;n>=0;n--)if(!t.contains(this.currentItem[0],this.containers[n].element[0]))if(this._intersectsWith(this.containers[n].containerCache)){if(f&&t.contains(this.containers[n].element[0],f.element[0]))continue;f=this.containers[n],m=n}else this.containers[n].containerCache.over&&(this.containers[n]._trigger("out",s,this._uiHash(this)),this.containers[n].containerCache.over=0);if(f)if(1===this.containers.length)this.containers[m].containerCache.over||(this.containers[m]._trigger("over",s,this._uiHash(this)),this.containers[m].containerCache.over=1);else{for(o=1e4,r=null,p=f.floating||i(this.currentItem),h=p?"left":"top",l=p?"width":"height",c=this.positionAbs[h]+this.offset.click[h],a=this.items.length-1;a>=0;a--)t.contains(this.containers[m].element[0],this.items[a].item[0])&&this.items[a].item[0]!==this.currentItem[0]&&(!p||e(this.positionAbs.top+this.offset.click.top,this.items[a].top,this.items[a].height))&&(u=this.items[a].item.offset()[h],d=!1,Math.abs(u-c)>Math.abs(u+this.items[a][l]-c)&&(d=!0,u+=this.items[a][l]),o>Math.abs(u-c)&&(o=Math.abs(u-c),r=this.items[a],this.direction=d?"up":"down"));if(!r&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[m])return;r?this._rearrange(s,r,null,!0):this._rearrange(s,null,this.containers[m].element,!0),this._trigger("change",s,this._uiHash()),this.containers[m]._trigger("change",s,this._uiHash(this)),this.currentContainer=this.containers[m],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[m]._trigger("over",s,this._uiHash(this)),this.containers[m].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,t("document"===n.containment?document:window).width()-this.helperProportions.width-this.margins.left,(t("document"===n.containment?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,a=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():a?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():a?0:n.scrollLeft())*s}},_generatePosition:function(e){var i,s,n=this.options,a=e.pageX,o=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==document&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.leftthis.containment[2]&&(a=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1],o=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((a-this.originalPageX)/n.grid[0])*n.grid[0],a=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:a-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){this.reverting=!1;var i,s=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(i in this._storedCSS)("auto"===this._storedCSS[i]||"static"===this._storedCSS[i])&&(this._storedCSS[i]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&s.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||s.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(s.push(function(t){this._trigger("remove",t,this._uiHash())}),s.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),s.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),i=this.containers.length-1;i>=0;i--)e||s.push(function(t){return function(e){t._trigger("deactivate",e,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over&&(s.push(function(t){return function(e){t._trigger("out",e,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,this.cancelHelperRemoval){if(!e){for(this._trigger("beforeStop",t,this._uiHash()),i=0;s.length>i;i++)s[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!1}if(e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null,!e){for(i=0;s.length>i;i++)s[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!0},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}})})(jQuery); \ No newline at end of file diff --git a/modules/appagebuilder/js/jquery.elevateZoom-3.0.8.min.js b/modules/appagebuilder/js/jquery.elevateZoom-3.0.8.min.js new file mode 100644 index 00000000..e5d16b87 --- /dev/null +++ b/modules/appagebuilder/js/jquery.elevateZoom-3.0.8.min.js @@ -0,0 +1,79 @@ +/* + * @Website: apollotheme.com - prestashop template provider + * @author Apollotheme + * @copyright 2007-2018 Apollotheme + * @description: + */ +/* jQuery elevateZoom 3.0.8 - Demo's and documentation: - www.elevateweb.co.uk/image-zoom - Copyright (c) 2013 Andrew Eades - www.elevateweb.co.uk - Dual licensed under the LGPL licenses. - http://en.wikipedia.org/wiki/MIT_License - http://en.wikipedia.org/wiki/GNU_General_Public_License */ +//DONGND:: fix type scroll to zoom on firefox +var check_browser = navigator.userAgent; +var leo = 'mousewheel wheel '; +if(check_browser.indexOf('Firefox') >= 0) { + leo = ''; +} + +"function"!==typeof Object.create&&(Object.create=function(d){function h(){}h.prototype=d;return new h}); +(function(d,h,l,m){var k={init:function(b,a){var c=this;c.elem=a;c.$elem=d(a);c.imageSrc=c.$elem.data("zoom-image")?c.$elem.data("zoom-image"):c.$elem.attr("src");c.options=d.extend({},d.fn.elevateZoom.options,b);c.options.tint&&(c.options.lensColour="none",c.options.lensOpacity="1");"inner"==c.options.zoomType&&(c.options.showLens=!1);c.$elem.parent().removeAttr("title").removeAttr("alt");c.zoomImage=c.imageSrc;c.refresh(1);d("#"+c.options.gallery+" a").click(function(a){c.options.galleryActiveClass&& +(d("#"+c.options.gallery+" a").removeClass(c.options.galleryActiveClass),d(this).addClass(c.options.galleryActiveClass));a.preventDefault();d(this).data("zoom-image")?c.zoomImagePre=d(this).data("zoom-image"):c.zoomImagePre=d(this).data("image");c.swaptheimage(d(this).data("image"),c.zoomImagePre);return!1})},refresh:function(b){var a=this;setTimeout(function(){a.fetch(a.imageSrc)},b||a.options.refresh)},fetch:function(b){var a=this,c=new Image;c.onload=function(){a.largeWidth=c.width;a.largeHeight= +c.height;a.startZoom();a.currentImage=a.imageSrc;a.options.onZoomedImageLoaded(a.$elem)};c.src=b},startZoom:function(){var b=this;b.nzWidth=b.$elem.width();b.nzHeight=b.$elem.height();b.isWindowActive=!1;b.isLensActive=!1;b.isTintActive=!1;b.overWindow=!1;b.options.imageCrossfade&&(b.zoomWrap=b.$elem.wrap('
    '),b.$elem.css("position","absolute"));b.zoomLock=1;b.scrollingLock=!1;b.changeBgSize=!1;b.currentZoomLevel=b.options.zoomLevel; +b.nzOffset=b.$elem.offset();b.widthRatio=b.largeWidth/b.currentZoomLevel/b.nzWidth;b.heightRatio=b.largeHeight/b.currentZoomLevel/b.nzHeight;"window"==b.options.zoomType&&(b.zoomWindowStyle="overflow: hidden;background-position: 0px 0px;text-align:center;background-color: "+String(b.options.zoomWindowBgColour)+";width: "+String(b.options.zoomWindowWidth)+"px;height: "+String(b.options.zoomWindowHeight)+"px;float: left;background-size: "+b.largeWidth/b.currentZoomLevel+"px "+b.largeHeight/b.currentZoomLevel+ +"px;display: none;z-index:100;border: "+String(b.options.borderSize)+"px solid "+b.options.borderColour+";background-repeat: no-repeat;position: absolute;");if("inner"==b.options.zoomType){var a=b.$elem.css("border-left-width");b.zoomWindowStyle="overflow: hidden;margin-left: "+String(a)+";margin-top: "+String(a)+";background-position: 0px 0px;width: "+String(b.nzWidth)+"px;height: "+String(b.nzHeight)+"px;float: left;display: none;cursor:"+b.options.cursor+";px solid "+b.options.borderColour+";background-repeat: no-repeat;position: absolute;"}"window"== +b.options.zoomType&&(lensHeight=b.nzHeight
    ');d("body").append(b.zoomContainer);b.options.containLensZoom&&"lens"==b.options.zoomType&&b.zoomContainer.css("overflow", +"hidden");"inner"!=b.options.zoomType&&(b.zoomLens=d("
     
    ").appendTo(b.zoomContainer).click(function(){b.$elem.trigger("click")}),b.options.tint&&(b.tintContainer=d("
    ").addClass("tintContainer"),b.zoomTint=d("
    "),b.zoomLens.wrap(b.tintContainer),b.zoomTintcss=b.zoomLens.after(b.zoomTint),b.zoomTintImage=d('').appendTo(b.zoomLens).click(function(){b.$elem.trigger("click")})));isNaN(b.options.zoomWindowPosition)?b.zoomWindow=d("
     
    ").appendTo("body").click(function(){b.$elem.trigger("click")}):b.zoomWindow=d("
     
    ").appendTo(b.zoomContainer).click(function(){b.$elem.trigger("click")});b.zoomWindowContainer=d("
    ").addClass("zoomWindowContainer").css("width",b.options.zoomWindowWidth);b.zoomWindow.wrap(b.zoomWindowContainer);"lens"==b.options.zoomType&&b.zoomLens.css({backgroundImage:"url('"+b.imageSrc+"')"});"window"==b.options.zoomType&&b.zoomWindow.css({backgroundImage:"url('"+b.imageSrc+"')"});"inner"==b.options.zoomType&&b.zoomWindow.css({backgroundImage:"url('"+b.imageSrc+ +"')"});b.$elem.bind("touchmove",function(a){a.preventDefault();b.setPosition(a.originalEvent.touches[0]||a.originalEvent.changedTouches[0])});b.zoomContainer.bind("touchmove",function(a){"inner"==b.options.zoomType&&b.showHideWindow("show");a.preventDefault();b.setPosition(a.originalEvent.touches[0]||a.originalEvent.changedTouches[0])});b.zoomContainer.bind("touchend",function(a){b.showHideWindow("hide");b.options.showLens&&b.showHideLens("hide");b.options.tint&&"inner"!=b.options.zoomType&&b.showHideTint("hide")}); +b.$elem.bind("touchend",function(a){b.showHideWindow("hide");b.options.showLens&&b.showHideLens("hide");b.options.tint&&"inner"!=b.options.zoomType&&b.showHideTint("hide")});b.options.showLens&&(b.zoomLens.bind("touchmove",function(a){a.preventDefault();b.setPosition(a.originalEvent.touches[0]||a.originalEvent.changedTouches[0])}),b.zoomLens.bind("touchend",function(a){b.showHideWindow("hide");b.options.showLens&&b.showHideLens("hide");b.options.tint&&"inner"!=b.options.zoomType&&b.showHideTint("hide")})); +b.$elem.bind("mousemove",function(a){!1==b.overWindow&&b.setElements("show");if(b.lastX!==a.clientX||b.lastY!==a.clientY)b.setPosition(a),b.currentLoc=a;b.lastX=a.clientX;b.lastY=a.clientY});b.zoomContainer.bind("mousemove",function(a){!1==b.overWindow&&b.setElements("show");if(b.lastX!==a.clientX||b.lastY!==a.clientY)b.setPosition(a),b.currentLoc=a;b.lastX=a.clientX;b.lastY=a.clientY});"inner"!=b.options.zoomType&&b.zoomLens.bind("mousemove",function(a){if(b.lastX!==a.clientX||b.lastY!==a.clientY)b.setPosition(a), +b.currentLoc=a;b.lastX=a.clientX;b.lastY=a.clientY});b.options.tint&&"inner"!=b.options.zoomType&&b.zoomTint.bind("mousemove",function(a){if(b.lastX!==a.clientX||b.lastY!==a.clientY)b.setPosition(a),b.currentLoc=a;b.lastX=a.clientX;b.lastY=a.clientY});"inner"==b.options.zoomType&&b.zoomWindow.bind("mousemove",function(a){if(b.lastX!==a.clientX||b.lastY!==a.clientY)b.setPosition(a),b.currentLoc=a;b.lastX=a.clientX;b.lastY=a.clientY});b.zoomContainer.add(b.$elem).mouseenter(function(){!1==b.overWindow&& +b.setElements("show")}).mouseleave(function(){b.scrollLock||b.setElements("hide")});"inner"!=b.options.zoomType&&b.zoomWindow.mouseenter(function(){b.overWindow=!0;b.setElements("hide")}).mouseleave(function(){b.overWindow=!1});b.minZoomLevel=b.options.minZoomLevel?b.options.minZoomLevel:2*b.options.scrollZoomIncrement;b.options.scrollZoom&&b.zoomContainer.add(b.$elem).bind(leo+"DOMMouseScroll MozMousePixelScroll",function(a){b.scrollLock=!0;clearTimeout(d.data(this,"timer"));d.data(this,"timer", +setTimeout(function(){b.scrollLock=!1},250));var e=a.originalEvent.wheelDelta||-1*a.originalEvent.detail;a.stopImmediatePropagation();a.stopPropagation();a.preventDefault();0=b.minZoomLevel&&b.changeZoomLevel(b.currentZoomLevel-b.options.scrollZoomIncrement):b.options.maxZoomLevel?b.currentZoomLevel<=b.options.maxZoomLevel&&b.changeZoomLevel(parseFloat(b.currentZoomLevel)+b.options.scrollZoomIncrement):b.changeZoomLevel(parseFloat(b.currentZoomLevel)+b.options.scrollZoomIncrement); +return!1})},setElements:function(b){if(!this.options.zoomEnabled)return!1;"show"==b&&this.isWindowSet&&("inner"==this.options.zoomType&&this.showHideWindow("show"),"window"==this.options.zoomType&&this.showHideWindow("show"),this.options.showLens&&this.showHideLens("show"),this.options.tint&&"inner"!=this.options.zoomType&&this.showHideTint("show"));"hide"==b&&("window"==this.options.zoomType&&this.showHideWindow("hide"),this.options.tint||this.showHideWindow("hide"),this.options.showLens&&this.showHideLens("hide"), +this.options.tint&&this.showHideTint("hide"))},setPosition:function(b){if(!this.options.zoomEnabled)return!1;this.nzHeight=this.$elem.height();this.nzWidth=this.$elem.width();this.nzOffset=this.$elem.offset();this.options.tint&&"inner"!=this.options.zoomType&&(this.zoomTint.css({top:0}),this.zoomTint.css({left:0}));this.options.responsive&&!this.options.scrollZoom&&this.options.showLens&&(lensHeight=this.nzHeightthis.nzHeight-this.zoomLens.height()/2-2*this.options.lensBorderSize,this.Eloppos=this.mouseLeft<0+this.zoomLens.width()/2,this.Eroppos=this.mouseLeft>this.nzWidth-this.zoomLens.width()/2-2*this.options.lensBorderSize);"inner"==this.options.zoomType&&(this.Etoppos=this.mouseTopthis.nzHeight- +this.nzHeight/2/this.heightRatio,this.Eloppos=this.mouseLeft<0+this.nzWidth/2/this.widthRatio,this.Eroppos=this.mouseLeft>this.nzWidth-this.nzWidth/2/this.widthRatio-2*this.options.lensBorderSize);0>=this.mouseLeft||0>this.mouseTop||this.mouseLeft>this.nzWidth||this.mouseTop>this.nzHeight?this.setElements("hide"):(this.options.showLens&&(this.lensLeftPos=String(this.mouseLeft-this.zoomLens.width()/2),this.lensTopPos=String(this.mouseTop-this.zoomLens.height()/2)),this.Etoppos&&(this.lensTopPos=0), +this.Eloppos&&(this.tintpos=this.lensLeftPos=this.windowLeftPos=0),"window"==this.options.zoomType&&(this.Eboppos&&(this.lensTopPos=Math.max(this.nzHeight-this.zoomLens.height()-2*this.options.lensBorderSize,0)),this.Eroppos&&(this.lensLeftPos=this.nzWidth-this.zoomLens.width()-2*this.options.lensBorderSize)),"inner"==this.options.zoomType&&(this.Eboppos&&(this.lensTopPos=Math.max(this.nzHeight-2*this.options.lensBorderSize,0)),this.Eroppos&&(this.lensLeftPos=this.nzWidth-this.nzWidth-2*this.options.lensBorderSize)), +"lens"==this.options.zoomType&&(this.windowLeftPos=String(-1*((b.pageX-this.nzOffset.left)*this.widthRatio-this.zoomLens.width()/2)),this.windowTopPos=String(-1*((b.pageY-this.nzOffset.top)*this.heightRatio-this.zoomLens.height()/2)),this.zoomLens.css({backgroundPosition:this.windowLeftPos+"px "+this.windowTopPos+"px"}),this.changeBgSize&&(this.nzHeight>this.nzWidth?("lens"==this.options.zoomType&&this.zoomLens.css({"background-size":this.largeWidth/this.newvalueheight+"px "+this.largeHeight/this.newvalueheight+ +"px"}),this.zoomWindow.css({"background-size":this.largeWidth/this.newvalueheight+"px "+this.largeHeight/this.newvalueheight+"px"})):("lens"==this.options.zoomType&&this.zoomLens.css({"background-size":this.largeWidth/this.newvaluewidth+"px "+this.largeHeight/this.newvaluewidth+"px"}),this.zoomWindow.css({"background-size":this.largeWidth/this.newvaluewidth+"px "+this.largeHeight/this.newvaluewidth+"px"})),this.changeBgSize=!1),this.setWindowPostition(b)),this.options.tint&&"inner"!=this.options.zoomType&& +this.setTintPosition(b),"window"==this.options.zoomType&&this.setWindowPostition(b),"inner"==this.options.zoomType&&this.setWindowPostition(b),this.options.showLens&&(this.fullwidth&&"lens"!=this.options.zoomType&&(this.lensLeftPos=0),this.zoomLens.css({left:this.lensLeftPos+"px",top:this.lensTopPos+"px"})))},showHideWindow:function(b){"show"!=b||this.isWindowActive||(this.options.zoomWindowFadeIn?this.zoomWindow.stop(!0,!0,!1).fadeIn(this.options.zoomWindowFadeIn):this.zoomWindow.show(),this.isWindowActive= +!0);"hide"==b&&this.isWindowActive&&(this.options.zoomWindowFadeOut?this.zoomWindow.stop(!0,!0).fadeOut(this.options.zoomWindowFadeOut):this.zoomWindow.hide(),this.isWindowActive=!1)},showHideLens:function(b){"show"!=b||this.isLensActive||(this.options.lensFadeIn?this.zoomLens.stop(!0,!0,!1).fadeIn(this.options.lensFadeIn):this.zoomLens.show(),this.isLensActive=!0);"hide"==b&&this.isLensActive&&(this.options.lensFadeOut?this.zoomLens.stop(!0,!0).fadeOut(this.options.lensFadeOut):this.zoomLens.hide(), +this.isLensActive=!1)},showHideTint:function(b){"show"!=b||this.isTintActive||(this.options.zoomTintFadeIn?this.zoomTint.css({opacity:this.options.tintOpacity}).animate().stop(!0,!0).fadeIn("slow"):(this.zoomTint.css({opacity:this.options.tintOpacity}).animate(),this.zoomTint.show()),this.isTintActive=!0);"hide"==b&&this.isTintActive&&(this.options.zoomTintFadeOut?this.zoomTint.stop(!0,!0).fadeOut(this.options.zoomTintFadeOut):this.zoomTint.hide(),this.isTintActive=!1)},setLensPostition:function(b){}, +setWindowPostition:function(b){var a=this;if(isNaN(a.options.zoomWindowPosition))a.externalContainer=d("#"+a.options.zoomWindowPosition),a.externalContainerWidth=a.externalContainer.width(),a.externalContainerHeight=a.externalContainer.height(),a.externalContainerOffset=a.externalContainer.offset(),a.windowOffsetTop=a.externalContainerOffset.top,a.windowOffsetLeft=a.externalContainerOffset.left;else switch(a.options.zoomWindowPosition){case 1:a.windowOffsetTop=a.options.zoomWindowOffety;a.windowOffsetLeft= ++a.nzWidth;break;case 2:a.options.zoomWindowHeight>a.nzHeight&&(a.windowOffsetTop=-1*(a.options.zoomWindowHeight/2-a.nzHeight/2),a.windowOffsetLeft=a.nzWidth);break;case 3:a.windowOffsetTop=a.nzHeight-a.zoomWindow.height()-2*a.options.borderSize;a.windowOffsetLeft=a.nzWidth;break;case 4:a.windowOffsetTop=a.nzHeight;a.windowOffsetLeft=a.nzWidth;break;case 5:a.windowOffsetTop=a.nzHeight;a.windowOffsetLeft=a.nzWidth-a.zoomWindow.width()-2*a.options.borderSize;break;case 6:a.options.zoomWindowHeight> +a.nzHeight&&(a.windowOffsetTop=a.nzHeight,a.windowOffsetLeft=-1*(a.options.zoomWindowWidth/2-a.nzWidth/2+2*a.options.borderSize));break;case 7:a.windowOffsetTop=a.nzHeight;a.windowOffsetLeft=0;break;case 8:a.windowOffsetTop=a.nzHeight;a.windowOffsetLeft=-1*(a.zoomWindow.width()+2*a.options.borderSize);break;case 9:a.windowOffsetTop=a.nzHeight-a.zoomWindow.height()-2*a.options.borderSize;a.windowOffsetLeft=-1*(a.zoomWindow.width()+2*a.options.borderSize);break;case 10:a.options.zoomWindowHeight>a.nzHeight&& +(a.windowOffsetTop=-1*(a.options.zoomWindowHeight/2-a.nzHeight/2),a.windowOffsetLeft=-1*(a.zoomWindow.width()+2*a.options.borderSize));break;case 11:a.windowOffsetTop=a.options.zoomWindowOffety;a.windowOffsetLeft=-1*(a.zoomWindow.width()+2*a.options.borderSize);break;case 12:a.windowOffsetTop=-1*(a.zoomWindow.height()+2*a.options.borderSize);a.windowOffsetLeft=-1*(a.zoomWindow.width()+2*a.options.borderSize);break;case 13:a.windowOffsetTop=-1*(a.zoomWindow.height()+2*a.options.borderSize);a.windowOffsetLeft= +0;break;case 14:a.options.zoomWindowHeight>a.nzHeight&&(a.windowOffsetTop=-1*(a.zoomWindow.height()+2*a.options.borderSize),a.windowOffsetLeft=-1*(a.options.zoomWindowWidth/2-a.nzWidth/2+2*a.options.borderSize));break;case 15:a.windowOffsetTop=-1*(a.zoomWindow.height()+2*a.options.borderSize);a.windowOffsetLeft=a.nzWidth-a.zoomWindow.width()-2*a.options.borderSize;break;case 16:a.windowOffsetTop=-1*(a.zoomWindow.height()+2*a.options.borderSize);a.windowOffsetLeft=a.nzWidth;break;default:a.windowOffsetTop= +a.options.zoomWindowOffety,a.windowOffsetLeft=a.nzWidth}a.isWindowSet=!0;a.windowOffsetTop+=a.options.zoomWindowOffety;a.windowOffsetLeft+=a.options.zoomWindowOffetx;a.zoomWindow.css({top:a.windowOffsetTop});a.zoomWindow.css({left:a.windowOffsetLeft});"inner"==a.options.zoomType&&(a.zoomWindow.css({top:0}),a.zoomWindow.css({left:0}));a.windowLeftPos=String(-1*((b.pageX-a.nzOffset.left)*a.widthRatio-a.zoomWindow.width()/2));a.windowTopPos=String(-1*((b.pageY-a.nzOffset.top)*a.heightRatio-a.zoomWindow.height()/ +2));a.Etoppos&&(a.windowTopPos=0);a.Eloppos&&(a.windowLeftPos=0);a.Eboppos&&(a.windowTopPos=-1*(a.largeHeight/a.currentZoomLevel-a.zoomWindow.height()));a.Eroppos&&(a.windowLeftPos=-1*(a.largeWidth/a.currentZoomLevel-a.zoomWindow.width()));a.fullheight&&(a.windowTopPos=0);a.fullwidth&&(a.windowLeftPos=0);if("window"==a.options.zoomType||"inner"==a.options.zoomType)1==a.zoomLock&&(1>=a.widthRatio&&(a.windowLeftPos=0),1>=a.heightRatio&&(a.windowTopPos=0)),a.largeHeight +a.nzWidth?("lens"==a.options.zoomType&&a.zoomLens.css({"background-size":a.largeWidth/a.newvalueheight+"px "+a.largeHeight/a.newvalueheight+"px"}),a.zoomWindow.css({"background-size":a.largeWidth/a.newvalueheight+"px "+a.largeHeight/a.newvalueheight+"px"})):("lens"!=a.options.zoomType&&a.zoomLens.css({"background-size":a.largeWidth/a.newvaluewidth+"px "+a.largeHeight/a.newvalueheight+"px"}),a.zoomWindow.css({"background-size":a.largeWidth/a.newvaluewidth+"px "+a.largeHeight/a.newvaluewidth+"px"})), +a.changeBgSize=!1),a.zoomWindow.css({backgroundPosition:a.windowLeftPos+"px "+a.windowTopPos+"px"}),a.scrollingLock=!1,a.loop=!1):(a.changeBgSize&&(a.nzHeight>a.nzWidth?("lens"==a.options.zoomType&&a.zoomLens.css({"background-size":a.largeWidth/a.newvalueheight+"px "+a.largeHeight/a.newvalueheight+"px"}),a.zoomWindow.css({"background-size":a.largeWidth/a.newvalueheight+"px "+a.largeHeight/a.newvalueheight+"px"})):("lens"!=a.options.zoomType&&a.zoomLens.css({"background-size":a.largeWidth/a.newvaluewidth+ +"px "+a.largeHeight/a.newvaluewidth+"px"}),a.zoomWindow.css({"background-size":a.largeWidth/a.newvaluewidth+"px "+a.largeHeight/a.newvaluewidth+"px"})),a.changeBgSize=!1),a.zoomWindow.css({backgroundPosition:a.xp+"px "+a.yp+"px"}))},16))):(a.changeBgSize&&(a.nzHeight>a.nzWidth?("lens"==a.options.zoomType&&a.zoomLens.css({"background-size":a.largeWidth/a.newvalueheight+"px "+a.largeHeight/a.newvalueheight+"px"}),a.zoomWindow.css({"background-size":a.largeWidth/a.newvalueheight+"px "+a.largeHeight/ +a.newvalueheight+"px"})):("lens"==a.options.zoomType&&a.zoomLens.css({"background-size":a.largeWidth/a.newvaluewidth+"px "+a.largeHeight/a.newvaluewidth+"px"}),a.largeHeight/a.newvaluewidth
    '),c.$elem.after(c.spinner)); +c.options.onImageSwap(c.$elem);e.onload=function(){c.largeWidth=e.width;c.largeHeight=e.height;c.zoomImage=a;c.zoomWindow.css({"background-size":c.largeWidth+"px "+c.largeHeight+"px"});c.zoomWindow.css({"background-size":c.largeWidth+"px "+c.largeHeight+"px"});c.swapAction(b,a)};e.src=a},swapAction:function(b,a){var c=this,e=new Image;e.onload=function(){c.nzHeight=e.height;c.nzWidth=e.width;c.options.onImageSwapComplete(c.$elem);c.doneCallback()};e.src=b;c.currentZoomLevel=c.options.zoomLevel;c.options.maxZoomLevel= +!1;"lens"==c.options.zoomType&&c.zoomLens.css({backgroundImage:"url('"+a+"')"});"window"==c.options.zoomType&&c.zoomWindow.css({backgroundImage:"url('"+a+"')"});"inner"==c.options.zoomType&&c.zoomWindow.css({backgroundImage:"url('"+a+"')"});c.currentImage=a;if(c.options.imageCrossfade){var f=c.$elem,g=f.clone();c.$elem.attr("src",b);c.$elem.after(g);g.stop(!0).fadeOut(c.options.imageCrossfade,function(){d(this).remove()});c.$elem.width("auto").removeAttr("width");c.$elem.height("auto").removeAttr("height"); +f.fadeIn(c.options.imageCrossfade);c.options.tint&&"inner"!=c.options.zoomType&&(f=c.zoomTintImage,g=f.clone(),c.zoomTintImage.attr("src",a),c.zoomTintImage.after(g),g.stop(!0).fadeOut(c.options.imageCrossfade,function(){d(this).remove()}),f.fadeIn(c.options.imageCrossfade),c.zoomTint.css({height:c.$elem.height()}),c.zoomTint.css({width:c.$elem.width()}));c.zoomContainer.css("height",c.$elem.height());c.zoomContainer.css("width",c.$elem.width());"inner"!=c.options.zoomType||c.options.constrainType|| +(c.zoomWrap.parent().css("height",c.$elem.height()),c.zoomWrap.parent().css("width",c.$elem.width()),c.zoomWindow.css("height",c.$elem.height()),c.zoomWindow.css("width",c.$elem.width()))}else c.$elem.attr("src",b),c.options.tint&&(c.zoomTintImage.attr("src",a),c.zoomTintImage.attr("height",c.$elem.height()),c.zoomTintImage.css({height:c.$elem.height()}),c.zoomTint.css({height:c.$elem.height()})),c.zoomContainer.css("height",c.$elem.height()),c.zoomContainer.css("width",c.$elem.width());c.options.imageCrossfade&& +(c.zoomWrap.css("height",c.$elem.height()),c.zoomWrap.css("width",c.$elem.width()));c.options.constrainType&&("height"==c.options.constrainType&&(c.zoomContainer.css("height",c.options.constrainSize),c.zoomContainer.css("width","auto"),c.options.imageCrossfade?(c.zoomWrap.css("height",c.options.constrainSize),c.zoomWrap.css("width","auto"),c.constwidth=c.zoomWrap.width()):(c.$elem.css("height",c.options.constrainSize),c.$elem.css("width","auto"),c.constwidth=c.$elem.width()),"inner"==c.options.zoomType&& +(c.zoomWrap.parent().css("height",c.options.constrainSize),c.zoomWrap.parent().css("width",c.constwidth),c.zoomWindow.css("height",c.options.constrainSize),c.zoomWindow.css("width",c.constwidth)),c.options.tint&&(c.tintContainer.css("height",c.options.constrainSize),c.tintContainer.css("width",c.constwidth),c.zoomTint.css("height",c.options.constrainSize),c.zoomTint.css("width",c.constwidth),c.zoomTintImage.css("height",c.options.constrainSize),c.zoomTintImage.css("width",c.constwidth))),"width"== +c.options.constrainType&&(c.zoomContainer.css("height","auto"),c.zoomContainer.css("width",c.options.constrainSize),c.options.imageCrossfade?(c.zoomWrap.css("height","auto"),c.zoomWrap.css("width",c.options.constrainSize),c.constheight=c.zoomWrap.height()):(c.$elem.css("height","auto"),c.$elem.css("width",c.options.constrainSize),c.constheight=c.$elem.height()),"inner"==c.options.zoomType&&(c.zoomWrap.parent().css("height",c.constheight),c.zoomWrap.parent().css("width",c.options.constrainSize),c.zoomWindow.css("height", +c.constheight),c.zoomWindow.css("width",c.options.constrainSize)),c.options.tint&&(c.tintContainer.css("height",c.constheight),c.tintContainer.css("width",c.options.constrainSize),c.zoomTint.css("height",c.constheight),c.zoomTint.css("width",c.options.constrainSize),c.zoomTintImage.css("height",c.constheight),c.zoomTintImage.css("width",c.options.constrainSize))))},doneCallback:function(){this.options.loadingIcon&&this.spinner.hide();this.nzOffset=this.$elem.offset();this.nzWidth=this.$elem.width(); +this.nzHeight=this.$elem.height();this.currentZoomLevel=this.options.zoomLevel;this.widthRatio=this.largeWidth/this.nzWidth;this.heightRatio=this.largeHeight/this.nzHeight;"window"==this.options.zoomType&&(lensHeight=this.nzHeightmaxheightnewvalue&&(newvalue=maxheightnewvalue),newvalue>maxwidthtnewvalue&&(newvalue=maxwidthtnewvalue),maxheightnewvalue<=newvalue?(this.heightRatio=this.largeHeight/ +newvalue/this.nzHeight,this.newvalueheight=newvalue>maxheightnewvalue?maxheightnewvalue:newvalue,this.fullheight=!0):(this.heightRatio=this.largeHeight/newvalue/this.nzHeight,this.newvalueheight=newvalue>maxheightnewvalue?maxheightnewvalue:newvalue,this.fullheight=!1),maxwidthtnewvalue<=newvalue?(this.widthRatio=this.largeWidth/newvalue/this.nzWidth,this.newvaluewidth=newvalue>maxwidthtnewvalue?maxwidthtnewvalue:newvalue,this.fullwidth=!0):(this.widthRatio=this.largeWidth/newvalue/this.nzWidth,this.newvaluewidth= +newvalue,this.fullwidth=!1));scrcontinue=!1;"inner"==this.options.zoomType&&(this.nzWidth>this.nzHeight&&(this.newvaluewidth<=maxwidthtnewvalue?scrcontinue=!0:(scrcontinue=!1,this.fullwidth=this.fullheight=!0)),this.nzHeight>this.nzWidth&&(this.newvaluewidth<=maxwidthtnewvalue?scrcontinue=!0:(scrcontinue=!1,this.fullwidth=this.fullheight=!0)));"inner"!=this.options.zoomType&&(scrcontinue=!0);scrcontinue&&(this.zoomLock=0,this.changeZoom=!0,this.options.zoomWindowHeight/this.heightRatio<=this.nzHeight&& +(this.currentZoomLevel=this.newvalueheight,"lens"!=this.options.zoomType&&"inner"!=this.options.zoomType&&(this.changeBgSize=!0,this.zoomLens.css({height:String(this.options.zoomWindowHeight/this.heightRatio)+"px"})),"lens"==this.options.zoomType||"inner"==this.options.zoomType)&&(this.changeBgSize=!0),this.options.zoomWindowWidth/this.widthRatio<=this.nzWidth&&("inner"!=this.options.zoomType&&this.newvaluewidth>this.newvalueheight&&(this.currentZoomLevel=this.newvaluewidth),"lens"!=this.options.zoomType&& +"inner"!=this.options.zoomType&&(this.changeBgSize=!0,this.zoomLens.css({width:String(this.options.zoomWindowWidth/this.widthRatio)+"px"})),"lens"==this.options.zoomType||"inner"==this.options.zoomType)&&(this.changeBgSize=!0),"inner"==this.options.zoomType&&(this.changeBgSize=!0,this.nzWidth>this.nzHeight&&(this.currentZoomLevel=this.newvaluewidth),this.nzHeight>this.nzWidth&&(this.currentZoomLevel=this.newvaluewidth)));this.setPosition(this.currentLoc)},closeAll:function(){self.zoomWindow&&self.zoomWindow.hide(); +self.zoomLens&&self.zoomLens.hide();self.zoomTint&&self.zoomTint.hide()},changeState:function(b){"enable"==b&&(this.options.zoomEnabled=!0);"disable"==b&&(this.options.zoomEnabled=!1)}};d.fn.elevateZoom=function(b){return this.each(function(){var a=Object.create(k);a.init(b,this);d.data(this,"elevateZoom",a)})};d.fn.elevateZoom.options={zoomActivation:"hover",zoomEnabled:!0,preloading:1,zoomLevel:1,scrollZoom:!1,scrollZoomIncrement:0.1,minZoomLevel:!1,maxZoomLevel:!1,easing:!1,easingAmount:12,lensSize:200, +zoomWindowWidth:400,zoomWindowHeight:400,zoomWindowOffetx:0,zoomWindowOffety:0,zoomWindowPosition:1,zoomWindowBgColour:"#fff",lensFadeIn:!1,lensFadeOut:!1,debug:!1,zoomWindowFadeIn:!1,zoomWindowFadeOut:!1,zoomWindowAlwaysShow:!1,zoomTintFadeIn:!1,zoomTintFadeOut:!1,borderSize:4,showLens:!0,borderColour:"#888",lensBorderSize:1,lensBorderColour:"#000",lensShape:"square",zoomType:"window",containLensZoom:!1,lensColour:"white",lensOpacity:0.4,lenszoom:!1,tint:!1,tintColour:"#333",tintOpacity:0.4,gallery:!1, +galleryActiveClass:"zoomGalleryActive",imageCrossfade:!1,constrainType:!1,constrainSize:!1,loadingIcon:!1,cursor:"default",responsive:!0,onComplete:d.noop,onZoomedImageLoaded:function(){},onImageSwap:d.noop,onImageSwapComplete:d.noop}})(jQuery,window,document); \ No newline at end of file diff --git a/modules/appagebuilder/js/jquery.fullPage.js b/modules/appagebuilder/js/jquery.fullPage.js new file mode 100644 index 00000000..92597b12 --- /dev/null +++ b/modules/appagebuilder/js/jquery.fullPage.js @@ -0,0 +1,3159 @@ +/*! + * fullPage 2.8.8 + * https://github.com/alvarotrigo/fullPage.js + * @license MIT licensed + * + * Copyright (C) 2015 alvarotrigo.com - A project by Alvaro Trigo + */ +(function(global, factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + define(['jquery'], function($) { + return factory($, global, global.document, global.Math); + }); + } else if (typeof exports === "object" && exports) { + module.exports = factory(require('jquery'), global, global.document, global.Math); + } else { + factory(jQuery, global, global.document, global.Math); + } +})(typeof window !== 'undefined' ? window : this, function($, window, document, Math, undefined) { + 'use strict'; + + // keeping central set of classnames and selectors + var WRAPPER = 'fullpage-wrapper'; + var WRAPPER_SEL = '.' + WRAPPER; + + // slimscroll + var SCROLLABLE = 'fp-scrollable'; + var SCROLLABLE_SEL = '.' + SCROLLABLE; + + // util + var RESPONSIVE = 'fp-responsive'; + var NO_TRANSITION = 'fp-notransition'; + var DESTROYED = 'fp-destroyed'; + var ENABLED = 'fp-enabled'; + var VIEWING_PREFIX = 'fp-viewing'; + var ACTIVE = 'active'; + var ACTIVE_SEL = '.' + ACTIVE; + var COMPLETELY = 'fp-completely'; + var COMPLETELY_SEL = '.' + COMPLETELY; + + // section + var SECTION_DEFAULT_SEL = '.section'; + var SECTION = 'fp-section'; + var SECTION_SEL = '.' + SECTION; + var SECTION_ACTIVE_SEL = SECTION_SEL + ACTIVE_SEL; + var SECTION_FIRST_SEL = SECTION_SEL + ':first'; + var SECTION_LAST_SEL = SECTION_SEL + ':last'; + var TABLE_CELL = 'fp-tableCell'; + var TABLE_CELL_SEL = '.' + TABLE_CELL; + var AUTO_HEIGHT = 'fp-auto-height'; + var AUTO_HEIGHT_SEL = '.fp-auto-height'; + var NORMAL_SCROLL = 'fp-normal-scroll'; + var NORMAL_SCROLL_SEL = '.fp-normal-scroll'; + + // section nav + var SECTION_NAV = 'fp-nav'; + var SECTION_NAV_SEL = '#' + SECTION_NAV; + var SECTION_NAV_TOOLTIP = 'fp-tooltip'; + var SECTION_NAV_TOOLTIP_SEL='.'+SECTION_NAV_TOOLTIP; + var SHOW_ACTIVE_TOOLTIP = 'fp-show-active'; + + // slide + // var SLIDE_DEFAULT_SEL = '.slide'; + //DONGND:: add special class item of carousel boostrap for appagebuilder + var SLIDE_DEFAULT_SEL = '.slide-ap'; + var SLIDE = 'fp-slide'; + var SLIDE_SEL = '.' + SLIDE; + var SLIDE_ACTIVE_SEL = SLIDE_SEL + ACTIVE_SEL; + var SLIDES_WRAPPER = 'fp-slides'; + var SLIDES_WRAPPER_SEL = '.' + SLIDES_WRAPPER; + var SLIDES_CONTAINER = 'fp-slidesContainer'; + var SLIDES_CONTAINER_SEL = '.' + SLIDES_CONTAINER; + var TABLE = 'fp-table'; + + // slide nav + var SLIDES_NAV = 'fp-slidesNav'; + var SLIDES_NAV_SEL = '.' + SLIDES_NAV; + var SLIDES_NAV_LINK_SEL = SLIDES_NAV_SEL + ' a'; + var SLIDES_ARROW = 'fp-controlArrow'; + var SLIDES_ARROW_SEL = '.' + SLIDES_ARROW; + var SLIDES_PREV = 'fp-prev'; + var SLIDES_PREV_SEL = '.' + SLIDES_PREV; + var SLIDES_ARROW_PREV = SLIDES_ARROW + ' ' + SLIDES_PREV; + var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL; + var SLIDES_NEXT = 'fp-next'; + var SLIDES_NEXT_SEL = '.' + SLIDES_NEXT; + var SLIDES_ARROW_NEXT = SLIDES_ARROW + ' ' + SLIDES_NEXT; + var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL; + + var $window = $(window); + var $document = $(document); + + // Default options for iScroll.js used when using scrollOverflow + var iscrollOptions = { + scrollbars: true, + mouseWheel: true, + hideScrollbars: false, + fadeScrollbars: false, + disableMouse: true, + interactiveScrollbars: true + }; + + $.fn.fullpage = function(options) { + //only once my friend! + if($('html').hasClass(ENABLED)){ displayWarnings(); return; } + + // common jQuery objects + var $htmlBody = $('html, body'); + var $body = $('body'); + + var FP = $.fn.fullpage; + + // Create some defaults, extending them with any options that were provided + options = $.extend({ + //navigation + menu: false, + anchors:[], + lockAnchors: false, + navigation: false, + navigationPosition: 'right', + navigationTooltips: [], + showActiveTooltip: false, + slidesNavigation: false, + slidesNavPosition: 'bottom', + scrollBar: false, + hybrid: false, + + //scrolling + css3: true, + scrollingSpeed: 700, + autoScrolling: true, + fitToSection: true, + fitToSectionDelay: 1000, + easing: 'easeInOutCubic', + easingcss3: 'ease', + loopBottom: false, + loopTop: false, + loopHorizontal: true, + continuousVertical: false, + continuousHorizontal: false, + scrollHorizontally: false, + interlockedSlides: false, + resetSliders: false, + fadingEffect: false, + normalScrollElements: null, + scrollOverflow: false, + scrollOverflowHandler: iscrollHandler, + scrollOverflowOptions: null, + touchSensitivity: 5, + normalScrollElementTouchThreshold: 5, + bigSectionsDestination: null, + + //Accessibility + keyboardScrolling: true, + animateAnchor: true, + recordHistory: true, + + //design + controlArrows: true, + controlArrowColor: '#fff', + verticalCentered: true, + sectionsColor : [], + paddingTop: 0, + paddingBottom: 0, + fixedElements: null, + responsive: 0, //backwards compabitility with responsiveWiddth + responsiveWidth: 0, + responsiveHeight: 0, + responsiveSlides: false, + + //Custom selectors + sectionSelector: SECTION_DEFAULT_SEL, + slideSelector: SLIDE_DEFAULT_SEL, + + //events + afterLoad: null, + onLeave: null, + afterRender: null, + afterResize: null, + afterReBuild: null, + afterSlideLoad: null, + onSlideLeave: null, + afterResponsive: null, + + lazyLoading: true + }, options); + + //flag to avoid very fast sliding for landscape sliders + var slideMoving = false; + + var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/); + var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints)); + var container = $(this); + var windowsHeight = $window.height(); + var isResizing = false; + var isWindowFocused = true; + var lastScrolledDestiny; + var lastScrolledSlide; + var canScroll = true; + var scrollings = []; + var controlPressed; + var isScrollAllowed = {}; + isScrollAllowed.m = { 'up':true, 'down':true, 'left':true, 'right':true }; + isScrollAllowed.k = $.extend(true,{}, isScrollAllowed.m); + + //timeouts + var resizeId; + var afterSectionLoadsId; + var afterSlideLoadsId; + var scrollId; + var scrollId2; + var keydownId; + var originals = $.extend(true, {}, options); //deep copy + + displayWarnings(); + + //fixing bug in iScroll with links: https://github.com/cubiq/iscroll/issues/783 + iscrollOptions.click = isTouch; // see #2035 + + //extending iScroll options with the user custom ones + iscrollOptions = $.extend(iscrollOptions, options.scrollOverflowOptions); + + //easeInOutCubic animation included in the plugin + $.extend($.easing,{ easeInOutCubic: function (x, t, b, c, d) {if ((t/=d/2) < 1) return c/2*t*t*t + b;return c/2*((t-=2)*t*t + 2) + b;}}); + + /** + * Sets the autoScroll option. + * It changes the scroll bar visibility and the history of the site as a result. + */ + function setAutoScrolling(value, type){ + setVariableState('autoScrolling', value, type); + + var element = $(SECTION_ACTIVE_SEL); + + if(options.autoScrolling && !options.scrollBar){ + $htmlBody.css({ + 'overflow' : 'hidden', + 'height' : '100%' + }); + + setRecordHistory(originals.recordHistory, 'internal'); + + //for IE touch devices + container.css({ + '-ms-touch-action': 'none', + 'touch-action': 'none' + }); + + if(element.length){ + //moving the container up + silentScroll(element.position().top); + } + + }else{ + $htmlBody.css({ + 'overflow' : 'visible', + 'height' : 'initial' + }); + + setRecordHistory(false, 'internal'); + + //for IE touch devices + container.css({ + '-ms-touch-action': '', + 'touch-action': '' + }); + + silentScroll(0); + + //scrolling the page to the section with no animation + if (element.length) { + $htmlBody.scrollTop(element.position().top); + } + } + } + + /** + * Defines wheter to record the history for each hash change in the URL. + */ + function setRecordHistory(value, type){ + setVariableState('recordHistory', value, type); + } + + /** + * Defines the scrolling speed + */ + function setScrollingSpeed(value, type){ + setVariableState('scrollingSpeed', value, type); + } + + /** + * Sets fitToSection + */ + function setFitToSection(value, type){ + setVariableState('fitToSection', value, type); + } + + /** + * Sets lockAnchors + */ + function setLockAnchors(value){ + options.lockAnchors = value; + } + + /** + * Adds or remove the possiblity of scrolling through sections by using the mouse wheel or the trackpad. + */ + function setMouseWheelScrolling(value){ + if(value){ + addMouseWheelHandler(); + addMiddleWheelHandler(); + }else{ + removeMouseWheelHandler(); + removeMiddleWheelHandler(); + } + } + + /** + * Adds or remove the possiblity of scrolling through sections by using the mouse wheel/trackpad or touch gestures. + * Optionally a second parameter can be used to specify the direction for which the action will be applied. + * + * @param directions string containing the direction or directions separated by comma. + */ + function setAllowScrolling(value, directions){ + if(typeof directions !== 'undefined'){ + directions = directions.replace(/ /g,'').split(','); + + $.each(directions, function (index, direction){ + setIsScrollAllowed(value, direction, 'm'); + }); + } + else if(value){ + setMouseWheelScrolling(true); + addTouchHandler(); + }else{ + setMouseWheelScrolling(false); + removeTouchHandler(); + } + } + + /** + * Adds or remove the possiblity of scrolling through sections by using the keyboard arrow keys + */ + function setKeyboardScrolling(value, directions){ + if(typeof directions !== 'undefined'){ + directions = directions.replace(/ /g,'').split(','); + + $.each(directions, function (index, direction){ + setIsScrollAllowed(value, direction, 'k'); + }); + }else{ + options.keyboardScrolling = value; + } + } + + /** + * Moves the page up one section. + */ + function moveSectionUp(){ + var prev = $(SECTION_ACTIVE_SEL).prev(SECTION_SEL); + + // DONGND: + if(!prev.length) + { + if($(SECTION_ACTIVE_SEL).prev().children().hasClass('fp-section')) + { + prev = $(SECTION_ACTIVE_SEL).prev().children(); + } + else if($(SECTION_ACTIVE_SEL).parent().prev().hasClass('fp-section')) + { + prev = $(SECTION_ACTIVE_SEL).parent().prev(); + } + else if($(SECTION_ACTIVE_SEL).parent().prev().children().hasClass('fp-section')) + { + prev = $(SECTION_ACTIVE_SEL).parent().prev().children(); + } + } + //looping to the bottom if there's no more sections above + if (!prev.length && (options.loopTop || options.continuousVertical)) { + prev = $(SECTION_SEL).last(); + } + + if (prev.length) { + scrollPage(prev, null, true); + } + } + + /** + * Moves the page down one section. + */ + function moveSectionDown(){ + var next = $(SECTION_ACTIVE_SEL).next(SECTION_SEL); + + // DONGND: + if(!next.length) + { + if($(SECTION_ACTIVE_SEL).next().children().hasClass('fp-section')) + { + next = $(SECTION_ACTIVE_SEL).next().children(); + } + else if($(SECTION_ACTIVE_SEL).parent().next().hasClass('fp-section')) + { + next = $(SECTION_ACTIVE_SEL).parent().next(); + } + else if($(SECTION_ACTIVE_SEL).parent().next().children().hasClass('fp-section')) + { + next = $(SECTION_ACTIVE_SEL).parent().next().children(); + } + } + //looping to the top if there's no more sections below + if(!next.length && + (options.loopBottom || options.continuousVertical)){ + next = $(SECTION_SEL).first(); + } + + if(next.length){ + scrollPage(next, null, false); + } + } + + /** + * Moves the page to the given section and slide with no animation. + * Anchors or index positions can be used as params. + */ + function silentMoveTo(sectionAnchor, slideAnchor){ + setScrollingSpeed (0, 'internal'); + moveTo(sectionAnchor, slideAnchor); + setScrollingSpeed (originals.scrollingSpeed, 'internal'); + } + + /** + * Moves the page to the given section and slide. + * Anchors or index positions can be used as params. + */ + function moveTo(sectionAnchor, slideAnchor){ + var destiny = getSectionByAnchor(sectionAnchor); + + if (typeof slideAnchor !== 'undefined'){ + scrollPageAndSlide(sectionAnchor, slideAnchor); + }else if(destiny.length > 0){ + scrollPage(destiny); + } + } + + /** + * Slides right the slider of the active section. + * Optional `section` param. + */ + function moveSlideRight(section){ + moveSlide('right', section); + } + + /** + * Slides left the slider of the active section. + * Optional `section` param. + */ + function moveSlideLeft(section){ + moveSlide('left', section); + } + + /** + * When resizing is finished, we adjust the slides sizes and positions + */ + function reBuild(resizing){ + if(container.hasClass(DESTROYED)){ return; } //nothing to do if the plugin was destroyed + + isResizing = true; + + windowsHeight = $window.height(); //updating global var + + $(SECTION_SEL).each(function(){ + var slidesWrap = $(this).find(SLIDES_WRAPPER_SEL); + var slides = $(this).find(SLIDE_SEL); + + //adjusting the height of the table-cell for IE and Firefox + if(options.verticalCentered){ + $(this).find(TABLE_CELL_SEL).css('height', getTableHeight($(this)) + 'px'); + } + + $(this).css('height', windowsHeight + 'px'); + + //resizing the scrolling divs + if(options.scrollOverflow){ + if(slides.length){ + slides.each(function(){ + createScrollBar($(this)); + }); + }else{ + createScrollBar($(this)); + } + } + + //adjusting the position fo the FULL WIDTH slides... + if (slides.length > 1) { + landscapeScroll(slidesWrap, slidesWrap.find(SLIDE_ACTIVE_SEL)); + } + }); + + var activeSection = $(SECTION_ACTIVE_SEL); + var sectionIndex = activeSection.index(SECTION_SEL); + + //isn't it the first section? + if(sectionIndex){ + //adjusting the position for the current section + silentMoveTo(sectionIndex + 1); + } + + isResizing = false; + $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container); + $.isFunction( options.afterReBuild ) && !resizing && options.afterReBuild.call(container); + } + + /** + * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height` + * are smaller than the set limit values. + */ + function setResponsive(active){ + var isResponsive = $body.hasClass(RESPONSIVE); + + if(active){ + if(!isResponsive){ + setAutoScrolling(false, 'internal'); + setFitToSection(false, 'internal'); + $(SECTION_NAV_SEL).hide(); + $body.addClass(RESPONSIVE); + $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); + } + } + else if(isResponsive){ + setAutoScrolling(originals.autoScrolling, 'internal'); + setFitToSection(originals.autoScrolling, 'internal'); + $(SECTION_NAV_SEL).show(); + $body.removeClass(RESPONSIVE); + $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); + } + } + + function getFullpageData(){ + return { + options: options, + internals: { + getXmovement: getXmovement, + removeAnimation: removeAnimation, + getTransforms: getTransforms, + lazyLoad: lazyLoad, + addAnimation: addAnimation, + performHorizontalMove: performHorizontalMove, + silentLandscapeScroll: silentLandscapeScroll, + keepSlidesPosition: keepSlidesPosition, + silentScroll: silentScroll, + styleSlides: styleSlides + } + }; + } + + if($(this).length){ + //public functions + FP.setAutoScrolling = setAutoScrolling; + FP.setRecordHistory = setRecordHistory; + FP.setScrollingSpeed = setScrollingSpeed; + FP.setFitToSection = setFitToSection; + FP.setLockAnchors = setLockAnchors; + FP.setMouseWheelScrolling = setMouseWheelScrolling; + FP.setAllowScrolling = setAllowScrolling; + FP.setKeyboardScrolling = setKeyboardScrolling; + FP.moveSectionUp = moveSectionUp; + FP.moveSectionDown = moveSectionDown; + FP.silentMoveTo = silentMoveTo; + FP.moveTo = moveTo; + FP.moveSlideRight = moveSlideRight; + FP.moveSlideLeft = moveSlideLeft; + FP.reBuild = reBuild; + FP.setResponsive = setResponsive; + FP.getFullpageData = getFullpageData; + FP.destroy = destroy; + + //DONGND: add function pause + + FP.pau = function(){ + FP.setAutoScrolling(false, 'internal'); + FP.setAllowScrolling(false); + FP.setKeyboardScrolling(false); + + $window + .off('scroll', scrollHandler) + .off('hashchange', hashChangeHandler) + .off('resize', resizeHandler); + + }; + + //DONGND: add function continue + + FP.con = function(){ + //DONGND:: disable scroll section if enable responsive + if (!$body.hasClass(RESPONSIVE)) + { + FP.setAutoScrolling(true); + } + FP.setAllowScrolling(true); + FP.setKeyboardScrolling(true); + + $window + .on('scroll', scrollHandler) + .on('hashchange', hashChangeHandler) + .on('resize', resizeHandler); + + $document.on('click touchstart', SECTION_NAV_SEL + ' a', function(e){ + e.preventDefault(); + var index = $(this).parent().index(); + scrollPage($(SECTION_SEL).eq(index)); + + }); + + }; + + + init(); + + bindEvents(); + } + + function init(){ + //if css3 is not supported, it will use jQuery animations + if(options.css3){ + options.css3 = support3d(); + } + + options.scrollBar = options.scrollBar || options.hybrid; + + setOptionsFromDOM(); + + prepareDom(); + setAllowScrolling(true); + + setAutoScrolling(options.autoScrolling, 'internal'); + + //the starting point is a slide? + var activeSlide = $(SECTION_ACTIVE_SEL).find(SLIDE_ACTIVE_SEL); + + //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/slide by default. + if( activeSlide.length && ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && activeSlide.index() !== 0))){ + silentLandscapeScroll(activeSlide); + } + + responsive(); + + //setting the class for the body element + setBodyClass(); + + if(document.readyState === 'complete'){ + scrollToAnchor(); + } + $window.on('load', scrollToAnchor); + } + + function bindEvents(){ + $window + //when scrolling... + .on('scroll', scrollHandler) + + //detecting any change on the URL to scroll to the given anchor link + //(a way to detect back history button as we play with the hashes on the URL) + .on('hashchange', hashChangeHandler) + + //when opening a new tab (ctrl + t), `control` won't be pressed when comming back. + .blur(blurHandler) + + //when resizing the site, we adjust the heights of the sections, slimScroll... + .resize(resizeHandler); + + $document + //Sliding with arrow keys, both, vertical and horizontal + .keydown(keydownHandler) + + //to prevent scrolling while zooming + .keyup(keyUpHandler) + + //Scrolls to the section when clicking the navigation bullet + .on('click touchstart', SECTION_NAV_SEL + ' a', sectionBulletHandler) + + //Scrolls the slider to the given slide destination for the given section + .on('click touchstart', SLIDES_NAV_LINK_SEL, slideBulletHandler) + + .on('click', SECTION_NAV_TOOLTIP_SEL, tooltipTextHandler); + + //Scrolling horizontally when clicking on the slider controls. + $(SECTION_SEL).on('click touchstart', SLIDES_ARROW_SEL, slideArrowHandler); + + /** + * Applying normalScroll elements. + * Ignoring the scrolls over the specified selectors. + */ + if(options.normalScrollElements){ + $document.on('mouseenter', options.normalScrollElements, function () { + setMouseWheelScrolling(false); + }); + + $document.on('mouseleave', options.normalScrollElements, function(){ + setMouseWheelScrolling(true); + }); + } + } + + /** + * Setting options from DOM elements if they are not provided. + */ + function setOptionsFromDOM(){ + var sections = container.find(options.sectionSelector); + + //no anchors option? Checking for them in the DOM attributes + if(!options.anchors.length){ + options.anchors = sections.filter('[data-anchor]').map(function(){ + return $(this).data('anchor').toString(); + }).get(); + } + + //no tooltipos option? Checking for them in the DOM attributes + if(!options.navigationTooltips.length){ + options.navigationTooltips = sections.filter('[data-tooltip]').map(function(){ + return $(this).data('tooltip').toString(); + }).get(); + } + } + + /** + * Works over the DOM structure to set it up for the current fullpage optionss. + */ + function prepareDom(){ + container.css({ + 'height': '100%', + 'position': 'relative' + }); + + //adding a class to recognize the container internally in the code + container.addClass(WRAPPER); + $('html').addClass(ENABLED); + + //due to https://github.com/alvarotrigo/fullPage.js/issues/1502 + windowsHeight = $window.height(); + + container.removeClass(DESTROYED); //in case it was destroyed before initilizing it again + + addInternalSelectors(); + + //styling the sections / slides / menu + $(SECTION_SEL).each(function(index){ + var section = $(this); + var slides = section.find(SLIDE_SEL); + var numSlides = slides.length; + + styleSection(section, index); + styleMenu(section, index); + + // if there's any slide + if (numSlides > 0) { + styleSlides(section, slides, numSlides); + }else{ + if(options.verticalCentered){ + addTableClass(section); + } + } + }); + + //fixed elements need to be moved out of the plugin container due to problems with CSS3. + if(options.fixedElements && options.css3){ + $(options.fixedElements).appendTo($body); + } + + //vertical centered of the navigation + active bullet + if(options.navigation){ + addVerticalNavigation(); + } + + enableYoutubeAPI(); + + if(options.scrollOverflow){ + if(document.readyState === 'complete'){ + createScrollBarHandler(); + } + //after DOM and images are loaded + $window.on('load', createScrollBarHandler); + }else{ + afterRenderActions(); + } + } + + /** + * Styles the horizontal slides for a section. + */ + function styleSlides(section, slides, numSlides){ + var sliderWidth = numSlides * 100; + var slideWidth = 100 / numSlides; + + slides.wrapAll('
    '); + slides.parent().wrap('
    '); + + section.find(SLIDES_CONTAINER_SEL).css('width', sliderWidth + '%'); + + if(numSlides > 1){ + if(options.controlArrows){ + createSlideArrows(section); + } + + if(options.slidesNavigation){ + addSlidesNavigation(section, numSlides); + } + } + + slides.each(function(index) { + $(this).css('width', slideWidth + '%'); + + if(options.verticalCentered){ + addTableClass($(this)); + } + }); + + var startingSlide = section.find(SLIDE_ACTIVE_SEL); + + //if the slide won't be an starting point, the default will be the first one + //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/slide by default. + if( startingSlide.length && ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && startingSlide.index() !== 0))){ + silentLandscapeScroll(startingSlide); + }else{ + slides.eq(0).addClass(ACTIVE); + } + } + + /** + * Styling vertical sections + */ + function styleSection(section, index){ + //if no active section is defined, the 1st one will be the default one + if(!index && $(SECTION_ACTIVE_SEL).length === 0) { + section.addClass(ACTIVE); + } + + section.css('height', windowsHeight + 'px'); + + if(options.paddingTop){ + section.css('padding-top', options.paddingTop); + } + + if(options.paddingBottom){ + section.css('padding-bottom', options.paddingBottom); + } + + if (typeof options.sectionsColor[index] !== 'undefined') { + section.css('background-color', options.sectionsColor[index]); + } + + if (typeof options.anchors[index] !== 'undefined') { + section.attr('data-anchor', options.anchors[index]); + } + } + + /** + * Sets the data-anchor attributes to the menu elements and activates the current one. + */ + function styleMenu(section, index){ + if (typeof options.anchors[index] !== 'undefined') { + //activating the menu / nav element on load + if(section.hasClass(ACTIVE)){ + activateMenuAndNav(options.anchors[index], index); + } + } + + //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms) + if(options.menu && options.css3 && $(options.menu).closest(WRAPPER_SEL).length){ + $(options.menu).appendTo($body); + } + } + + /** + * Adds internal classes to be able to provide customizable selectors + * keeping the link with the style sheet. + */ + function addInternalSelectors(){ + container.find(options.sectionSelector).addClass(SECTION); + container.find(options.slideSelector).addClass(SLIDE); + } + + /** + * Creates the control arrows for the given section + */ + function createSlideArrows(section){ + section.find(SLIDES_WRAPPER_SEL).after('
    '); + + if(options.controlArrowColor!='#fff'){ + section.find(SLIDES_ARROW_NEXT_SEL).css('border-color', 'transparent transparent transparent '+options.controlArrowColor); + section.find(SLIDES_ARROW_PREV_SEL).css('border-color', 'transparent '+ options.controlArrowColor + ' transparent transparent'); + } + + if(!options.loopHorizontal){ + section.find(SLIDES_ARROW_PREV_SEL).hide(); + } + } + + /** + * Creates a vertical navigation bar. + */ + function addVerticalNavigation(){ + $body.append('
      '); + var nav = $(SECTION_NAV_SEL); + + nav.addClass(function() { + return options.showActiveTooltip ? SHOW_ACTIVE_TOOLTIP + ' ' + options.navigationPosition : options.navigationPosition; + }); + + for (var i = 0; i < $(SECTION_SEL).length; i++) { + var link = ''; + if (options.anchors.length) { + link = options.anchors[i]; + } + + var li = '
    • '; + + // Only add tooltip if needed (defined by user) + var tooltip = options.navigationTooltips[i]; + + if (typeof tooltip !== 'undefined' && tooltip !== '') { + li += '
      ' + tooltip + '
      '; + } + + li += '
    • '; + + nav.find('ul').append(li); + } + + //centering it vertically + $(SECTION_NAV_SEL).css('margin-top', '-' + ($(SECTION_NAV_SEL).height()/2) + 'px'); + + //activating the current active section + $(SECTION_NAV_SEL).find('li').eq($(SECTION_ACTIVE_SEL).index(SECTION_SEL)).find('a').addClass(ACTIVE); + } + + /** + * Creates the slim scroll scrollbar for the sections and slides inside them. + */ + function createScrollBarHandler(){ + $(SECTION_SEL).each(function(){ + var slides = $(this).find(SLIDE_SEL); + + if(slides.length){ + slides.each(function(){ + createScrollBar($(this)); + }); + }else{ + createScrollBar($(this)); + } + + }); + afterRenderActions(); + } + + /* + * Enables the Youtube videos API so we can control their flow if necessary. + */ + function enableYoutubeAPI(){ + container.find('iframe[src*="youtube.com/embed/"]').each(function(){ + addURLParam($(this), 'enablejsapi=1'); + }); + } + + /** + * Adds a new parameter and its value to the `src` of a given element + */ + function addURLParam(element, newParam){ + var originalSrc = element.attr('src'); + element.attr('src', originalSrc + getUrlParamSign(originalSrc) + newParam); + } + + /* + * Returns the prefix sign to use for a new parameter in an existen URL. + * + * @return {String} ? | & + */ + function getUrlParamSign(url){ + return ( !/\?/.test( url ) ) ? '?' : '&'; + } + + /** + * Actions and callbacks to fire afterRender + */ + function afterRenderActions(){ + var section = $(SECTION_ACTIVE_SEL); + + section.addClass(COMPLETELY); + + if(options.scrollOverflowHandler.afterRender){ + options.scrollOverflowHandler.afterRender(section); + } + lazyLoad(section); + playMedia(section); + + $.isFunction( options.afterLoad ) && options.afterLoad.call(section, section.data('anchor'), (section.index(SECTION_SEL) + 1)); + $.isFunction( options.afterRender ) && options.afterRender.call(container); + } + + + var isScrolling = false; + var lastScroll = 0; + + //when scrolling... + function scrollHandler(){ + var currentSection; + + if(!options.autoScrolling || options.scrollBar){ + var currentScroll = $window.scrollTop(); + var scrollDirection = getScrollDirection(currentScroll); + var visibleSectionIndex = 0; + var screen_mid = currentScroll + ($window.height() / 2.0); + var isAtBottom = $body.height() - $window.height() === currentScroll; + var sections = document.querySelectorAll(SECTION_SEL); + + //when using `auto-height` for a small last section it won't be centered in the viewport + if(isAtBottom){ + visibleSectionIndex = sections.length - 1; + } + //is at top? when using `auto-height` for a small first section it won't be centered in the viewport + else if(!currentScroll){ + visibleSectionIndex = 0; + } + + //taking the section which is showing more content in the viewport + else{ + for (var i = 0; i < sections.length; ++i) { + var section = sections[i]; + + // Pick the the last section which passes the middle line of the screen. + if (section.offsetTop <= screen_mid) + { + visibleSectionIndex = i; + } + } + } + + if(isCompletelyInViewPort(scrollDirection)){ + if(!$(SECTION_ACTIVE_SEL).hasClass(COMPLETELY)){ + $(SECTION_ACTIVE_SEL).addClass(COMPLETELY).siblings().removeClass(COMPLETELY); + } + } + + //geting the last one, the current one on the screen + currentSection = $(sections).eq(visibleSectionIndex); + + //setting the visible section as active when manually scrolling + //executing only once the first time we reach the section + if(!currentSection.hasClass(ACTIVE)){ + isScrolling = true; + var leavingSection = $(SECTION_ACTIVE_SEL); + var leavingSectionIndex = leavingSection.index(SECTION_SEL) + 1; + var yMovement = getYmovement(currentSection); + var anchorLink = currentSection.data('anchor'); + var sectionIndex = currentSection.index(SECTION_SEL) + 1; + var activeSlide = currentSection.find(SLIDE_ACTIVE_SEL); + var slideIndex; + var slideAnchorLink; + + if(activeSlide.length){ + slideAnchorLink = activeSlide.data('anchor'); + slideIndex = activeSlide.index(); + } + + if(canScroll){ + currentSection.addClass(ACTIVE).siblings().removeClass(ACTIVE); + + $.isFunction( options.onLeave ) && options.onLeave.call( leavingSection, leavingSectionIndex, sectionIndex, yMovement); + $.isFunction( options.afterLoad ) && options.afterLoad.call( currentSection, anchorLink, sectionIndex); + + stopMedia(leavingSection); + lazyLoad(currentSection); + playMedia(currentSection); + + activateMenuAndNav(anchorLink, sectionIndex - 1); + + if(options.anchors.length){ + //needed to enter in hashChange event when using the menu with anchor links + lastScrolledDestiny = anchorLink; + } + setState(slideIndex, slideAnchorLink, anchorLink, sectionIndex); + } + + //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet + clearTimeout(scrollId); + scrollId = setTimeout(function(){ + isScrolling = false; + }, 100); + } + + if(options.fitToSection){ + //for the auto adjust of the viewport to fit a whole section + clearTimeout(scrollId2); + + scrollId2 = setTimeout(function(){ + //checking fitToSection again in case it was set to false before the timeout delay + if(canScroll && options.fitToSection){ + //allows to scroll to an active section and + //if the section is already active, we prevent firing callbacks + if($(SECTION_ACTIVE_SEL).is(currentSection)){ + isResizing = true; + } + scrollPage($(SECTION_ACTIVE_SEL)); + + isResizing = false; + } + }, options.fitToSectionDelay); + } + } + } + + /** + * Determines whether the active section has seen in its whole or not. + */ + function isCompletelyInViewPort(movement){ + var top = $(SECTION_ACTIVE_SEL).position().top; + var bottom = top + $window.height(); + + if(movement == 'up'){ + return bottom >= ($window.scrollTop() + $window.height()); + } + return top <= $window.scrollTop(); + } + + /** + * Gets the directon of the the scrolling fired by the scroll event. + */ + function getScrollDirection(currentScroll){ + var direction = currentScroll > lastScroll ? 'down' : 'up'; + + lastScroll = currentScroll; + + //needed for auto-height sections to determine if we want to scroll to the top or bottom of the destination + previousDestTop = currentScroll; + + return direction; + } + + /** + * Determines the way of scrolling up or down: + * by 'automatically' scrolling a section or by using the default and normal scrolling. + */ + function scrolling(type, scrollable){ + if (!isScrollAllowed.m[type]){ + return; + } + var check = (type === 'down') ? 'bottom' : 'top'; + var scrollSection = (type === 'down') ? moveSectionDown : moveSectionUp; + + if(scrollable.length > 0 ){ + //is the scrollbar at the start/end of the scroll? + if(options.scrollOverflowHandler.isScrolled(check, scrollable)){ + scrollSection(); + }else{ + return true; + } + }else{ + // moved up/down + scrollSection(); + } + } + + /* + * Preventing bouncing in iOS #2285 + */ + function preventBouncing(event){ + var e = event.originalEvent; + if(options.autoScrolling && isReallyTouch(e)){ + //preventing the easing on iOS devices + event.preventDefault(); + } + } + + var touchStartY = 0; + var touchStartX = 0; + var touchEndY = 0; + var touchEndX = 0; + + /* Detecting touch events + + * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it. + * This way, the touchstart and the touch moves shows an small difference between them which is the + * used one to determine the direction. + */ + function touchMoveHandler(event){ + var e = event.originalEvent; + var activeSection = $(e.target).closest(SECTION_SEL); + + // additional: if one of the normalScrollElements isn't within options.normalScrollElementTouchThreshold hops up the DOM chain + if (!checkParentForNormalScrollElement(event.target) && isReallyTouch(e) ) { + + if(options.autoScrolling){ + //preventing the easing on iOS devices + event.preventDefault(); + } + + var scrollable = options.scrollOverflowHandler.scrollable(activeSection); + + if (canScroll && !slideMoving) { //if theres any # + var touchEvents = getEventsPage(e); + + touchEndY = touchEvents.y; + touchEndX = touchEvents.x; + + //if movement in the X axys is greater than in the Y and the currect section has slides... + if (activeSection.find(SLIDES_WRAPPER_SEL).length && Math.abs(touchStartX - touchEndX) > (Math.abs(touchStartY - touchEndY))) { + + //is the movement greater than the minimum resistance to scroll? + if (Math.abs(touchStartX - touchEndX) > ($window.outerWidth() / 100 * options.touchSensitivity)) { + if (touchStartX > touchEndX) { + if(isScrollAllowed.m.right){ + moveSlideRight(activeSection); //next + } + } else { + if(isScrollAllowed.m.left){ + moveSlideLeft(activeSection); //prev + } + } + } + } + + //vertical scrolling (only when autoScrolling is enabled) + else if(options.autoScrolling){ + + //is the movement greater than the minimum resistance to scroll? + if (Math.abs(touchStartY - touchEndY) > ($window.height() / 100 * options.touchSensitivity)) { + if (touchStartY > touchEndY) { + scrolling('down', scrollable); + } else if (touchEndY > touchStartY) { + scrolling('up', scrollable); + } + } + } + } + } + + } + + /** + * recursive function to loop up the parent nodes to check if one of them exists in options.normalScrollElements + * Currently works well for iOS - Android might need some testing + * @param {Element} el target element / jquery selector (in subsequent nodes) + * @param {int} hop current hop compared to options.normalScrollElementTouchThreshold + * @return {boolean} true if there is a match to options.normalScrollElements + */ + function checkParentForNormalScrollElement (el, hop) { + hop = hop || 0; + var parent = $(el).parent(); + + if (hop < options.normalScrollElementTouchThreshold && + parent.is(options.normalScrollElements) ) { + return true; + } else if (hop == options.normalScrollElementTouchThreshold) { + return false; + } else { + return checkParentForNormalScrollElement(parent, ++hop); + } + } + + /** + * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen + * this way we make sure that is really a touch event what IE is detecting. + */ + function isReallyTouch(e){ + //if is not IE || IE is detecting `touch` or `pen` + return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse'; + } + + /** + * Handler for the touch start event. + */ + function touchStartHandler(event){ + var e = event.originalEvent; + + //stopping the auto scroll to adjust to a section + if(options.fitToSection){ + $htmlBody.stop(); + } + + if(isReallyTouch(e)){ + var touchEvents = getEventsPage(e); + touchStartY = touchEvents.y; + touchStartX = touchEvents.x; + } + } + + /** + * Gets the average of the last `number` elements of the given array. + */ + function getAverage(elements, number){ + var sum = 0; + + //taking `number` elements from the end to make the average, if there are not enought, 1 + var lastElements = elements.slice(Math.max(elements.length - number, 1)); + + for(var i = 0; i < lastElements.length; i++){ + sum = sum + lastElements[i]; + } + + return Math.ceil(sum/number); + } + + /** + * Detecting mousewheel scrolling + * + * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html + * http://www.sitepoint.com/html5-javascript-mouse-wheel/ + */ + var prevTime = new Date().getTime(); + + function MouseWheelHandler(e) { + var curTime = new Date().getTime(); + var isNormalScroll = $(COMPLETELY_SEL).hasClass(NORMAL_SCROLL); + + //autoscrolling and not zooming? + if(options.autoScrolling && !controlPressed && !isNormalScroll){ + // cross-browser wheel delta + e = e || window.event; + var value = e.wheelDelta || -e.deltaY || -e.detail; + var delta = Math.max(-1, Math.min(1, value)); + + var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined'; + var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection); + + //Limiting the array to 150 (lets not waste memory!) + if(scrollings.length > 149){ + scrollings.shift(); + } + + //keeping record of the previous scrollings + scrollings.push(Math.abs(value)); + + //preventing to scroll the site on mouse wheel when scrollbar is present + if(options.scrollBar){ + e.preventDefault ? e.preventDefault() : e.returnValue = false; + } + + var activeSection = $(SECTION_ACTIVE_SEL); + var scrollable = options.scrollOverflowHandler.scrollable(activeSection); + + //time difference between the last scroll and the current one + var timeDiff = curTime-prevTime; + prevTime = curTime; + + //haven't they scrolled in a while? + //(enough to be consider a different scrolling action to scroll another section) + if(timeDiff > 200){ + //emptying the array, we dont care about old scrollings for our averages + scrollings = []; + } + + if(canScroll){ + var averageEnd = getAverage(scrollings, 10); + var averageMiddle = getAverage(scrollings, 70); + var isAccelerating = averageEnd >= averageMiddle; + + //to avoid double swipes... + if(isAccelerating && isScrollingVertically){ + //scrolling down? + if (delta < 0) { + scrolling('down', scrollable); + + //scrolling up? + }else { + scrolling('up', scrollable); + } + } + } + + return false; + } + + if(options.fitToSection){ + //stopping the auto scroll to adjust to a section + $htmlBody.stop(); + } + } + + /** + * Slides a slider to the given direction. + * Optional `section` param. + */ + function moveSlide(direction, section){ + var activeSection = typeof section === 'undefined' ? $(SECTION_ACTIVE_SEL) : section; + var slides = activeSection.find(SLIDES_WRAPPER_SEL); + var numSlides = slides.find(SLIDE_SEL).length; + + // more than one slide needed and nothing should be sliding + if (!slides.length || slideMoving || numSlides < 2) { + return; + } + + var currentSlide = slides.find(SLIDE_ACTIVE_SEL); + var destiny = null; + + if(direction === 'left'){ + destiny = currentSlide.prev(SLIDE_SEL); + }else{ + destiny = currentSlide.next(SLIDE_SEL); + } + + //isn't there a next slide in the secuence? + if(!destiny.length){ + //respect loopHorizontal settin + if (!options.loopHorizontal) return; + + if(direction === 'left'){ + destiny = currentSlide.siblings(':last'); + }else{ + destiny = currentSlide.siblings(':first'); + } + } + + slideMoving = true; + + landscapeScroll(slides, destiny, direction); + } + + /** + * Maintains the active slides in the viewport + * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical) + */ + function keepSlidesPosition(){ + $(SLIDE_ACTIVE_SEL).each(function(){ + silentLandscapeScroll($(this), 'internal'); + }); + } + + var previousDestTop = 0; + /** + * Returns the destination Y position based on the scrolling direction and + * the height of the section. + */ + function getDestinationPosition(element){ + var elemPosition = element.position(); + + //top of the desination will be at the top of the viewport + var position = elemPosition.top; + var isScrollingDown = elemPosition.top > previousDestTop; + var sectionBottom = position - windowsHeight + element.outerHeight(); + var bigSectionsDestination = options.bigSectionsDestination; + + //is the destination element bigger than the viewport? + if(element.outerHeight() > windowsHeight){ + //scrolling up? + if(!isScrollingDown && !bigSectionsDestination || bigSectionsDestination === 'bottom' ){ + position = sectionBottom; + } + } + + //sections equal or smaller than the viewport height && scrolling down? || is resizing and its in the last section + else if(isScrollingDown || (isResizing && element.is(':last-child')) ){ + //The bottom of the destination will be at the bottom of the viewport + position = sectionBottom; + } + + /* + Keeping record of the last scrolled position to determine the scrolling direction. + No conventional methods can be used as the scroll bar might not be present + AND the section might not be active if it is auto-height and didnt reach the middle + of the viewport. + */ + previousDestTop = position; + return position; + } + + /** + * Scrolls the site to the given element and scrolls to the slide if a callback is given. + */ + function scrollPage(element, callback, isMovementUp){ + if(typeof element === 'undefined'){ return; } //there's no element to scroll, leaving the function + + var dtop = getDestinationPosition(element); + var slideAnchorLink; + var slideIndex; + + //local variables + var v = { + element: element, + callback: callback, + isMovementUp: isMovementUp, + dtop: dtop, + yMovement: getYmovement(element), + anchorLink: element.data('anchor'), + sectionIndex: element.index(SECTION_SEL), + activeSlide: element.find(SLIDE_ACTIVE_SEL), + activeSection: $(SECTION_ACTIVE_SEL), + leavingSection: $(SECTION_ACTIVE_SEL).index(SECTION_SEL) + 1, + + //caching the value of isResizing at the momment the function is called + //because it will be checked later inside a setTimeout and the value might change + localIsResizing: isResizing + }; + + //quiting when destination scroll is the same as the current one + if((v.activeSection.is(element) && !isResizing) || (options.scrollBar && $window.scrollTop() === v.dtop && !element.hasClass(AUTO_HEIGHT) )){ return; } + + if(v.activeSlide.length){ + slideAnchorLink = v.activeSlide.data('anchor'); + slideIndex = v.activeSlide.index(); + } + + // If continuousVertical && we need to wrap around + if (options.autoScrolling && options.continuousVertical && typeof (v.isMovementUp) !== "undefined" && + ((!v.isMovementUp && v.yMovement == 'up') || // Intending to scroll down but about to go up or + (v.isMovementUp && v.yMovement == 'down'))) { // intending to scroll up but about to go down + + v = createInfiniteSections(v); + } + + //callback (onLeave) if the site is not just resizing and readjusting the slides + if($.isFunction(options.onLeave) && !v.localIsResizing){ + if(options.onLeave.call(v.activeSection, v.leavingSection, (v.sectionIndex + 1), v.yMovement) === false){ + return; + } + } + + stopMedia(v.activeSection); + + options.scrollOverflowHandler.beforeLeave(); + element.addClass(ACTIVE).siblings().removeClass(ACTIVE); + lazyLoad(element); + options.scrollOverflowHandler.onLeave(); + + + //preventing from activating the MouseWheelHandler event + //more than once if the page is scrolling + canScroll = false; + + setState(slideIndex, slideAnchorLink, v.anchorLink, v.sectionIndex); + + performMovement(v); + + //flag to avoid callingn `scrollPage()` twice in case of using anchor links + lastScrolledDestiny = v.anchorLink; + + //avoid firing it twice (as it does also on scroll) + activateMenuAndNav(v.anchorLink, v.sectionIndex); + // DONGND: add function for element have parent with class 'wrapper' + if(element.parent().hasClass('wrapper')) + { + element.addClass(ACTIVE).siblings().removeClass(ACTIVE); + element.siblings().find('.active').removeClass(ACTIVE); + element.parent().siblings().removeClass(ACTIVE); + element.parent().siblings().children('.fp-section').removeClass(ACTIVE); + } + + } + + /** + * Performs the vertical movement (by CSS3 or by jQuery) + */ + function performMovement(v){ + // using CSS3 translate functionality + if (options.css3 && options.autoScrolling && !options.scrollBar) { + + // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 + // that's why we round it to 0. + var translate3d = 'translate3d(0px, -' + Math.round(v.dtop) + 'px, 0px)'; + transformContainer(translate3d, true); + + //even when the scrollingSpeed is 0 there's a little delay, which might cause the + //scrollingSpeed to change in case of using silentMoveTo(); + if(options.scrollingSpeed){ + clearTimeout(afterSectionLoadsId); + afterSectionLoadsId = setTimeout(function () { + afterSectionLoads(v); + }, options.scrollingSpeed); + }else{ + afterSectionLoads(v); + } + } + + // using jQuery animate + else{ + var scrollSettings = getScrollSettings(v); + + $(scrollSettings.element).animate( + scrollSettings.options, + options.scrollingSpeed, options.easing).promise().done(function () { //only one single callback in case of animating `html, body` + if(options.scrollBar){ + + /* Hack! + The timeout prevents setting the most dominant section in the viewport as "active" when the user + scrolled to a smaller section by using the mousewheel (auto scrolling) rather than draging the scroll bar. + + When using scrollBar:true It seems like the scroll events still getting propagated even after the scrolling animation has finished. + */ + setTimeout(function(){ + afterSectionLoads(v); + },30); + }else{ + afterSectionLoads(v); + } + }); + } + } + + /** + * Gets the scrolling settings depending on the plugin autoScrolling option + */ + function getScrollSettings(v){ + var scroll = {}; + + if(options.autoScrolling && !options.scrollBar){ + scroll.options = { 'top': -v.dtop}; + scroll.element = WRAPPER_SEL; + }else{ + scroll.options = { 'scrollTop': v.dtop}; + scroll.element = 'html, body'; + } + + return scroll; + } + + /** + * Adds sections before or after the current one to create the infinite effect. + */ + function createInfiniteSections(v){ + // Scrolling down + if (!v.isMovementUp) { + // Move all previous sections to after the active section + $(SECTION_ACTIVE_SEL).after(v.activeSection.prevAll(SECTION_SEL).get().reverse()); + } + else { // Scrolling up + // Move all next sections to before the active section + $(SECTION_ACTIVE_SEL).before(v.activeSection.nextAll(SECTION_SEL)); + } + + // Maintain the displayed position (now that we changed the element order) + silentScroll($(SECTION_ACTIVE_SEL).position().top); + + // Maintain the active slides visible in the viewport + keepSlidesPosition(); + + // save for later the elements that still need to be reordered + v.wrapAroundElements = v.activeSection; + + // Recalculate animation variables + v.dtop = v.element.position().top; + v.yMovement = getYmovement(v.element); + + return v; + } + + /** + * Fix section order after continuousVertical changes have been animated + */ + function continuousVerticalFixSectionOrder (v) { + // If continuousVertical is in effect (and autoScrolling would also be in effect then), + // finish moving the elements around so the direct navigation will function more simply + if (!v.wrapAroundElements || !v.wrapAroundElements.length) { + return; + } + + if (v.isMovementUp) { + $(SECTION_FIRST_SEL).before(v.wrapAroundElements); + } + else { + $(SECTION_LAST_SEL).after(v.wrapAroundElements); + } + + silentScroll($(SECTION_ACTIVE_SEL).position().top); + + // Maintain the active slides visible in the viewport + keepSlidesPosition(); + } + + + /** + * Actions to do once the section is loaded. + */ + function afterSectionLoads (v){ + continuousVerticalFixSectionOrder(v); + + //callback (afterLoad) if the site is not just resizing and readjusting the slides + $.isFunction(options.afterLoad) && !v.localIsResizing && options.afterLoad.call(v.element, v.anchorLink, (v.sectionIndex + 1)); + options.scrollOverflowHandler.afterLoad(); + + playMedia(v.element); + v.element.addClass(COMPLETELY).siblings().removeClass(COMPLETELY); + + canScroll = true; + + $.isFunction(v.callback) && v.callback.call(this); + } + + /** + * Lazy loads image, video and audio elements. + */ + function lazyLoad(destiny){ + if (!options.lazyLoading){ + return; + } + + var panel = getSlideOrSection(destiny); + var element; + + panel.find('img[data-src], source[data-src], audio[data-src], iframe[data-src]').each(function(){ + element = $(this); + element.attr('src', element.data('src')); + element.removeAttr('data-src'); + + if(element.is('source')){ + element.closest('video').get(0).load(); + } + }); + } + + /** + * Plays video and audio elements. + */ + function playMedia(destiny){ + var panel = getSlideOrSection(destiny); + + //playing HTML5 media elements + panel.find('video, audio').each(function(){ + var element = $(this).get(0); + + if( element.hasAttribute('data-autoplay') && typeof element.play === 'function' ) { + element.play(); + } + }); + + //youtube videos + panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ + var element = $(this).get(0); + + if ( element.hasAttribute('data-autoplay') ){ + playYoutube(element); + } + + //in case the URL was not loaded yet. On page load we need time for the new URL (with the API string) to load. + element.onload = function() { + if ( element.hasAttribute('data-autoplay') ){ + playYoutube(element); + } + }; + }); + } + + /** + * Plays a youtube video + */ + function playYoutube(element){ + element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*'); + } + + /** + * Stops video and audio elements. + */ + function stopMedia(destiny){ + var panel = getSlideOrSection(destiny); + + //stopping HTML5 media elements + panel.find('video, audio').each(function(){ + var element = $(this).get(0); + + if( !element.hasAttribute('data-keepplaying') && typeof element.pause === 'function' ) { + element.pause(); + } + }); + + //youtube videos + panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ + var element = $(this).get(0); + + if( /youtube\.com\/embed\//.test($(this).attr('src')) && !element.hasAttribute('data-keepplaying')){ + $(this).get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*'); + } + }); + } + + /** + * Gets the active slide (or section) for the given section + */ + function getSlideOrSection(destiny){ + var slide = destiny.find(SLIDE_ACTIVE_SEL); + if( slide.length ) { + destiny = $(slide); + } + + return destiny; + } + + /** + * Scrolls to the anchor in the URL when loading the site + */ + function scrollToAnchor(){ + //getting the anchor link in the URL and deleting the `#` + var value = window.location.hash.replace('#', '').split('/'); + var sectionAnchor = decodeURIComponent(value[0]); + var slideAnchor = decodeURIComponent(value[1]); + + if(sectionAnchor){ //if theres any # + if(options.animateAnchor){ + scrollPageAndSlide(sectionAnchor, slideAnchor); + }else{ + silentMoveTo(sectionAnchor, slideAnchor); + } + } + } + + /** + * Detecting any change on the URL to scroll to the given anchor link + * (a way to detect back history button as we play with the hashes on the URL) + */ + function hashChangeHandler(){ + if(!isScrolling && !options.lockAnchors){ + var value = window.location.hash.replace('#', '').split('/'); + var sectionAnchor = decodeURIComponent(value[0]); + var slideAnchor = decodeURIComponent(value[1]); + + //when moving to a slide in the first section for the first time (first time to add an anchor to the URL) + var isFirstSlideMove = (typeof lastScrolledDestiny === 'undefined'); + var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' && typeof slideAnchor === 'undefined' && !slideMoving); + + + if(sectionAnchor.length){ + /*in order to call scrollpage() only once for each destination at a time + It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange` + event is fired on every scroll too.*/ + if ((sectionAnchor && sectionAnchor !== lastScrolledDestiny) && !isFirstSlideMove || isFirstScrollMove || (!slideMoving && lastScrolledSlide != slideAnchor )) { + scrollPageAndSlide(sectionAnchor, slideAnchor); + } + } + } + } + + //Sliding with arrow keys, both, vertical and horizontal + function keydownHandler(e) { + + clearTimeout(keydownId); + + var activeElement = $(':focus'); + + if(!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select') && + activeElement.attr('contentEditable') !== "true" && activeElement.attr('contentEditable') !== '' && + options.keyboardScrolling && options.autoScrolling){ + var keyCode = e.which; + + //preventing the scroll with arrow keys & spacebar & Page Up & Down keys + var keyControls = [40, 38, 32, 33, 34]; + if($.inArray(keyCode, keyControls) > -1){ + e.preventDefault(); + } + + controlPressed = e.ctrlKey; + + keydownId = setTimeout(function(){ + onkeydown(e); + },150); + } + } + + function tooltipTextHandler(){ + $(this).prev().trigger('click'); + } + + //to prevent scrolling while zooming + function keyUpHandler(e){ + if(isWindowFocused){ //the keyup gets fired on new tab ctrl + t in Firefox + controlPressed = e.ctrlKey; + } + } + + //binding the mousemove when the mouse's middle button is released + function mouseDownHandler(e){ + //middle button + if (e.which == 2){ + oldPageY = e.pageY; + container.on('mousemove', mouseMoveHandler); + } + } + + //unbinding the mousemove when the mouse's middle button is released + function mouseUpHandler(e){ + //middle button + if (e.which == 2){ + container.off('mousemove'); + } + } + + //Scrolling horizontally when clicking on the slider controls. + function slideArrowHandler(){ + var section = $(this).closest(SECTION_SEL); + + if ($(this).hasClass(SLIDES_PREV)) { + if(isScrollAllowed.m.left){ + moveSlideLeft(section); + } + } else { + if(isScrollAllowed.m.right){ + moveSlideRight(section); + } + } + } + + //when opening a new tab (ctrl + t), `control` won't be pressed when comming back. + function blurHandler(){ + isWindowFocused = false; + controlPressed = false; + } + + //Scrolls to the section when clicking the navigation bullet + function sectionBulletHandler(e){ + e.preventDefault(); + var index = $(this).parent().index(); + scrollPage($(SECTION_SEL).eq(index)); + } + + //Scrolls the slider to the given slide destination for the given section + function slideBulletHandler(e){ + e.preventDefault(); + var slides = $(this).closest(SECTION_SEL).find(SLIDES_WRAPPER_SEL); + var destiny = slides.find(SLIDE_SEL).eq($(this).closest('li').index()); + + landscapeScroll(slides, destiny); + } + + /** + * Keydown event + */ + function onkeydown(e){ + var shiftPressed = e.shiftKey; + + switch (e.which) { + //up + case 38: + case 33: + if(isScrollAllowed.k.up){ + moveSectionUp(); + } + break; + + //down + case 32: //spacebar + if(shiftPressed && isScrollAllowed.k.up){ + moveSectionUp(); + break; + } + /* falls through */ + case 40: + case 34: + if(isScrollAllowed.k.down){ + moveSectionDown(); + } + break; + + //Home + case 36: + if(isScrollAllowed.k.up){ + moveTo(1); + } + break; + + //End + case 35: + if(isScrollAllowed.k.down){ + moveTo( $(SECTION_SEL).length ); + } + break; + + //left + case 37: + if(isScrollAllowed.k.left){ + moveSlideLeft(); + } + break; + + //right + case 39: + if(isScrollAllowed.k.right){ + moveSlideRight(); + } + break; + + default: + return; // exit this handler for other keys + } + } + + /** + * Detecting the direction of the mouse movement. + * Used only for the middle button of the mouse. + */ + var oldPageY = 0; + function mouseMoveHandler(e){ + if(canScroll){ + // moving up + if (e.pageY < oldPageY && isScrollAllowed.m.up){ + moveSectionUp(); + } + + // moving down + else if(e.pageY > oldPageY && isScrollAllowed.m.down){ + moveSectionDown(); + } + } + oldPageY = e.pageY; + } + + /** + * Scrolls horizontal sliders. + */ + function landscapeScroll(slides, destiny, direction){ + var section = slides.closest(SECTION_SEL); + var v = { + slides: slides, + destiny: destiny, + direction: direction, + destinyPos: destiny.position(), + slideIndex: destiny.index(), + section: section, + sectionIndex: section.index(SECTION_SEL), + anchorLink: section.data('anchor'), + slidesNav: section.find(SLIDES_NAV_SEL), + slideAnchor: getAnchor(destiny), + prevSlide: section.find(SLIDE_ACTIVE_SEL), + prevSlideIndex: section.find(SLIDE_ACTIVE_SEL).index(), + + //caching the value of isResizing at the momment the function is called + //because it will be checked later inside a setTimeout and the value might change + localIsResizing: isResizing + }; + v.xMovement = getXmovement(v.prevSlideIndex, v.slideIndex); + + //important!! Only do it when not resizing + if(!v.localIsResizing){ + //preventing from scrolling to the next/prev section when using scrollHorizontally + canScroll = false; + } + + if(options.onSlideLeave){ + + //if the site is not just resizing and readjusting the slides + if(!v.localIsResizing && v.xMovement!=='none'){ + if($.isFunction( options.onSlideLeave )){ + if(options.onSlideLeave.call( v.prevSlide, v.anchorLink, (v.sectionIndex + 1), v.prevSlideIndex, v.xMovement, v.slideIndex ) === false){ + slideMoving = false; + return; + } + } + } + } + + destiny.addClass(ACTIVE).siblings().removeClass(ACTIVE); + + if(!v.localIsResizing){ + stopMedia(v.prevSlide); + lazyLoad(destiny); + } + + if(!options.loopHorizontal && options.controlArrows){ + //hidding it for the fist slide, showing for the rest + section.find(SLIDES_ARROW_PREV_SEL).toggle(v.slideIndex!==0); + + //hidding it for the last slide, showing for the rest + section.find(SLIDES_ARROW_NEXT_SEL).toggle(!destiny.is(':last-child')); + } + + //only changing the URL if the slides are in the current section (not for resize re-adjusting) + if(section.hasClass(ACTIVE)){ + setState(v.slideIndex, v.slideAnchor, v.anchorLink, v.sectionIndex); + } + + performHorizontalMove(slides, v, true); + } + + + function afterSlideLoads(v){ + activeSlidesNavigation(v.slidesNav, v.slideIndex); + + //if the site is not just resizing and readjusting the slides + if(!v.localIsResizing){ + $.isFunction( options.afterSlideLoad ) && options.afterSlideLoad.call( v.destiny, v.anchorLink, (v.sectionIndex + 1), v.slideAnchor, v.slideIndex); + + //needs to be inside the condition to prevent problems with continuousVertical and scrollHorizontally + //and to prevent double scroll right after a windows resize + canScroll = true; + } + + playMedia(v.destiny); + + //letting them slide again + slideMoving = false; + } + + /** + * Performs the horizontal movement. (CSS3 or jQuery) + * + * @param fireCallback {Bool} - determines whether or not to fire the callback + */ + function performHorizontalMove(slides, v, fireCallback){ + var destinyPos = v.destinyPos; + + if(options.css3){ + var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)'; + + addAnimation(slides.find(SLIDES_CONTAINER_SEL)).css(getTransforms(translate3d)); + + afterSlideLoadsId = setTimeout(function(){ + fireCallback && afterSlideLoads(v); + }, options.scrollingSpeed, options.easing); + }else{ + slides.animate({ + scrollLeft : Math.round(destinyPos.left) + }, options.scrollingSpeed, options.easing, function() { + + fireCallback && afterSlideLoads(v); + }); + } + } + + /** + * Sets the state for the horizontal bullet navigations. + */ + function activeSlidesNavigation(slidesNav, slideIndex){ + slidesNav.find(ACTIVE_SEL).removeClass(ACTIVE); + slidesNav.find('li').eq(slideIndex).find('a').addClass(ACTIVE); + } + + var previousHeight = windowsHeight; + + //when resizing the site, we adjust the heights of the sections, slimScroll... + function resizeHandler(){ + //checking if it needs to get responsive + responsive(); + + // rebuild immediately on touch devices + if (isTouchDevice) { + var activeElement = $(document.activeElement); + + //if the keyboard is NOT visible + if (!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select')) { + var currentHeight = $window.height(); + + //making sure the change in the viewport size is enough to force a rebuild. (20 % of the window to avoid problems when hidding scroll bars) + if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){ + reBuild(true); + previousHeight = currentHeight; + } + } + }else{ + //in order to call the functions only when the resize is finished + //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing + clearTimeout(resizeId); + + resizeId = setTimeout(function(){ + reBuild(true); + }, 350); + } + } + + /** + * Checks if the site needs to get responsive and disables autoScrolling if so. + * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS. + */ + function responsive(){ + var widthLimit = options.responsive || options.responsiveWidth; //backwards compatiblity + var heightLimit = options.responsiveHeight; + + //only calculating what we need. Remember its called on the resize event. + var isBreakingPointWidth = widthLimit && $window.outerWidth() < widthLimit; + var isBreakingPointHeight = heightLimit && $window.height() < heightLimit; + + if(widthLimit && heightLimit){ + setResponsive(isBreakingPointWidth || isBreakingPointHeight); + } + else if(widthLimit){ + setResponsive(isBreakingPointWidth); + } + else if(heightLimit){ + setResponsive(isBreakingPointHeight); + } + } + + /** + * Adds transition animations for the given element + */ + function addAnimation(element){ + var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3; + + element.removeClass(NO_TRANSITION); + return element.css({ + '-webkit-transition': transition, + 'transition': transition + }); + } + + /** + * Remove transition animations for the given element + */ + function removeAnimation(element){ + return element.addClass(NO_TRANSITION); + } + + /** + * Activating the vertical navigation bullets according to the given slide name. + */ + function activateNavDots(name, sectionIndex){ + if(options.navigation){ + $(SECTION_NAV_SEL).find(ACTIVE_SEL).removeClass(ACTIVE); + if(name){ + $(SECTION_NAV_SEL).find('a[href="#' + name + '"]').addClass(ACTIVE); + }else{ + $(SECTION_NAV_SEL).find('li').eq(sectionIndex).find('a').addClass(ACTIVE); + } + } + } + + /** + * Activating the website main menu elements according to the given slide name. + */ + function activateMenuElement(name){ + if(options.menu){ + $(options.menu).find(ACTIVE_SEL).removeClass(ACTIVE); + $(options.menu).find('[data-menuanchor="'+name+'"]').addClass(ACTIVE); + } + } + + /** + * Sets to active the current menu and vertical nav items. + */ + function activateMenuAndNav(anchor, index){ + activateMenuElement(anchor); + activateNavDots(anchor, index); + } + + /** + * Retuns `up` or `down` depending on the scrolling movement to reach its destination + * from the current section. + */ + function getYmovement(destiny){ + var fromIndex = $(SECTION_ACTIVE_SEL).index(SECTION_SEL); + var toIndex = destiny.index(SECTION_SEL); + if( fromIndex == toIndex){ + return 'none'; + } + if(fromIndex > toIndex){ + return 'up'; + } + return 'down'; + } + + /** + * Retuns `right` or `left` depending on the scrolling movement to reach its destination + * from the current slide. + */ + function getXmovement(fromIndex, toIndex){ + if( fromIndex == toIndex){ + return 'none'; + } + if(fromIndex > toIndex){ + return 'left'; + } + return 'right'; + } + + /** + * Checks if the element needs scrollbar and if the user wants to apply it. + * If so it creates it. + * + * @param {Object} element jQuery object of the section or slide + */ + function createScrollBar(element){ + //User doesn't want scrollbar here? Sayonara baby! + if(element.hasClass('fp-noscroll')) return; + + //needed to make `scrollHeight` work under Opera 12 + element.css('overflow', 'hidden'); + + var scrollOverflowHandler = options.scrollOverflowHandler; + var wrap = scrollOverflowHandler.wrapContent(); + //in case element is a slide + var section = element.closest(SECTION_SEL); + var scrollable = scrollOverflowHandler.scrollable(element); + var contentHeight; + + //if there was scroll, the contentHeight will be the one in the scrollable section + if(scrollable.length){ + contentHeight = scrollOverflowHandler.scrollHeight(element); + }else{ + contentHeight = element.get(0).scrollHeight; + if(options.verticalCentered){ + contentHeight = element.find(TABLE_CELL_SEL).get(0).scrollHeight; + } + } + + var scrollHeight = windowsHeight - parseInt(section.css('padding-bottom')) - parseInt(section.css('padding-top')); + + //needs scroll? + if ( contentHeight > scrollHeight) { + //did we already have an scrollbar ? Updating it + if(scrollable.length){ + scrollOverflowHandler.update(element, scrollHeight); + } + //creating the scrolling + else{ + if(options.verticalCentered){ + element.find(TABLE_CELL_SEL).wrapInner(wrap); + }else{ + element.wrapInner(wrap); + } + scrollOverflowHandler.create(element, scrollHeight); + } + } + //removing the scrolling when it is not necessary anymore + else{ + scrollOverflowHandler.remove(element); + } + + //undo + element.css('overflow', ''); + } + + function addTableClass(element){ + //In case we are styling for the 2nd time as in with reponsiveSlides + if(!element.hasClass(TABLE)){ + element.addClass(TABLE).wrapInner('
      '); + } + } + + function getTableHeight(element){ + var sectionHeight = windowsHeight; + + if(options.paddingTop || options.paddingBottom){ + var section = element; + if(!section.hasClass(SECTION)){ + section = element.closest(SECTION_SEL); + } + + var paddings = parseInt(section.css('padding-top')) + parseInt(section.css('padding-bottom')); + sectionHeight = (windowsHeight - paddings); + } + + return sectionHeight; + } + + /** + * Adds a css3 transform property to the container class with or without animation depending on the animated param. + */ + function transformContainer(translate3d, animated){ + if(animated){ + addAnimation(container); + }else{ + removeAnimation(container); + } + + container.css(getTransforms(translate3d)); + + //syncronously removing the class after the animation has been applied. + setTimeout(function(){ + container.removeClass(NO_TRANSITION); + },10); + } + + /** + * Gets a section by its anchor / index + */ + function getSectionByAnchor(sectionAnchor){ + //section + var section = container.find(SECTION_SEL + '[data-anchor="'+sectionAnchor+'"]'); + if(!section.length){ + section = $(SECTION_SEL).eq( (sectionAnchor -1) ); + } + + return section; + } + + /** + * Gets a slide inside a given section by its anchor / index + */ + function getSlideByAnchor(slideAnchor, section){ + var slides = section.find(SLIDES_WRAPPER_SEL); + var slide = slides.find(SLIDE_SEL + '[data-anchor="'+slideAnchor+'"]'); + + if(!slide.length){ + slide = slides.find(SLIDE_SEL).eq(slideAnchor); + } + + return slide; + } + + /** + * Scrolls to the given section and slide anchors + */ + function scrollPageAndSlide(destiny, slide){ + var section = getSectionByAnchor(destiny); + + //do nothing if there's no section with the given anchor name + if(!section.length) return; + + //default slide + if (typeof slide === 'undefined') { + slide = 0; + } + + //we need to scroll to the section and then to the slide + if (destiny !== lastScrolledDestiny && !section.hasClass(ACTIVE)){ + scrollPage(section, function(){ + scrollSlider(section, slide); + }); + } + //if we were already in the section + else{ + scrollSlider(section, slide); + } + } + + /** + * Scrolls the slider to the given slide destination for the given section + */ + function scrollSlider(section, slideAnchor){ + if(typeof slideAnchor !== 'undefined'){ + var slides = section.find(SLIDES_WRAPPER_SEL); + var destiny = getSlideByAnchor(slideAnchor, section); + + if(destiny.length){ + landscapeScroll(slides, destiny); + } + } + } + + /** + * Creates a landscape navigation bar with dots for horizontal sliders. + */ + function addSlidesNavigation(section, numSlides){ + section.append('
        '); + var nav = section.find(SLIDES_NAV_SEL); + + //top or bottom + nav.addClass(options.slidesNavPosition); + + for(var i=0; i< numSlides; i++){ + nav.find('ul').append('
      • '); + } + + //centering it + nav.css('margin-left', '-' + (nav.width()/2) + 'px'); + + nav.find('li').first().find('a').addClass(ACTIVE); + } + + + /** + * Sets the state of the website depending on the active section/slide. + * It changes the URL hash when needed and updates the body class. + */ + function setState(slideIndex, slideAnchor, anchorLink, sectionIndex){ + var sectionHash = ''; + + if(options.anchors.length && !options.lockAnchors){ + + //isn't it the first slide? + if(slideIndex){ + if(typeof anchorLink !== 'undefined'){ + sectionHash = anchorLink; + } + + //slide without anchor link? We take the index instead. + if(typeof slideAnchor === 'undefined'){ + slideAnchor = slideIndex; + } + + lastScrolledSlide = slideAnchor; + setUrlHash(sectionHash + '/' + slideAnchor); + + //first slide won't have slide anchor, just the section one + }else if(typeof slideIndex !== 'undefined'){ + lastScrolledSlide = slideAnchor; + setUrlHash(anchorLink); + } + + //section without slides + else{ + setUrlHash(anchorLink); + } + } + + setBodyClass(); + } + + /** + * Sets the URL hash. + */ + function setUrlHash(url){ + if(options.recordHistory){ + location.hash = url; + }else{ + //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :) + if(isTouchDevice || isTouch){ + window.history.replaceState(undefined, undefined, '#' + url); + }else{ + var baseUrl = window.location.href.split('#')[0]; + window.location.replace( baseUrl + '#' + url ); + } + } + } + + /** + * Gets the anchor for the given slide / section. Its index will be used if there's none. + */ + function getAnchor(element){ + var anchor = element.data('anchor'); + var index = element.index(); + + //Slide without anchor link? We take the index instead. + if(typeof anchor === 'undefined'){ + anchor = index; + } + + return anchor; + } + + /** + * Sets a class for the body of the page depending on the active section / slide + */ + function setBodyClass(){ + var section = $(SECTION_ACTIVE_SEL); + var slide = section.find(SLIDE_ACTIVE_SEL); + + var sectionAnchor = getAnchor(section); + var slideAnchor = getAnchor(slide); + + var text = String(sectionAnchor); + + if(slide.length){ + text = text + '-' + slideAnchor; + } + + //changing slash for dash to make it a valid CSS style + text = text.replace('/', '-').replace('#',''); + + //removing previous anchor classes + var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g"); + $body[0].className = $body[0].className.replace(classRe, ''); + + //adding the current anchor + $body.addClass(VIEWING_PREFIX + '-' + text); + } + + /** + * Checks for translate3d support + * @return boolean + * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support + */ + function support3d() { + var el = document.createElement('p'), + has3d, + transforms = { + 'webkitTransform':'-webkit-transform', + 'OTransform':'-o-transform', + 'msTransform':'-ms-transform', + 'MozTransform':'-moz-transform', + 'transform':'transform' + }; + + // Add it to the body to get the computed style. + document.body.insertBefore(el, null); + + for (var t in transforms) { + if (el.style[t] !== undefined) { + el.style[t] = 'translate3d(1px,1px,1px)'; + has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]); + } + } + + document.body.removeChild(el); + + return (has3d !== undefined && has3d.length > 0 && has3d !== 'none'); + } + + /** + * Removes the auto scrolling action fired by the mouse wheel and trackpad. + * After this function is called, the mousewheel and trackpad movements won't scroll through sections. + */ + function removeMouseWheelHandler(){ + if (document.addEventListener) { + document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper + document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox + document.removeEventListener('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox + } else { + document.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8 + } + } + + /** + * Adds the auto scrolling action for the mouse wheel and trackpad. + * After this function is called, the mousewheel and trackpad movements will scroll through sections + * https://developer.mozilla.org/en-US/docs/Web/Events/wheel + */ + function addMouseWheelHandler(){ + var prefix = ''; + var _addEventListener; + + if (window.addEventListener){ + _addEventListener = "addEventListener"; + }else{ + _addEventListener = "attachEvent"; + prefix = 'on'; + } + + // detect available wheel event + var support = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel" + document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel" + 'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox + + + if(support == 'DOMMouseScroll'){ + document[ _addEventListener ](prefix + 'MozMousePixelScroll', MouseWheelHandler, false); + } + + //handle MozMousePixelScroll in older Firefox + else{ + document[ _addEventListener ](prefix + support, MouseWheelHandler, false); + } + } + + /** + * Binding the mousemove when the mouse's middle button is pressed + */ + function addMiddleWheelHandler(){ + container + .on('mousedown', mouseDownHandler) + .on('mouseup', mouseUpHandler); + } + + /** + * Unbinding the mousemove when the mouse's middle button is released + */ + function removeMiddleWheelHandler(){ + container + .off('mousedown', mouseDownHandler) + .off('mouseup', mouseUpHandler); + } + + /** + * Adds the possibility to auto scroll through sections on touch devices. + */ + function addTouchHandler(){ + if(options.autoScrolling && (isTouchDevice || isTouch)){ + //Microsoft pointers + var MSPointer = getMSPointer(); + + $body.off('touchmove ' + MSPointer.move).on('touchmove ' + MSPointer.move, preventBouncing); + + $(WRAPPER_SEL) + .off('touchstart ' + MSPointer.down).on('touchstart ' + MSPointer.down, touchStartHandler) + .off('touchmove ' + MSPointer.move).on('touchmove ' + MSPointer.move, touchMoveHandler); + } + } + + /** + * Removes the auto scrolling for touch devices. + */ + function removeTouchHandler(){ + if(isTouchDevice || isTouch){ + //Microsoft pointers + var MSPointer = getMSPointer(); + + $(WRAPPER_SEL) + .off('touchstart ' + MSPointer.down) + .off('touchmove ' + MSPointer.move); + } + } + + /* + * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11) + * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx + */ + function getMSPointer(){ + var pointer; + + //IE >= 11 & rest of browsers + if(window.PointerEvent){ + pointer = { down: 'pointerdown', move: 'pointermove'}; + } + + //IE < 11 + else{ + pointer = { down: 'MSPointerDown', move: 'MSPointerMove'}; + } + + return pointer; + } + + /** + * Gets the pageX and pageY properties depending on the browser. + * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854 + */ + function getEventsPage(e){ + var events = []; + + events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY); + events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX); + + //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008 + if(isTouch && isReallyTouch(e) && options.scrollBar){ + events.y = e.touches[0].pageY; + events.x = e.touches[0].pageX; + } + + return events; + } + + /** + * Slides silently (with no animation) the active slider to the given slide. + * @param noCallback {bool} true or defined -> no callbacks + */ + function silentLandscapeScroll(activeSlide, noCallbacks){ + setScrollingSpeed (0, 'internal'); + + if(typeof noCallbacks !== 'undefined'){ + //preventing firing callbacks afterSlideLoad etc. + isResizing = true; + } + + landscapeScroll(activeSlide.closest(SLIDES_WRAPPER_SEL), activeSlide); + + if(typeof noCallbacks !== 'undefined'){ + isResizing = false; + } + + setScrollingSpeed(originals.scrollingSpeed, 'internal'); + } + + /** + * Scrolls silently (with no animation) the page to the given Y position. + */ + function silentScroll(top){ + // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 + // that's why we round it to 0. + var roundedTop = Math.round(top); + + if(options.scrollBar){ + container.scrollTop(roundedTop); + } + else if (options.css3) { + var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)'; + transformContainer(translate3d, false); + } + else { + container.css('top', -roundedTop); + } + } + + /** + * Returns the cross-browser transform string. + */ + function getTransforms(translate3d){ + return { + '-webkit-transform': translate3d, + '-moz-transform': translate3d, + '-ms-transform':translate3d, + 'transform': translate3d + }; + } + + /** + * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard) + * @type m (mouse) or k (keyboard) + */ + function setIsScrollAllowed(value, direction, type){ + switch (direction){ + case 'up': isScrollAllowed[type].up = value; break; + case 'down': isScrollAllowed[type].down = value; break; + case 'left': isScrollAllowed[type].left = value; break; + case 'right': isScrollAllowed[type].right = value; break; + case 'all': + if(type == 'm'){ + setAllowScrolling(value); + }else{ + setKeyboardScrolling(value); + } + } + } + + /* + * Destroys fullpage.js plugin events and optinally its html markup and styles + */ + function destroy(all){ + setAutoScrolling(false, 'internal'); + setAllowScrolling(false); + setKeyboardScrolling(false); + container.addClass(DESTROYED); + + clearTimeout(afterSlideLoadsId); + clearTimeout(afterSectionLoadsId); + clearTimeout(resizeId); + clearTimeout(scrollId); + clearTimeout(scrollId2); + + $window + .off('scroll', scrollHandler) + .off('hashchange', hashChangeHandler) + .off('resize', resizeHandler); + + $document + .off('click touchstart', SECTION_NAV_SEL + ' a') + .off('mouseenter', SECTION_NAV_SEL + ' li') + .off('mouseleave', SECTION_NAV_SEL + ' li') + .off('click touchstart', SLIDES_NAV_LINK_SEL) + .off('mouseover', options.normalScrollElements) + .off('mouseout', options.normalScrollElements); + + $(SECTION_SEL) + .off('click touchstart', SLIDES_ARROW_SEL); + + clearTimeout(afterSlideLoadsId); + clearTimeout(afterSectionLoadsId); + + //lets make a mess! + if(all){ + destroyStructure(); + } + } + + + /* + * Removes inline styles added by fullpage.js + */ + function destroyStructure(){ + //reseting the `top` or `translate` properties to 0 + silentScroll(0); + + //loading all the lazy load content + container.find('img[data-src], source[data-src], audio[data-src], iframe[data-src]').each(function(){ + $(this).attr('src', $(this).data('src')); + $(this).removeAttr('data-src'); + }); + + $(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL + ', ' + SLIDES_ARROW_SEL).remove(); + + //removing inline styles + $(SECTION_SEL).css( { + 'height': '', + 'background-color' : '', + 'padding': '' + }); + + $(SLIDE_SEL).css( { + 'width': '' + }); + + container.css({ + 'height': '', + 'position': '', + '-ms-touch-action': '', + 'touch-action': '' + }); + + $htmlBody.css({ + 'overflow': '', + 'height': '' + }); + + // remove .fp-enabled class + $('html').removeClass(ENABLED); + + // remove .fp-responsive class + $body.removeClass(RESPONSIVE); + + // remove all of the .fp-viewing- classes + $.each($body.get(0).className.split(/\s+/), function (index, className) { + if (className.indexOf(VIEWING_PREFIX) === 0) { + $body.removeClass(className); + } + }); + + //removing added classes + $(SECTION_SEL + ', ' + SLIDE_SEL).each(function(){ + options.scrollOverflowHandler.remove($(this)); + $(this).removeClass(TABLE + ' ' + ACTIVE); + }); + + removeAnimation(container); + + //Unwrapping content + container.find(TABLE_CELL_SEL + ', ' + SLIDES_CONTAINER_SEL + ', ' + SLIDES_WRAPPER_SEL).each(function(){ + //unwrap not being use in case there's no child element inside and its just text + $(this).replaceWith(this.childNodes); + }); + + //scrolling the page to the top with no animation + $htmlBody.scrollTop(0); + + //removing selectors + var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER]; + $.each(usedSelectors, function(index, value){ + $('.' + value).removeClass(value); + }); + } + + /* + * Sets the state for a variable with multiple states (original, and temporal) + * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`. + * This function is used to keep track of both states, the original and the temporal one. + * If type is not 'internal', then we assume the user is globally changing the variable. + */ + function setVariableState(variable, value, type){ + options[variable] = value; + if(type !== 'internal'){ + originals[variable] = value; + } + } + + /** + * Displays warnings + */ + function displayWarnings(){ + var extensions = ['fadingEffect', 'continuousHorizontal', 'scrollHorizontally', 'interlockedSlides', 'resetSliders', 'responsiveSlides']; + if($('html').hasClass(ENABLED)){ + showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!'); + return; + } + + // Disable mutually exclusive settings + if (options.continuousVertical && + (options.loopTop || options.loopBottom)) { + options.continuousVertical = false; + showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); + } + + if(options.scrollBar && options.scrollOverflow){ + showError('warn', 'Option `scrollBar` is mutually exclusive with `scrollOverflow`. Sections with scrollOverflow might not work well in Firefox'); + } + + if(options.continuousVertical && options.scrollBar){ + options.continuousVertical = false; + showError('warn', 'Option `scrollBar` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); + } + + //using extensions? Wrong file! + extensions.forEach(function(extension){ + //is the option set to true? + if(options[extension]){ + showError('warn', 'fullpage.js extensions require jquery.fullpage.extensions.min.js file instead of the usual jquery.fullpage.js. Requested: '+ extension); + } + }); + + //anchors can not have the same value as any element ID or NAME + $.each(options.anchors, function(index, name){ + + //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396) + var nameAttr = $document.find('[name]').filter(function() { + return $(this).attr('name') && $(this).attr('name').toLowerCase() == name.toLowerCase(); + }); + + var idAttr = $document.find('[id]').filter(function() { + return $(this).attr('id') && $(this).attr('id').toLowerCase() == name.toLowerCase(); + }); + + if(idAttr.length || nameAttr.length ){ + showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).'); + idAttr.length && showError('error', '"' + name + '" is is being used by another element `id` property'); + nameAttr.length && showError('error', '"' + name + '" is is being used by another element `name` property'); + } + }); + } + + /** + * Shows a message in the console of the given type. + */ + function showError(type, text){ + console && console[type] && console[type]('fullPage: ' + text); + } + + }; //end of $.fn.fullpage + + if(typeof IScroll !== 'undefined'){ + /* + * Turns iScroll `mousewheel` option off dynamically + * https://github.com/cubiq/iscroll/issues/1036 + */ + IScroll.prototype.wheelOn = function () { + this.wrapper.addEventListener('wheel', this); + this.wrapper.addEventListener('mousewheel', this); + this.wrapper.addEventListener('DOMMouseScroll', this); + }; + + /* + * Turns iScroll `mousewheel` option on dynamically + * https://github.com/cubiq/iscroll/issues/1036 + */ + IScroll.prototype.wheelOff = function () { + this.wrapper.removeEventListener('wheel', this); + this.wrapper.removeEventListener('mousewheel', this); + this.wrapper.removeEventListener('DOMMouseScroll', this); + }; + } + + /** + * An object to handle overflow scrolling. + * This uses jquery.slimScroll to accomplish overflow scrolling. + * It is possible to pass in an alternate scrollOverflowHandler + * to the fullpage.js option that implements the same functions + * as this handler. + * + * @type {Object} + */ + var iscrollHandler = { + refreshId: null, + iScrollInstances: [], + + /** + * Turns off iScroll for the destination section. + * When scrolling very fast on some trackpads (and Apple laptops) the inertial scrolling would + * scroll the destination section/slide before the sections animations ends. + */ + onLeave: function(){ + var scroller = $(SECTION_ACTIVE_SEL).find(SCROLLABLE_SEL).data('iscrollInstance'); + if(typeof scroller !== 'undefined' && scroller){ + scroller.wheelOff(); + } + }, + + // Turns off iScroll for the leaving section + beforeLeave: function(){ + iscrollHandler.onLeave() + }, + + // Turns on iScroll on section load + afterLoad: function(){ + var scroller = $(SECTION_ACTIVE_SEL).find(SCROLLABLE_SEL).data('iscrollInstance'); + if(typeof scroller !== 'undefined' && scroller){ + scroller.wheelOn(); + } + }, + + /** + * Called when overflow scrolling is needed for a section. + * + * @param {Object} element jQuery object containing current section + * @param {Number} scrollHeight Current window height in pixels + */ + create: function(element, scrollHeight) { + var scrollable = element.find(SCROLLABLE_SEL); + + scrollable.height(scrollHeight); + scrollable.each(function() { + var $this = jQuery(this); + var iScrollInstance = $this.data('iscrollInstance'); + if (iScrollInstance) { + $.each(iscrollHandler.iScrollInstances, function(){ + $(this).destroy(); + }); + } + + iScrollInstance = new IScroll($this.get(0), iscrollOptions); + iscrollHandler.iScrollInstances.push(iScrollInstance); + + //off by default until the section gets active + iScrollInstance.wheelOff(); + + $this.data('iscrollInstance', iScrollInstance); + }); + }, + + /** + * Return a boolean depending on whether the scrollable element is a + * the end or at the start of the scrolling depending on the given type. + * + * @param {String} type Either 'top' or 'bottom' + * @param {Object} scrollable jQuery object for the scrollable element + * @return {Boolean} + */ + isScrolled: function(type, scrollable) { + var scroller = scrollable.data('iscrollInstance'); + + //no scroller? + if (!scroller) { + return true; + } + + if (type === 'top') { + return scroller.y >= 0 && !scrollable.scrollTop(); + } else if (type === 'bottom') { + return (0 - scroller.y) + scrollable.scrollTop() + 1 + scrollable.innerHeight() >= scrollable[0].scrollHeight; + } + }, + + /** + * Returns the scrollable element for the given section. + * If there are landscape slides, will only return a scrollable element + * if it is in the active slide. + * + * @param {Object} activeSection jQuery object containing current section + * @return {Boolean} + */ + scrollable: function(activeSection){ + // if there are landscape slides, we check if the scrolling bar is in the current one or not + if (activeSection.find(SLIDES_WRAPPER_SEL).length) { + return activeSection.find(SLIDE_ACTIVE_SEL).find(SCROLLABLE_SEL); + } + return activeSection.find(SCROLLABLE_SEL); + }, + + /** + * Returns the scroll height of the wrapped content. + * If this is larger than the window height minus section padding, + * overflow scrolling is needed. + * + * @param {Object} element jQuery object containing current section + * @return {Number} + */ + scrollHeight: function(element) { + return element.find(SCROLLABLE_SEL).children().first().get(0).scrollHeight; + }, + + /** + * Called when overflow scrolling is no longer needed for a section. + * + * @param {Object} element jQuery object containing current section + */ + remove: function(element) { + var scrollable = element.find(SCROLLABLE_SEL); + if (scrollable.length) { + var iScrollInstance = scrollable.data('iscrollInstance'); + iScrollInstance.destroy(); + + scrollable.data('iscrollInstance', null); + } + element.find(SCROLLABLE_SEL).children().first().children().first().unwrap().unwrap(); + }, + + /** + * Called when overflow scrolling has already been setup but the + * window height has potentially changed. + * + * @param {Object} element jQuery object containing current section + * @param {Number} scrollHeight Current window height in pixels + */ + update: function(element, scrollHeight) { + //using a timeout in order to execute the refresh function only once when `update` is called multiple times in a + //short period of time. + //it also comes on handy because iScroll requires the use of timeout when using `refresh`. + clearTimeout(iscrollHandler.refreshId); + iscrollHandler.refreshId = setTimeout(function(){ + $.each(iscrollHandler.iScrollInstances, function(){ + $(this).get(0).refresh(); + }); + }, 150); + + //updating the wrappers height + element.find(SCROLLABLE_SEL).css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px'); + }, + + /** + * Called to get any additional elements needed to wrap the section + * content in order to facilitate overflow scrolling. + * + * @return {String|Object} Can be a string containing HTML, + * a DOM element, or jQuery object. + */ + wrapContent: function() { + return '
        '; + } + }; +}); diff --git a/modules/appagebuilder/js/jquery.infinitescroll.min.js b/modules/appagebuilder/js/jquery.infinitescroll.min.js new file mode 100644 index 00000000..7771c085 --- /dev/null +++ b/modules/appagebuilder/js/jquery.infinitescroll.min.js @@ -0,0 +1,40 @@ +/** + * @Website: http://infinite-scroll.com/ + * @author Paul Irish & Luke Shumard + * @copyright 2011-2015 Paul Irish & Luke Shumard + * @description: + */ +(function(window,$,undefined){$.infinitescroll=function infscr(options,callback,element){this.element=$(element);this._create(options,callback);};$.infinitescroll.defaults={loading:{finished:undefined,finishedMsg:"Congratulations, you've reached the end of the internet.",img:"http://www.infinite-scroll.com/loading.gif",msg:null,msgText:"Loading the next set of posts...",selector:null,speed:'fast',start:undefined},state:{isDuringAjax:false,isInvalidPage:false,isDestroyed:false,isDone:false,isPaused:false,currPage:1},callback:undefined,debug:false,behavior:undefined,binder:$(window),nextSelector:"div.navigation a:first",navSelector:"div.navigation",contentSelector:null,extraScrollPx:150,itemSelector:"div.post",animate:false,pathParse:undefined,dataType:'html',appendCallback:true,bufferPx:40,errorCallback:function(){},infid:0,pixelsFromNavToBottom:undefined,path:undefined};$.infinitescroll.prototype={_binding:function infscr_binding(binding){var instance=this,opts=instance.options;if(!!opts.behavior&&this['_binding_'+opts.behavior]!==undefined){this['_binding_'+opts.behavior].call(this);return;} +if(binding!=='bind'&&binding!=='unbind'){this._debug('Binding value '+binding+' not valid') +return false;} +if(binding=='unbind'){(this.options.binder).unbind('smartscroll.infscr.'+instance.options.infid);}else{(this.options.binder)[binding]('smartscroll.infscr.'+instance.options.infid,function(){instance.scroll();});};this._debug('Binding',binding);},_create:function infscr_create(options,callback){if(!this._validate(options)){return false;} +var opts=this.options=$.extend(true,{},$.infinitescroll.defaults,options),relurl=/(.*?\/\/).*?(\/.*)/,path=$(opts.nextSelector).attr('href');opts.contentSelector=opts.contentSelector||this.element;opts.loading.selector=opts.loading.selector||opts.contentSelector;if(!path){this._debug('Navigation selector not found');return;} +opts.path=this._determinepath(path);opts.loading.msg=$('
        Loading...
        '+opts.loading.msgText+'
        ');(new Image()).src=opts.loading.img;opts.pixelsFromNavToBottom=$(document).height()-$(opts.navSelector).offset().top;opts.loading.start=opts.loading.start||function(){$(opts.navSelector).hide();opts.loading.msg.appendTo(opts.loading.selector).show(opts.loading.speed,function(){beginAjax(opts);});};opts.loading.finished=opts.loading.finished||function(){opts.loading.msg.fadeOut('normal');};opts.callback=function(instance,data){if(!!opts.behavior&&instance['_callback_'+opts.behavior]!==undefined){instance['_callback_'+opts.behavior].call($(opts.contentSelector)[0],data);} +if(callback){callback.call($(opts.contentSelector)[0],data);}};this._setup();},_debug:function infscr_debug(){if(this.options.debug){return window.console&&console.log.call(console,arguments);}},_determinepath:function infscr_determinepath(path){var opts=this.options;if(!!opts.behavior&&this['_determinepath_'+opts.behavior]!==undefined){this['_determinepath_'+opts.behavior].call(this,path);return;} +if(!!opts.pathParse){this._debug('pathParse manual');return opts.pathParse;}else if(path.match(/^(.*?)\b2\b(.*?$)/)){path=path.match(/^(.*?)\b2\b(.*?$)/).slice(1);}else if(path.match(/^(.*?)2(.*?$)/)){if(path.match(/^(.*?page=)2(\/.*|$)/)){path=path.match(/^(.*?page=)2(\/.*|$)/).slice(1);return path;} +path=path.match(/^(.*?)2(.*?$)/).slice(1);}else{if(path.match(/^(.*?page=)1(\/.*|$)/)){path=path.match(/^(.*?page=)1(\/.*|$)/).slice(1);return path;}else{this._debug('Sorry, we couldn\'t parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag. If you still get this error: yell, scream, and kindly ask for help at infinite-scroll.com.');opts.state.isInvalidPage=true;}} +this._debug('determinePath',path);return path;},_error:function infscr_error(xhr){var opts=this.options;if(!!opts.behavior&&this['_error_'+opts.behavior]!==undefined){this['_error_'+opts.behavior].call(this,xhr);return;} +if(xhr!=='destroy'&&xhr!=='end'){xhr='unknown';} +this._debug('Error',xhr);if(xhr=='end'){this._showdonemsg();} +opts.state.isDone=true;opts.state.currPage=1;opts.state.isPaused=false;this._binding('unbind');},_loadcallback:function infscr_loadcallback(box,data){var opts=this.options,callback=this.options.callback,result=(opts.state.isDone)?'done':(!opts.appendCallback)?'no-append':'append',frag;if(!!opts.behavior&&this['_loadcallback_'+opts.behavior]!==undefined){this['_loadcallback_'+opts.behavior].call(this,box,data);return;} +switch(result){case'done':this._showdonemsg();return false;break;case'no-append':if(opts.dataType=='html'){data='
        '+data+'
        ';data=$(data).find(opts.itemSelector);};break;case'append':var children=box.children();if(children.length==0){return this._error('end');} +frag=document.createDocumentFragment();while(box[0].firstChild){frag.appendChild(box[0].firstChild);} +this._debug('contentSelector',$(opts.contentSelector)[0]) +$(opts.contentSelector)[0].appendChild(frag);data=children.get();break;} +opts.loading.finished.call($(opts.contentSelector)[0],opts) +if(opts.animate){var scrollTo=$(window).scrollTop()+$('#infscr-loading').height()+opts.extraScrollPx+'px';$('html,body').animate({scrollTop:scrollTo},800,function(){opts.state.isDuringAjax=false;});} +if(!opts.animate)opts.state.isDuringAjax=false;callback(this,data);},_nearbottom:function infscr_nearbottom(){var opts=this.options,pixelsFromWindowBottomToBottom=0+$(document).height()-(opts.binder.scrollTop())-$(window).height();if(!!opts.behavior&&this['_nearbottom_'+opts.behavior]!==undefined){this['_nearbottom_'+opts.behavior].call(this);return;} +this._debug('math:',pixelsFromWindowBottomToBottom,opts.pixelsFromNavToBottom);return(pixelsFromWindowBottomToBottom-opts.bufferPx-1&&$(opts[key]).length===0){this._debug('Your '+key+' found no elements.');return false;} +return true;}},bind:function infscr_bind(){this._binding('bind');},destroy:function infscr_destroy(){this.options.state.isDestroyed=true;return this._error('destroy');},pause:function infscr_pause(){this._pausing('pause');},resume:function infscr_resume(){this._pausing('resume');},retrieve:function infscr_retrieve(pageNum){var instance=this,opts=instance.options,path=opts.path,box,frag,desturl,method,condition,pageNum=pageNum||null,getPage=(!!pageNum)?pageNum:opts.state.currPage;beginAjax=function infscr_ajax(opts){opts.state.currPage++;instance._debug('heading into ajax',path);box=$(opts.contentSelector).is('table')?$(''):$('
        ');desturl=path.join(opts.state.currPage);method=(opts.dataType=='html'||opts.dataType=='json')?opts.dataType:'html+callback';if(opts.appendCallback&&opts.dataType=='html')method+='+callback' +switch(method){case'html+callback':instance._debug('Using HTML via .load() method');box.load(desturl+' '+opts.itemSelector,null,function infscr_ajax_callback(responseText){instance._loadcallback(box,responseText);});break;case'html':case'json':instance._debug('Using '+(method.toUpperCase())+' via $.ajax() method');$.ajax({url:desturl,dataType:opts.dataType,complete:function infscr_ajax_callback(jqXHR,textStatus){condition=(typeof(jqXHR.isResolved)!=='undefined')?(jqXHR.isResolved()):(textStatus==="success"||textStatus==="notmodified");(condition)?instance._loadcallback(box,jqXHR.responseText):instance._error('end');}});break;}};if(!!opts.behavior&&this['retrieve_'+opts.behavior]!==undefined){this['retrieve_'+opts.behavior].call(this,pageNum);return;} +if(opts.state.isDestroyed){this._debug('Instance is destroyed');return false;};opts.state.isDuringAjax=true;opts.loading.start.call($(opts.contentSelector)[0],opts);},scroll:function infscr_scroll(){var opts=this.options,state=opts.state;if(!!opts.behavior&&this['scroll_'+opts.behavior]!==undefined){this['scroll_'+opts.behavior].call(this);return;} +if(state.isDuringAjax||state.isInvalidPage||state.isDone||state.isDestroyed||state.isPaused)return;if(!this._nearbottom())return;this.retrieve();},toggle:function infscr_toggle(){this._pausing();},unbind:function infscr_unbind(){this._binding('unbind');},update:function infscr_options(key){if($.isPlainObject(key)){this.options=$.extend(true,this.options,key);}}} +$.fn.infinitescroll=function infscr_init(options,callback){var thisCall=typeof options;switch(thisCall){case'string':var args=Array.prototype.slice.call(arguments,1);this.each(function(){var instance=$.data(this,'infinitescroll');if(!instance){return false;} +if(!$.isFunction(instance[options])||options.charAt(0)==="_"){return false;} +instance[options].apply(instance,args);});break;case'object':this.each(function(){var instance=$.data(this,'infinitescroll');if(instance){instance.update(options);}else{$.data(this,'infinitescroll',new $.infinitescroll(options,callback,this));}});break;} +return this;};var event=$.event,scrollTimeout;event.special.smartscroll={setup:function(){$(this).bind("scroll",event.special.smartscroll.handler);},teardown:function(){$(this).unbind("scroll",event.special.smartscroll.handler);},handler:function(event,execAsap){var context=this,args=arguments;event.type="smartscroll";if(scrollTimeout){clearTimeout(scrollTimeout);} +scrollTimeout=setTimeout(function(){$.event.handle.apply(context,args);},execAsap==="execAsap"?0:100);}};$.fn.smartscroll=function(fn){return fn?this.bind("smartscroll",fn):this.trigger("smartscroll",["execAsap"]);};})(window,jQuery); \ No newline at end of file diff --git a/modules/appagebuilder/js/jquery.stellar.js b/modules/appagebuilder/js/jquery.stellar.js new file mode 100644 index 00000000..020db3a6 --- /dev/null +++ b/modules/appagebuilder/js/jquery.stellar.js @@ -0,0 +1,660 @@ +/*! + * Stellar.js v0.6.2 + * http://markdalgleish.com/projects/stellar.js + * + * Copyright 2014, Mark Dalgleish + * This content is released under the MIT license + * http://markdalgleish.mit-license.org + */ + +;(function($, window, document, undefined) { + + var pluginName = 'stellar', + defaults = { + scrollProperty: 'scroll', + positionProperty: 'position', + horizontalScrolling: true, + verticalScrolling: true, + horizontalOffset: 0, + verticalOffset: 0, + responsive: false, + parallaxBackgrounds: true, + parallaxElements: true, + hideDistantElements: true, + hideElement: function($elem) { $elem.hide(); }, + showElement: function($elem) { $elem.show(); } + }, + + scrollProperty = { + scroll: { + getLeft: function($elem) { return $elem.scrollLeft(); }, + setLeft: function($elem, val) { $elem.scrollLeft(val); }, + + getTop: function($elem) { return $elem.scrollTop(); }, + setTop: function($elem, val) { $elem.scrollTop(val); } + }, + position: { + getLeft: function($elem) { return parseInt($elem.css('left'), 10) * -1; }, + getTop: function($elem) { return parseInt($elem.css('top'), 10) * -1; } + }, + margin: { + getLeft: function($elem) { return parseInt($elem.css('margin-left'), 10) * -1; }, + getTop: function($elem) { return parseInt($elem.css('margin-top'), 10) * -1; } + }, + transform: { + getLeft: function($elem) { + var computedTransform = getComputedStyle($elem[0])[prefixedTransform]; + return (computedTransform !== 'none' ? parseInt(computedTransform.match(/(-?[0-9]+)/g)[4], 10) * -1 : 0); + }, + getTop: function($elem) { + var computedTransform = getComputedStyle($elem[0])[prefixedTransform]; + return (computedTransform !== 'none' ? parseInt(computedTransform.match(/(-?[0-9]+)/g)[5], 10) * -1 : 0); + } + } + }, + + positionProperty = { + position: { + setLeft: function($elem, left) { $elem.css('left', left); }, + setTop: function($elem, top) { $elem.css('top', top); } + }, + transform: { + setPosition: function($elem, left, startingLeft, top, startingTop) { + $elem[0].style[prefixedTransform] = 'translate3d(' + (left - startingLeft) + 'px, ' + (top - startingTop) + 'px, 0)'; + } + } + }, + + // Returns a function which adds a vendor prefix to any CSS property name + vendorPrefix = (function() { + var prefixes = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/, + style = $('script')[0].style, + prefix = '', + prop; + + for (prop in style) { + if (prefixes.test(prop)) { + prefix = prop.match(prefixes)[0]; + break; + } + } + + if ('WebkitOpacity' in style) { prefix = 'Webkit'; } + if ('KhtmlOpacity' in style) { prefix = 'Khtml'; } + + return function(property) { + return prefix + (prefix.length > 0 ? property.charAt(0).toUpperCase() + property.slice(1) : property); + }; + }()), + + prefixedTransform = vendorPrefix('transform'), + + supportsBackgroundPositionXY = $('
        ', { style: 'background:#fff' }).css('background-position-x') !== undefined, + + setBackgroundPosition = (supportsBackgroundPositionXY ? + function($elem, x, y) { + $elem.css({ + 'background-position-x': x, + 'background-position-y': y + }); + } : + function($elem, x, y) { + $elem.css('background-position', x + ' ' + y); + } + ), + + getBackgroundPosition = (supportsBackgroundPositionXY ? + function($elem) { + return [ + $elem.css('background-position-x'), + $elem.css('background-position-y') + ]; + } : + function($elem) { + return $elem.css('background-position').split(' '); + } + ), + + requestAnimFrame = ( + window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(callback) { + setTimeout(callback, 1000 / 60); + } + ); + + function Plugin(element, options) { + this.element = element; + this.options = $.extend({}, defaults, options); + + this._defaults = defaults; + this._name = pluginName; + + this.init(); + } + + Plugin.prototype = { + init: function() { + this.options.name = pluginName + '_' + Math.floor(Math.random() * 1e9); + + this._defineElements(); + this._defineGetters(); + this._defineSetters(); + this._handleWindowLoadAndResize(); + this._detectViewport(); + + this.refresh({ firstLoad: true }); + + if (this.options.scrollProperty === 'scroll') { + this._handleScrollEvent(); + } else { + this._startAnimationLoop(); + } + }, + _defineElements: function() { + if (this.element === document.body) this.element = window; + this.$scrollElement = $(this.element); + this.$element = (this.element === window ? $('body') : this.$scrollElement); + this.$viewportElement = (this.options.viewportElement !== undefined ? $(this.options.viewportElement) : (this.$scrollElement[0] === window || this.options.scrollProperty === 'scroll' ? this.$scrollElement : this.$scrollElement.parent()) ); + }, + _defineGetters: function() { + var self = this, + scrollPropertyAdapter = scrollProperty[self.options.scrollProperty]; + + this._getScrollLeft = function() { + return scrollPropertyAdapter.getLeft(self.$scrollElement); + }; + + this._getScrollTop = function() { + return scrollPropertyAdapter.getTop(self.$scrollElement); + }; + }, + _defineSetters: function() { + var self = this, + scrollPropertyAdapter = scrollProperty[self.options.scrollProperty], + positionPropertyAdapter = positionProperty[self.options.positionProperty], + setScrollLeft = scrollPropertyAdapter.setLeft, + setScrollTop = scrollPropertyAdapter.setTop; + + this._setScrollLeft = (typeof setScrollLeft === 'function' ? function(val) { + setScrollLeft(self.$scrollElement, val); + } : $.noop); + + this._setScrollTop = (typeof setScrollTop === 'function' ? function(val) { + setScrollTop(self.$scrollElement, val); + } : $.noop); + + this._setPosition = positionPropertyAdapter.setPosition || + function($elem, left, startingLeft, top, startingTop) { + if (self.options.horizontalScrolling) { + positionPropertyAdapter.setLeft($elem, left, startingLeft); + } + + if (self.options.verticalScrolling) { + positionPropertyAdapter.setTop($elem, top, startingTop); + } + }; + }, + _handleWindowLoadAndResize: function() { + var self = this, + $window = $(window); + + if (self.options.responsive) { + $window.bind('load.' + this.name, function() { + self.refresh(); + }); + } + + $window.bind('resize.' + this.name, function() { + self._detectViewport(); + + if (self.options.responsive) { + self.refresh(); + } + }); + }, + refresh: function(options) { + var self = this, + oldLeft = self._getScrollLeft(), + oldTop = self._getScrollTop(); + + if (!options || !options.firstLoad) { + this._reset(); + } + + this._setScrollLeft(0); + this._setScrollTop(0); + + this._setOffsets(); + this._findParticles(); + this._findBackgrounds(); + + // Fix for WebKit background rendering bug + if (options && options.firstLoad && /WebKit/.test(navigator.userAgent)) { + $(window).load(function() { + var oldLeft = self._getScrollLeft(), + oldTop = self._getScrollTop(); + + self._setScrollLeft(oldLeft + 1); + self._setScrollTop(oldTop + 1); + + self._setScrollLeft(oldLeft); + self._setScrollTop(oldTop); + }); + } + + this._setScrollLeft(oldLeft); + this._setScrollTop(oldTop); + }, + _detectViewport: function() { + var viewportOffsets = this.$viewportElement.offset(), + hasOffsets = viewportOffsets !== null && viewportOffsets !== undefined; + + this.viewportWidth = this.$viewportElement.width(); + this.viewportHeight = this.$viewportElement.height(); + + this.viewportOffsetTop = (hasOffsets ? viewportOffsets.top : 0); + this.viewportOffsetLeft = (hasOffsets ? viewportOffsets.left : 0); + }, + _findParticles: function() { + var self = this, + scrollLeft = this._getScrollLeft(), + scrollTop = this._getScrollTop(); + + if (this.particles !== undefined) { + for (var i = this.particles.length - 1; i >= 0; i--) { + this.particles[i].$element.data('stellar-elementIsActive', undefined); + } + } + + this.particles = []; + + if (!this.options.parallaxElements) return; + + this.$element.find('[data-stellar-ratio]').each(function(i) { + var $this = $(this), + horizontalOffset, + verticalOffset, + positionLeft, + positionTop, + marginLeft, + marginTop, + $offsetParent, + offsetLeft, + offsetTop, + parentOffsetLeft = 0, + parentOffsetTop = 0, + tempParentOffsetLeft = 0, + tempParentOffsetTop = 0; + + // Ensure this element isn't already part of another scrolling element + if (!$this.data('stellar-elementIsActive')) { + $this.data('stellar-elementIsActive', this); + } else if ($this.data('stellar-elementIsActive') !== this) { + return; + } + + self.options.showElement($this); + + // Save/restore the original top and left CSS values in case we refresh the particles or destroy the instance + if (!$this.data('stellar-startingLeft')) { + $this.data('stellar-startingLeft', $this.css('left')); + $this.data('stellar-startingTop', $this.css('top')); + } else { + $this.css('left', $this.data('stellar-startingLeft')); + $this.css('top', $this.data('stellar-startingTop')); + } + + positionLeft = $this.position().left; + positionTop = $this.position().top; + + // Catch-all for margin top/left properties (these evaluate to 'auto' in IE7 and IE8) + marginLeft = ($this.css('margin-left') === 'auto') ? 0 : parseInt($this.css('margin-left'), 10); + marginTop = ($this.css('margin-top') === 'auto') ? 0 : parseInt($this.css('margin-top'), 10); + + offsetLeft = $this.offset().left - marginLeft; + offsetTop = $this.offset().top - marginTop; + + // Calculate the offset parent + $this.parents().each(function() { + var $this = $(this); + + if ($this.data('stellar-offset-parent') === true) { + parentOffsetLeft = tempParentOffsetLeft; + parentOffsetTop = tempParentOffsetTop; + $offsetParent = $this; + + return false; + } else { + tempParentOffsetLeft += $this.position().left; + tempParentOffsetTop += $this.position().top; + } + }); + + // Detect the offsets + horizontalOffset = ($this.data('stellar-horizontal-offset') !== undefined ? $this.data('stellar-horizontal-offset') : ($offsetParent !== undefined && $offsetParent.data('stellar-horizontal-offset') !== undefined ? $offsetParent.data('stellar-horizontal-offset') : self.horizontalOffset)); + verticalOffset = ($this.data('stellar-vertical-offset') !== undefined ? $this.data('stellar-vertical-offset') : ($offsetParent !== undefined && $offsetParent.data('stellar-vertical-offset') !== undefined ? $offsetParent.data('stellar-vertical-offset') : self.verticalOffset)); + + // Add our object to the particles collection + self.particles.push({ + $element: $this, + $offsetParent: $offsetParent, + isFixed: $this.css('position') === 'fixed', + horizontalOffset: horizontalOffset, + verticalOffset: verticalOffset, + startingPositionLeft: positionLeft, + startingPositionTop: positionTop, + startingOffsetLeft: offsetLeft, + startingOffsetTop: offsetTop, + parentOffsetLeft: parentOffsetLeft, + parentOffsetTop: parentOffsetTop, + stellarRatio: ($this.data('stellar-ratio') !== undefined ? $this.data('stellar-ratio') : 1), + width: $this.outerWidth(true), + height: $this.outerHeight(true), + isHidden: false + }); + }); + }, + _findBackgrounds: function() { + var self = this, + scrollLeft = this._getScrollLeft(), + scrollTop = this._getScrollTop(), + $backgroundElements; + + this.backgrounds = []; + + if (!this.options.parallaxBackgrounds) return; + + $backgroundElements = this.$element.find('[data-stellar-background-ratio]'); + + if (this.$element.data('stellar-background-ratio')) { + $backgroundElements = $backgroundElements.add(this.$element); + } + + $backgroundElements.each(function() { + var $this = $(this), + backgroundPosition = getBackgroundPosition($this), + horizontalOffset, + verticalOffset, + positionLeft, + positionTop, + marginLeft, + marginTop, + offsetLeft, + offsetTop, + $offsetParent, + parentOffsetLeft = 0, + parentOffsetTop = 0, + tempParentOffsetLeft = 0, + tempParentOffsetTop = 0; + + // Ensure this element isn't already part of another scrolling element + if (!$this.data('stellar-backgroundIsActive')) { + $this.data('stellar-backgroundIsActive', this); + } else if ($this.data('stellar-backgroundIsActive') !== this) { + return; + } + + // Save/restore the original top and left CSS values in case we destroy the instance + if (!$this.data('stellar-backgroundStartingLeft')) { + $this.data('stellar-backgroundStartingLeft', backgroundPosition[0]); + $this.data('stellar-backgroundStartingTop', backgroundPosition[1]); + } else { + setBackgroundPosition($this, $this.data('stellar-backgroundStartingLeft'), $this.data('stellar-backgroundStartingTop')); + } + + // Catch-all for margin top/left properties (these evaluate to 'auto' in IE7 and IE8) + marginLeft = ($this.css('margin-left') === 'auto') ? 0 : parseInt($this.css('margin-left'), 10); + marginTop = ($this.css('margin-top') === 'auto') ? 0 : parseInt($this.css('margin-top'), 10); + + offsetLeft = $this.offset().left - marginLeft - scrollLeft; + offsetTop = $this.offset().top - marginTop - scrollTop; + + // Calculate the offset parent + $this.parents().each(function() { + var $this = $(this); + + if ($this.data('stellar-offset-parent') === true) { + parentOffsetLeft = tempParentOffsetLeft; + parentOffsetTop = tempParentOffsetTop; + $offsetParent = $this; + + return false; + } else { + tempParentOffsetLeft += $this.position().left; + tempParentOffsetTop += $this.position().top; + } + }); + + // Detect the offsets + horizontalOffset = ($this.data('stellar-horizontal-offset') !== undefined ? $this.data('stellar-horizontal-offset') : ($offsetParent !== undefined && $offsetParent.data('stellar-horizontal-offset') !== undefined ? $offsetParent.data('stellar-horizontal-offset') : self.horizontalOffset)); + verticalOffset = ($this.data('stellar-vertical-offset') !== undefined ? $this.data('stellar-vertical-offset') : ($offsetParent !== undefined && $offsetParent.data('stellar-vertical-offset') !== undefined ? $offsetParent.data('stellar-vertical-offset') : self.verticalOffset)); + + self.backgrounds.push({ + $element: $this, + $offsetParent: $offsetParent, + isFixed: $this.css('background-attachment') === 'fixed', + horizontalOffset: horizontalOffset, + verticalOffset: verticalOffset, + startingValueLeft: backgroundPosition[0], + startingValueTop: backgroundPosition[1], + startingBackgroundPositionLeft: (isNaN(parseInt(backgroundPosition[0], 10)) ? 0 : parseInt(backgroundPosition[0], 10)), + startingBackgroundPositionTop: (isNaN(parseInt(backgroundPosition[1], 10)) ? 0 : parseInt(backgroundPosition[1], 10)), + startingPositionLeft: $this.position().left, + startingPositionTop: $this.position().top, + startingOffsetLeft: offsetLeft, + startingOffsetTop: offsetTop, + parentOffsetLeft: parentOffsetLeft, + parentOffsetTop: parentOffsetTop, + stellarRatio: ($this.data('stellar-background-ratio') === undefined ? 1 : $this.data('stellar-background-ratio')) + }); + }); + }, + _reset: function() { + var particle, + startingPositionLeft, + startingPositionTop, + background, + i; + + for (i = this.particles.length - 1; i >= 0; i--) { + particle = this.particles[i]; + startingPositionLeft = particle.$element.data('stellar-startingLeft'); + startingPositionTop = particle.$element.data('stellar-startingTop'); + + this._setPosition(particle.$element, startingPositionLeft, startingPositionLeft, startingPositionTop, startingPositionTop); + + this.options.showElement(particle.$element); + + particle.$element.data('stellar-startingLeft', null).data('stellar-elementIsActive', null).data('stellar-backgroundIsActive', null); + } + + for (i = this.backgrounds.length - 1; i >= 0; i--) { + background = this.backgrounds[i]; + + background.$element.data('stellar-backgroundStartingLeft', null).data('stellar-backgroundStartingTop', null); + + setBackgroundPosition(background.$element, background.startingValueLeft, background.startingValueTop); + } + }, + destroy: function() { + this._reset(); + + this.$scrollElement.unbind('resize.' + this.name).unbind('scroll.' + this.name); + this._animationLoop = $.noop; + + $(window).unbind('load.' + this.name).unbind('resize.' + this.name); + }, + _setOffsets: function() { + var self = this, + $window = $(window); + + $window.unbind('resize.horizontal-' + this.name).unbind('resize.vertical-' + this.name); + + if (typeof this.options.horizontalOffset === 'function') { + this.horizontalOffset = this.options.horizontalOffset(); + $window.bind('resize.horizontal-' + this.name, function() { + self.horizontalOffset = self.options.horizontalOffset(); + }); + } else { + this.horizontalOffset = this.options.horizontalOffset; + } + + if (typeof this.options.verticalOffset === 'function') { + this.verticalOffset = this.options.verticalOffset(); + $window.bind('resize.vertical-' + this.name, function() { + self.verticalOffset = self.options.verticalOffset(); + }); + } else { + this.verticalOffset = this.options.verticalOffset; + } + }, + _repositionElements: function() { + var scrollLeft = this._getScrollLeft(), + scrollTop = this._getScrollTop(), + horizontalOffset, + verticalOffset, + particle, + fixedRatioOffset, + background, + bgLeft, + bgTop, + isVisibleVertical = true, + isVisibleHorizontal = true, + newPositionLeft, + newPositionTop, + newOffsetLeft, + newOffsetTop, + i; + + // First check that the scroll position or container size has changed + if (this.currentScrollLeft === scrollLeft && this.currentScrollTop === scrollTop && this.currentWidth === this.viewportWidth && this.currentHeight === this.viewportHeight) { + return; + } else { + this.currentScrollLeft = scrollLeft; + this.currentScrollTop = scrollTop; + this.currentWidth = this.viewportWidth; + this.currentHeight = this.viewportHeight; + } + + // Reposition elements + for (i = this.particles.length - 1; i >= 0; i--) { + particle = this.particles[i]; + + fixedRatioOffset = (particle.isFixed ? 1 : 0); + + // Calculate position, then calculate what the particle's new offset will be (for visibility check) + if (this.options.horizontalScrolling) { + newPositionLeft = (scrollLeft + particle.horizontalOffset + this.viewportOffsetLeft + particle.startingPositionLeft - particle.startingOffsetLeft + particle.parentOffsetLeft) * -(particle.stellarRatio + fixedRatioOffset - 1) + particle.startingPositionLeft; + newOffsetLeft = newPositionLeft - particle.startingPositionLeft + particle.startingOffsetLeft; + } else { + newPositionLeft = particle.startingPositionLeft; + newOffsetLeft = particle.startingOffsetLeft; + } + + if (this.options.verticalScrolling) { + newPositionTop = (scrollTop + particle.verticalOffset + this.viewportOffsetTop + particle.startingPositionTop - particle.startingOffsetTop + particle.parentOffsetTop) * -(particle.stellarRatio + fixedRatioOffset - 1) + particle.startingPositionTop; + newOffsetTop = newPositionTop - particle.startingPositionTop + particle.startingOffsetTop; + } else { + newPositionTop = particle.startingPositionTop; + newOffsetTop = particle.startingOffsetTop; + } + + // Check visibility + if (this.options.hideDistantElements) { + isVisibleHorizontal = !this.options.horizontalScrolling || newOffsetLeft + particle.width > (particle.isFixed ? 0 : scrollLeft) && newOffsetLeft < (particle.isFixed ? 0 : scrollLeft) + this.viewportWidth + this.viewportOffsetLeft; + isVisibleVertical = !this.options.verticalScrolling || newOffsetTop + particle.height > (particle.isFixed ? 0 : scrollTop) && newOffsetTop < (particle.isFixed ? 0 : scrollTop) + this.viewportHeight + this.viewportOffsetTop; + } + + if (isVisibleHorizontal && isVisibleVertical) { + if (particle.isHidden) { + this.options.showElement(particle.$element); + particle.isHidden = false; + } + + this._setPosition(particle.$element, newPositionLeft, particle.startingPositionLeft, newPositionTop, particle.startingPositionTop); + } else { + if (!particle.isHidden) { + this.options.hideElement(particle.$element); + particle.isHidden = true; + } + } + } + + // Reposition backgrounds + for (i = this.backgrounds.length - 1; i >= 0; i--) { + background = this.backgrounds[i]; + + fixedRatioOffset = (background.isFixed ? 0 : 1); + bgLeft = (this.options.horizontalScrolling ? (scrollLeft + background.horizontalOffset - this.viewportOffsetLeft - background.startingOffsetLeft + background.parentOffsetLeft - background.startingBackgroundPositionLeft) * (fixedRatioOffset - background.stellarRatio) + 'px' : background.startingValueLeft); + bgTop = (this.options.verticalScrolling ? (scrollTop + background.verticalOffset - this.viewportOffsetTop - background.startingOffsetTop + background.parentOffsetTop - background.startingBackgroundPositionTop) * (fixedRatioOffset - background.stellarRatio) + 'px' : background.startingValueTop); + + setBackgroundPosition(background.$element, bgLeft, bgTop); + } + }, + _handleScrollEvent: function() { + var self = this, + ticking = false; + + var update = function() { + self._repositionElements(); + ticking = false; + }; + + var requestTick = function() { + if (!ticking) { + requestAnimFrame(update); + ticking = true; + } + }; + + this.$scrollElement.bind('scroll.' + this.name, requestTick); + requestTick(); + }, + _startAnimationLoop: function() { + var self = this; + + this._animationLoop = function() { + requestAnimFrame(self._animationLoop); + self._repositionElements(); + }; + this._animationLoop(); + } + }; + + $.fn[pluginName] = function (options) { + var args = arguments; + if (options === undefined || typeof options === 'object') { + return this.each(function () { + if (!$.data(this, 'plugin_' + pluginName)) { + $.data(this, 'plugin_' + pluginName, new Plugin(this, options)); + } + }); + } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') { + return this.each(function () { + var instance = $.data(this, 'plugin_' + pluginName); + if (instance instanceof Plugin && typeof instance[options] === 'function') { + instance[options].apply(instance, Array.prototype.slice.call(args, 1)); + } + if (options === 'destroy') { + $.data(this, 'plugin_' + pluginName, null); + } + }); + } + }; + + $[pluginName] = function(options) { + var $window = $(window); + return $window.stellar.apply($window, Array.prototype.slice.call(arguments, 0)); + }; + + // Expose the scroll and position property function hashes so they can be extended + $[pluginName].scrollProperty = scrollProperty; + $[pluginName].positionProperty = positionProperty; + + // Expose the plugin class so it can be modified + window.Stellar = Plugin; +}(jQuery, this, document)); \ No newline at end of file diff --git a/modules/appagebuilder/js/mediaelement-and-player.js b/modules/appagebuilder/js/mediaelement-and-player.js new file mode 100644 index 00000000..e677683d --- /dev/null +++ b/modules/appagebuilder/js/mediaelement-and-player.js @@ -0,0 +1,5752 @@ +/*! + * + * MediaElement.js + * HTML5