{l s='We\'re sorry, but the Web address you entered is no longer available'}
+{l s='To find a product, please type its name in the field below'}
+diff --git a/classes/Context.php b/classes/Context.php index f40f07fe8..bae296667 100644 --- a/classes/Context.php +++ b/classes/Context.php @@ -95,6 +95,59 @@ class ContextCore */ public $smarty; + /** + * @var boolean|string mobile device of the customer + */ + protected $mobile_device; + + /** + * @var boolean|string touch pad device of the customer + */ + protected $touchpad_device; + + public function getMobileDevice() + { + if (is_null($this->mobile_device)) + { + $this->mobile_device = false; + if ($this->checkMobileContext()) + if (preg_match('/(alcatel|amoi|android|avantgo|blackberry|benq|cell|cricket|docomo|elaine|htc|iemobile|iphone|ipaq|ipod|j2me|java|midp|mini|mmp|mobi\s|motorola|nec-|nokia|palm|panasonic|philips|phone|sagem|sharp|sie-|smartphone|sony|symbian|t-mobile|telus|up\.browser|up\.link|vodafone|wap|webos|wireless|xda|zte)/i', $_SERVER['HTTP_USER_AGENT'], $out)) + $this->mobile_device = $out[0]; + } + + return $this->mobile_device; + } + + protected function checkMobileContext() + { + return file_exists(_PS_THEME_MOBILE_DIR_) + && Configuration::get('PS_ALLOW_MOBILE_DEVICE') + && isset($_SERVER['HTTP_USER_AGENT']) + && !Context::getContext()->cookie->no_mobile; + } + + protected function getTouchPadDevice() + { + if (is_null($this->touchpad_device)) + { + $this->touchpad_device = false; + if ($this->checkMobileContext()) + { + if (preg_match('/(xoom|ipad)/i', $_SERVER['HTTP_USER_AGENT'], $out)) + $this->touchpad_device = $out[0]; + if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'android') && !strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'mobile')) + $this->touchpad_device = 'android'; + + // for Galaxy tab + if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'android') + && (strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'sch-i800') + || strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'gt-p1000'))) + $this->touchpad_device = 'android'; + } + } + return $this->touchpad_device; + } + /** * Get a singleton context * diff --git a/classes/controller/FrontController.php b/classes/controller/FrontController.php index f655061e9..0c7746f06 100755 --- a/classes/controller/FrontController.php +++ b/classes/controller/FrontController.php @@ -249,6 +249,10 @@ class FrontControllerCore extends Controller CartRule::autoAddToCart($this->context); } + // Check mobile context + if (Tools::isSubmit('no_mobile')) + $this->context->cookie->no_mobile = true; + $locale = strtolower(Configuration::get('PS_LOCALE_LANGUAGE')).'_'.strtoupper(Configuration::get('PS_LOCALE_COUNTRY').'.UTF-8'); setlocale(LC_COLLATE, $locale); setlocale(LC_CTYPE, $locale); @@ -305,6 +309,8 @@ class FrontControllerCore extends Controller $meta_language[] = $lang['iso_code']; $this->context->smarty->assign(array( + // Usefull for layout.tpl + 'mobile_device' => $this->context->getMobileDevice(), 'link' => $link, 'cart' => $cart, 'currency' => $currency, @@ -338,6 +344,12 @@ class FrontControllerCore extends Controller 'request' => $link->getPaginationLink(false, false, false, true) )); + // Add the tpl files directory for mobile + if ($this->context->getMobileDevice() != false) + $this->context->smarty->assign(array( + 'tpl_mobile_uri' => _PS_THEME_MOBILE_DIR_, + )); + // Deprecated $this->context->smarty->assign(array( 'id_currency_cookie' => (int)$currency->id, @@ -361,6 +373,14 @@ class FrontControllerCore extends Controller 'pic_dir' => _THEME_PROD_PIC_DIR_ ); + // Add the images directory for mobile + if ($this->context->getMobileDevice() != false) + $assign_array['img_mobile_dir'] = _THEME_MOBILE_IMG_DIR_; + + // Add the CSS directory for mobile + if ($this->context->getMobileDevice() != false) + $assign_array['css_mobile_dir'] = _THEME_MOBILE_CSS_DIR_; + foreach ($assign_array as $assign_key => $assign_value) if (substr($assign_value, 0, 1) == '/' || $protocol_content == 'https://') $this->context->smarty->assign($assign_key, $protocol_content.Tools::getMediaServer($assign_value).$assign_value); @@ -419,12 +439,25 @@ class FrontControllerCore extends Controller $this->process(); if (!isset($this->context->cart)) $this->context->cart = new Cart(); - $this->context->smarty->assign(array( - 'HOOK_HEADER' => Hook::exec('displayHeader'), - 'HOOK_TOP' => Hook::exec('displayTop'), - 'HOOK_LEFT_COLUMN' => ($this->display_column_left ? Hook::exec('displayLeftColumn') : ''), - 'HOOK_RIGHT_COLUMN' => ($this->display_column_right ? Hook::exec('displayRightColumn', array('cart' => $this->context->cart)) : ''), - )); + if ($this->context->getMobileDevice() == false) + { + // These hooks aren't used for the mobile theme. + // Needed hooks are called in the tpl files. + if (!isset($this->context->cart)) + $this->context->cart = new Cart(); + $this->context->smarty->assign(array( + 'HOOK_HEADER' => Hook::exec('displayHeader'), + 'HOOK_TOP' => Hook::exec('displayTop'), + 'HOOK_LEFT_COLUMN' => ($this->display_column_left ? Hook::exec('displayLeftColumn') : ''), + 'HOOK_RIGHT_COLUMN' => ($this->display_column_right ? Hook::exec('displayRightColumn', array('cart' => $this->context->cart)) : ''), + )); + } + else + { + $this->context->smarty->assign(array( + 'HOOK_MOBILE_HEADER' => Hook::exec('displayMobileHeader'), + )); + } } /** @@ -517,7 +550,8 @@ class FrontControllerCore extends Controller 'display_footer' => $this->display_footer, )); - if (Tools::isSubmit('live_edit')) + // Don't use live edit if on mobile device + if ($this->context->getMobileDevice() == false && Tools::isSubmit('live_edit')) $this->context->smarty->assign('live_edit', $this->getLiveEditFooter()); $layout = $this->getLayout(); @@ -572,7 +606,9 @@ class FrontControllerCore extends Controller { header('HTTP/1.1 503 temporarily overloaded'); $this->context->smarty->assign('favicon_url', _PS_IMG_.Configuration::get('PS_FAVICON')); - $this->context->smarty->display(_PS_THEME_DIR_.'maintenance.tpl'); + + $template_dir = ($this->context->getMobileDevice() == true ? _PS_THEME_MOBILE_DIR_ : _PS_THEME_DIR_); + $this->context->smarty->display($template_dir.'maintenance.tpl'); exit; } } @@ -685,8 +721,32 @@ class FrontControllerCore extends Controller return false; } + /** + * Specific medias for mobile device. + */ + public function setMobileMedia() + { + $this->addjquery(); + $this->addJS(_THEME_MOBILE_JS_DIR_.'jquery.mobile-1.1.1.min.js'); + $this->addJS(_THEME_MOBILE_JS_DIR_.'jqm-docs.js'); + $this->addJS(_PS_JS_DIR_.'tools.js'); + $this->addJS(_THEME_MOBILE_JS_DIR_.'global.js'); + $this->addjqueryPlugin('fancybox'); + + $this->addCSS(_THEME_MOBILE_CSS_DIR_.'jquery.mobile-1.1.1.min.css', 'all'); + $this->addCSS(_THEME_MOBILE_CSS_DIR_.'jqm-docs.css', 'all'); + $this->addCSS(_THEME_MOBILE_CSS_DIR_.'global.css', 'all'); + } + public function setMedia() { + // if website is accessed by mobile device + // @see FrontControllerCore::setMobileMedia() + if ($this->context->getMobileDevice() != false) + { + $this->setMobileMedia(); + return true; + } $this->addCSS(_THEME_CSS_DIR_.'global.css', 'all'); $this->addjquery(); $this->addjqueryPlugin('easing'); @@ -960,15 +1020,20 @@ class FrontControllerCore extends Controller /** * This is overrided to manage is behaviour + * if a customer access to the site with mobile device. */ public function setTemplate($default_template) { - $template = $this->getOverrideTemplate(); - - if ($template) - parent::setTemplate($template); - else - parent::setTemplate($default_template); + if ($this->context->getMobileDevice() != false) + $this->setMobileTemplate($default_template); + else + { + $template = $this->getOverrideTemplate(); + if ($template) + parent::setTemplate($template); + else + parent::setTemplate($default_template); + } } /** @@ -1002,6 +1067,12 @@ class FrontControllerCore extends Controller $layout_dir = _PS_THEME_DIR_; $layout_override_dir = _PS_THEME_OVERRIDE_DIR_; + if ($this->context->getMobileDevice() != false) + { + $layout_dir = _PS_THEME_MOBILE_DIR_; + $layout_override_dir = _PS_THEME_MOBILE_OVERRIDE_DIR_; + } + $layout = false; if ($entity) { @@ -1016,4 +1087,47 @@ class FrontControllerCore extends Controller return $layout; } + + /** + * This checks if the template set is available for mobile themes, + * otherwise the front template is choosen. + */ + public function setMobileTemplate($template) + { + // Needed for site map + $blockmanufacturer = Module::getInstanceByName('blockmanufacturer'); + $blocksupplier = Module::getInstanceByName('blocksupplier'); + $this->context->smarty->assign('categoriesTree', Category::getRootCategory()->recurseLiteCategTree(0)); + $this->context->smarty->assign('categoriescmsTree', CMSCategory::getRecurseCategory($this->context->language->id, 1, 1, 1)); + $this->context->smarty->assign('voucherAllowed', (int)Configuration::get('PS_VOUCHERS')); + $this->context->smarty->assign('display_manufacturer_link', (((int)$blockmanufacturer->id) ? true : false)); + $this->context->smarty->assign('display_supplier_link', (((int)$blocksupplier->id) ? true : false)); + $this->context->smarty->assign('PS_DISPLAY_SUPPLIERS', Configuration::get('PS_DISPLAY_SUPPLIERS')); + $this->context->smarty->assign('display_store', Configuration::get('PS_STORES_DISPLAY_SITEMAP')); + $this->context->smarty->assign('conditions', Configuration::get('PS_CONDITIONS')); + $this->context->smarty->assign('id_cgv', Configuration::get('PS_CONDITIONS_CMS_ID')); + $this->context->smarty->assign('PS_SHOP_NAME', Configuration::get('PS_SHOP_NAME')); + + $mobile_template = ''; + $tpl_file = basename($template); + $dirname = dirname($template).(substr(dirname($template), -1, 1) == '/' ? '' : '/'); + + if ($dirname == _PS_THEME_DIR_) + { + if (file_exists(_PS_THEME_MOBILE_DIR_.$tpl_file)) + $template = _PS_THEME_MOBILE_DIR_.$tpl_file; + } + elseif ($dirname == _PS_THEME_MOBILE_DIR_) + { + if (!file_exists(_PS_THEME_MOBILE_DIR_.$tpl_file) && file_exists(_PS_THEME_DIR_.$tpl_file)) + $template = _PS_THEME_DIR_.$tpl_file; + } + $assign = array(); + $assign['tpl_file'] = basename($tpl_file, '.tpl'); + if (isset($this->php_self)) + $assign['controller_name'] = $this->php_self; + + $this->context->smarty->assign($assign); + $this->template = $template; + } } diff --git a/config/defines_uri.inc.php b/config/defines_uri.inc.php index fa226bdc3..918010c0f 100644 --- a/config/defines_uri.inc.php +++ b/config/defines_uri.inc.php @@ -34,6 +34,28 @@ define('_THEME_CSS_DIR_', _THEME_DIR_.'css/'); define('_THEME_JS_DIR_', _THEME_DIR_.'js/'); define('_PS_THEME_OVERRIDE_DIR_', _PS_THEME_DIR_.'override/'); +/* For mobile devices */ +if (file_exists(_PS_THEME_DIR_.'mobile/')) +{ + define('_PS_THEME_MOBILE_DIR_', _PS_THEME_DIR_.'mobile/'); + define('_THEME_MOBILE_DIR_', _THEMES_DIR_._THEME_NAME_.'/mobile/'); + define('_PS_THEME_MOBILE_OVERRIDE_DIR_', _PS_THEME_MOBILE_DIR_.'override/'); +} +else +{ + define('_PS_THEME_MOBILE_DIR_', _PS_ROOT_DIR_.'/themes/default/mobile/'); + define('_THEME_MOBILE_DIR_', __PS_BASE_URI__.'themes/default/mobile/'); +} +define('_THEME_MOBILE_IMG_DIR_', _THEME_MOBILE_DIR_.'img/'); +define('_THEME_MOBILE_CSS_DIR_', _THEME_MOBILE_DIR_.'css/'); +define('_THEME_MOBILE_JS_DIR_', _THEME_MOBILE_DIR_.'js/'); + +/* For touch pad devices */ +define('_PS_THEME_TOUCHPAD_DIR_', _PS_THEME_DIR_.'touchpad/'); +define('_THEME_TOUCHPAD_DIR_', _THEMES_DIR_._THEME_NAME_.'/touchpad/'); +define('_THEME_TOUCHPAD_CSS_DIR_', _THEME_MOBILE_DIR_.'css/'); +define('_THEME_TOUCHPAD_JS_DIR_', _THEME_MOBILE_DIR_.'js/'); + /* Image URLs */ define('_PS_IMG_', __PS_BASE_URI__.'img/'); define('_PS_ADMIN_IMG_', _PS_IMG_.'admin/'); diff --git a/controllers/admin/AdminThemesController.php b/controllers/admin/AdminThemesController.php index b23e5272f..f588a7ed2 100644 --- a/controllers/admin/AdminThemesController.php +++ b/controllers/admin/AdminThemesController.php @@ -160,6 +160,12 @@ class AdminThemesControllerCore extends AdminController 'type' => 'text', 'size' => 20 ), + 'PS_ALLOW_MOBILE_DEVICE' => array( + 'title' => $this->l('Enable mobile theme'), + 'desc' => $this->l('Allows visitors browsing on a mobile device, to have a light version of website'), + 'cast' => 'intval', + 'type' => 'bool', + ) ), 'submit' => array('title' => $this->l('Save'), 'class' => 'button') ), diff --git a/controllers/front/OrderOpcController.php b/controllers/front/OrderOpcController.php index eb1e47aca..086957ba2 100644 --- a/controllers/front/OrderOpcController.php +++ b/controllers/front/OrderOpcController.php @@ -191,7 +191,7 @@ class OrderOpcControllerCore extends ParentOrderController $this->context->cart->id_address_invoice = Tools::isSubmit('same') ? $this->context->cart->id_address_delivery : (int)(Tools::getValue('id_address_invoice')); if (!$this->context->cart->update()) $this->errors[] = Tools::displayError('An error occurred while updating your cart.'); - + // Address has changed, so we check if the cart rules still apply CartRule::autoRemoveFromCart($this->context); CartRule::autoAddToCart($this->context); @@ -271,11 +271,16 @@ class OrderOpcControllerCore extends ParentOrderController { parent::setMedia(); - // Adding CSS style sheet - $this->addCSS(_THEME_CSS_DIR_.'order-opc.css'); - // Adding JS files - $this->addJS(_THEME_JS_DIR_.'order-opc.js'); - $this->addJqueryPlugin('scrollTo'); + if ($this->context->getMobileDevice() == false) + { + // Adding CSS style sheet + $this->addCSS(_THEME_CSS_DIR_.'order-opc.css'); + // Adding JS files + $this->addJS(_THEME_JS_DIR_.'order-opc.js'); + $this->addJqueryPlugin('scrollTo'); + } + else + $this->addJS(_THEME_MOBILE_JS_DIR_.'opc.js'); $this->addJS(_THEME_JS_DIR_.'tools/statesManagement.js'); } diff --git a/controllers/front/ProductController.php b/controllers/front/ProductController.php index 4b5965c9e..28508eeee 100644 --- a/controllers/front/ProductController.php +++ b/controllers/front/ProductController.php @@ -41,13 +41,25 @@ class ProductControllerCore extends FrontController { parent::setMedia(); - $this->addCSS(_THEME_CSS_DIR_.'product.css'); - $this->addCSS(_PS_CSS_DIR_.'jquery.fancybox-1.3.4.css', 'screen'); - $this->addJqueryPlugin(array('fancybox', 'idTabs', 'scrollTo', 'serialScroll')); - $this->addJS(array( - _THEME_JS_DIR_.'tools.js', - _THEME_JS_DIR_.'product.js' - )); + if ($this->context->getMobileDevice() == false) + { + $this->addCSS(_THEME_CSS_DIR_.'product.css'); + $this->addCSS(_PS_CSS_DIR_.'jquery.fancybox-1.3.4.css', 'screen'); + $this->addJqueryPlugin(array('fancybox', 'idTabs', 'scrollTo', 'serialScroll')); + $this->addJS(array( + _THEME_JS_DIR_.'tools.js', + _THEME_JS_DIR_.'product.js' + )); + } + else + { + $this->addJqueryPlugin(array('scrollTo', 'serialScroll')); + $this->addJS(array( + _THEME_JS_DIR_.'tools.js', + _THEME_MOBILE_JS_DIR_.'product.js', + _THEME_MOBILE_JS_DIR_.'jquery.touch-gallery.js' + )); + } if (Configuration::get('PS_DISPLAY_JQZOOM') == 1) $this->addJqueryPlugin('jqzoom'); diff --git a/modules/blocksearch/blocksearch-top.tpl b/modules/blocksearch/blocksearch-top.tpl index 149df6da9..ed373d4b1 100644 --- a/modules/blocksearch/blocksearch-top.tpl +++ b/modules/blocksearch/blocksearch-top.tpl @@ -23,6 +23,17 @@ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) * International Registered Trademark & Property of PrestaShop SA *} + +{if isset($hook_mobile)} +
- {l s='My wishlists' mod='blockwishlist'}
+
{l s='My wishlists' mod='blockwishlist'}
{/if}
+ {if !$in_footer}{l s='We\'re sorry, but the Web address you entered is no longer available'}
+{l s='To find a product, please type its name in the field below'}
++ {if isset($id_address) && (isset($smarty.post.alias) || isset($address->alias))} + {l s='Modify address'} + {if isset($smarty.post.alias)} + "{$smarty.post.alias}" + {else} + {if isset($address->alias)}"{$address->alias|escape:'htmlall':'UTF-8'}"{/if} + {/if} + {else} + {l s='To add a new address, please fill out the form below.'} + {/if} +
+ +