diff --git a/admin-dev/ajax.php b/admin-dev/ajax.php
index 876370c4c..2919c874e 100644
--- a/admin-dev/ajax.php
+++ b/admin-dev/ajax.php
@@ -562,11 +562,11 @@ if (Tools::isSubmit('getHookableList'))
die('{"hasError" : true, "errors" : ["Live Edit : This functionnality has been disabled"]}');
/* PrestaShop demo mode*/
- if (!strlen(Tools::getValue('hooks_list')))
+ if (!count(Tools::getValue('hooks_list')))
die('{"hasError" : true, "errors" : ["Live Edit : no module on this page"]}');
- $modules_list = explode(',', Tools::getValue('modules_list'));
- $hooks_list = explode(',', Tools::getValue('hooks_list'));
+ $modules_list = Tools::getValue('modules_list');
+ $hooks_list = Tools::getValue('hooks_list');
$hookableList = array();
foreach ($modules_list as $module)
@@ -629,35 +629,34 @@ if (Tools::isSubmit('saveHook'))
$res = true;
$hookableList = array();
- foreach ($hooks_list as $hook)
+ // $_POST['hook'] is an array of id_module
+ $hooks_list = Tools::getValue('hook');
+ foreach ($hooks_list as $id_hook => $modules)
{
- $hook = trim($hook);
- if (!$hook)
- continue;
-
- $sql = 'DELETE FROM '._DB_PREFIX_.'hook_module
- WHERE id_hook = ( SELECT id_hook
- FROM '._DB_PREFIX_.'hook
- WHERE `name` = \''.pSQL($hook).'\' LIMIT 1
- )
+ // 1st, drop all previous hooked modules
+ $sql = 'DELETE FROM `'._DB_PREFIX_.'hook_module`
+ WHERE `id_hook` = '.(int)$id_hook.'
AND id_shop = '.$id_shop;
$res &= Db::getInstance()->execute($sql);
- $hookedModules = explode(',', Tools::getValue($hook));
+
$i = 1;
$value = '';
$ids = array();
- foreach ($hookedModules as $module)
+ // then prepare sql query to rehook all chosen modules(id_module, id_shop, id_hook, position)
+ // position is i (autoincremented)
+ foreach ($modules as $id_module)
{
- $id = explode('_', $module);
- if (!in_array($id[1], $ids))
+ if (!in_array($id_module, $ids))
{
- $ids[] = $id[1];
- $value .= '('.(int)$id[1].', '.$id_shop.', (SELECT id_hook FROM `'._DB_PREFIX_.'hook` WHERE `name` = \''.pSQL($hook).'\' LIMIT 0, 1), '.$i.'),';
+ $ids[] = $id_module;
+ $value .= '('.(int)$id_module.', '.$id_shop.', '.(int)$id_hook.', '.$i.'),';
}
$i++;
}
$value = rtrim($value, ',');
- $res &= Db::getInstance()->execute('INSERT INTO '._DB_PREFIX_.'hook_module (id_module, id_shop, id_hook, position) VALUES '.$value);
+ $res &= Db::getInstance()->execute('INSERT INTO `'._DB_PREFIX_.'hook_module`
+ (id_module, id_shop, id_hook, position)
+ VALUES '.$value);
}
if ($res)
diff --git a/classes/Controller.php b/classes/Controller.php
index 8579d8e89..f5b307835 100644
--- a/classes/Controller.php
+++ b/classes/Controller.php
@@ -73,6 +73,9 @@ abstract class ControllerCore
protected $status = '';
protected $redirect_after = null;
+
+ /** hook_list is used with liveEdit */
+ public $hook_list = array();
/**
* check that the controller is available for the current user/visitor
*/
diff --git a/classes/FrontController.php b/classes/FrontController.php
index 80740b60c..a890329e3 100755
--- a/classes/FrontController.php
+++ b/classes/FrontController.php
@@ -374,6 +374,13 @@ class FrontControllerCore extends Controller
public function initContent()
{
$this->process();
+
+ $this->context->smarty->assign(array(
+ 'HOOK_HEADER' => Hook::exec('displayHeader'),
+ 'HOOK_TOP' => Hook::exec('displayTop'),
+ 'HOOK_LEFT_COLUMN' => Hook::exec('displayLeftColumn'),
+ 'HOOK_RIGHT_COLUMN' => Hook::exec('displayRightColumn', array('cart' => $this->context->cart)),
+ ));
}
public function initCursedPage()
@@ -393,23 +400,40 @@ class FrontControllerCore extends Controller
public function display()
{
Tools::safePostVars();
- $this->context->smarty->assign('errors', $this->errors);
- if ($this->display_header)
- $this->context->smarty->display(_PS_THEME_DIR_.'header.tpl');
-
- if ($this->template)
- $this->context->smarty->display($this->template);
-
- if ($this->display_footer)
- $this->context->smarty->display(_PS_THEME_DIR_.'footer.tpl');
-
- // live edit
- if (Tools::isSubmit('live_edit') AND $ad = Tools::getValue('ad') AND (Tools::getValue('liveToken') == sha1(Tools::getValue('ad')._COOKIE_KEY_)))
+ // assign css_files and js_files at the very last time
+ if ((Configuration::get('PS_CSS_THEME_CACHE') OR Configuration::get('PS_JS_THEME_CACHE')) AND is_writable(_PS_THEME_DIR_.'cache'))
{
- $this->context->smarty->assign(array('ad' => $ad, 'live_edit' => true));
- $this->context->smarty->display(_PS_ALL_THEMES_DIR_.'live_edit.tpl');
+ // CSS compressor management
+ if (Configuration::get('PS_CSS_THEME_CACHE'))
+ $this->css_files = Media::cccCSS($this->css_files);
+ //JS compressor management
+ if (Configuration::get('PS_JS_THEME_CACHE'))
+ $this->js_files = Media::cccJs($this->js_files);
}
+
+ $this->context->smarty->assign('css_files', $this->css_files);
+ $this->context->smarty->assign('js_files', array_unique($this->js_files));
+
+ $this->context->smarty->assign(array(
+ 'errors' => $this->errors,
+ 'display_header' => $this->display_header,
+ 'display_footer' => $this->display_footer,
+ 'template' => $this->context->smarty->fetch($this->template),
+ ));
+
+
+
+
+ if (Tools::isSubmit('live_edit'))
+ {
+ $this->context->smarty->assign('live_edit', $this->getLiveEditFooter());
+ }
+
+
+ $this->context->smarty->display(_PS_THEME_DIR_.'layout.tpl');
+
+ return true;
}
/* Display a maintenance page if shop is closed */
@@ -549,31 +573,37 @@ class FrontControllerCore extends Controller
'priceDisplayPrecision' => _PS_PRICE_DISPLAY_PRECISION_,
'content_only' => (int)Tools::getValue('content_only')
));
- $this->context->smarty->assign(array(
- 'HOOK_HEADER' => Hook::exec('header'),
- 'HOOK_TOP' => Hook::exec('top'),
- 'HOOK_LEFT_COLUMN' => Hook::exec('leftColumn')
- ));
- if ((Configuration::get('PS_CSS_THEME_CACHE') OR Configuration::get('PS_JS_THEME_CACHE')) AND is_writable(_PS_THEME_DIR_.'cache'))
- {
- // CSS compressor management
- if (Configuration::get('PS_CSS_THEME_CACHE'))
- $this->css_files = Media::cccCSS($this->css_files);
- //JS compressor management
- if (Configuration::get('PS_JS_THEME_CACHE'))
- $this->js_files = Media::cccJs($this->js_files);
- }
- $this->context->smarty->assign('css_files', $this->css_files);
- $this->context->smarty->assign('js_files', array_unique($this->js_files));
+
+
}
public function initFooter()
{
$this->context->smarty->assign(array(
- 'HOOK_RIGHT_COLUMN' => Hook::exec('rightColumn', array('cart' => $this->context->cart)),
'HOOK_FOOTER' => Hook::exec('footer'),
));
+
+
+ }
+
+ public function getLiveEditFooter(){
+ if (Tools::isSubmit('live_edit')
+ && ($ad = Tools::getValue('ad'))
+ && (Tools::getValue('liveToken') == sha1(Tools::getValue('ad')._COOKIE_KEY_))
+ )
+ {
+ $data = $this->context->smarty->createData();
+ $data->assign(array(
+ 'ad' => $ad,
+ 'live_edit' => true,
+ 'hook_list' => $this->hook_list,
+ 'id_shop' => $this->context->shop->getId(true)
+ ));
+ return $this->context->smarty->createTemplate(_PS_ALL_THEMES_DIR_.'live_edit.tpl', $data)->fetch();
+ }
+ else
+ return '';
}
public function productSort()
diff --git a/classes/Hook.php b/classes/Hook.php
index 14aad0bec..560a6bb55 100644
--- a/classes/Hook.php
+++ b/classes/Hook.php
@@ -62,7 +62,7 @@ class HookCore extends ObjectModel
return false;
$hook_alias_list = Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'hook_alias`');
foreach ($hook_alias_list as $ha)
- self::$_hook_alias[strtolower($ha['alias'])] = $ha['name'];
+ self::$_hook_alias[strtolower($ha['name'])] = $ha['alias'];
return true;
}
@@ -220,7 +220,9 @@ class HookCore extends ObjectModel
// Get retrocompatible hook name
$retro_hook_name = Hook::getRetroHookName($hook_name);
- // Get cookie and cart
+ if (!in_array($hook_name, Context::getContext()->controller->hook_list))
+ Context::getContext()->controller->hook_list[Hook::getIdByName($hook_name)] = $hook_name;
+
$live_edit = false;
if (!isset($hookArgs['cookie']) || !$hookArgs['cookie'])
$hookArgs['cookie'] = $context->cookie;
diff --git a/js/hookLiveEdit.js b/js/hookLiveEdit.js
index d9a401908..d7cc85522 100644
--- a/js/hookLiveEdit.js
+++ b/js/hookLiveEdit.js
@@ -3,123 +3,158 @@ var hooks_list = new Array();
var hookable_list = new Array();
var timer;
$(document).ready(function() {
- $('body').css('margin-bottom', '45px');
- $('#fancy').fancybox({
- autoDimensions: true,
- autoScale: true,
- width: 300,
- height: 300,
- padding: 0,
- hideOnOverlayClick: false,
- hideOnContentClick: false,
- showCloseButton: false
- });
- $('#live_edit_feedback_str').html('');
- $('a').each(function() {
- var href = $(this).attr('href');
- var search = $(this).attr('search');
- var hrefAdd = 'live_edit&liveToken=' + get('liveToken') + '&ad=' + get('ad') + '&id_shop=' + get('id_shop');
- if (href != undefined && href != '#' && href.substr(0, baseDir.length) == baseDir) {
- if (search.length == 0) {
- $(this).attr('search', hrefAdd);
- } else {
- $(this).attr('search', search + '&' + hrefAdd);
- }
- }
- });
- getHookableList();
- $('.unregisterHook').unbind('click').click(function() {
- id = $(this).attr('id');
- $(this).parent().parent().parent().fadeOut('slow', function() {
- $(this).remove();
- });
- return false;
- });
- $('#cancelMove').unbind('click').click(function() {
- $('#' + cancelMove + '').sortable('cancel');
- return false;
- });
- $('#saveLiveEdit').unbind('click').click(function() {
- saveModulePosition();
- return false;
- });
- $('#closeLiveEdit').unbind('click').click(function() {
- $("#live_edit_feedback_str").html('
');
- $("#fancy").attr('href', '#live_edit_feedback');
- $("#fancy").trigger("click");
- });
- $('.add_module_live_edit').unbind('click').click(function() {
- $("#live_edit_feedback_str").html('');
- $("#fancy").attr('href', '#live_edit_feedback');
- $("#fancy").trigger("click");
- var id = $(this).attr('id');
- getHookableModuleList(id.substr(4, id.length));
- return false;
- });
- $('.dndHook').each(function() {
- var id_hook = $(this).attr('id');
- var new_target = '';
- var old_target = '';
- var cancel = false;
- $('#' + id_hook + '').sortable({
- opacity: 0.5,
- cursor: 'move',
- connectWith: '.dndHook',
- receive: function(event, ui) {
- if (new_target == '') {
- new_target = event.target.id;
- }
- },
- start: function(event, ui) {
- new_target = ui.item[0].parentNode.id;
- },
- stop: function(event, ui) {
- if (cancel) {
- $(this).sortable('cancel');
- } else {
- old_target = event.target.id;
- cancelMove = old_target;
- if (new_target == '') new_target = old_target;
- }
- },
- change: function(event, ui) {
- new_target = $(ui.placeholder).parent().attr('id');
- ids = ui.item[0].id.split('_');
- if ($.inArray(ids[5], hookable_list[new_target]) != -1) {
- cancel = false;
- ui.placeholder.css({
- visibility: 'visible',
- border: '1px solid #72CB67',
- background: '#DFFAD3'
- });
- } else {
- ui.placeholder.css({
- visibility: 'visible',
- border: '1px solid #EC9B9B',
- background: '#FAE2E3'
- });
- cancel = true;
- }
- }
- });
- $('#' + id_hook + '').disableSelection();
- });
-});
+ // do some place for submit button
+ $('body').css('margin-bottom', '45px');
+ // this is the result box, which will "pop up" the succeed or fail result
+ $('#fancy').fancybox({
+ autoDimensions: true,
+ autoScale: true,
+ width: 300,
+ height: 300,
+ padding: 0,
+ hideOnOverlayClick: false,
+ hideOnContentClick: false,
+ showCloseButton: false
+ });
+
+ $('#live_edit_feedback_str').html('');
+ // add liveToken in each link to navigate into the shop and keeping the liveedit mode
+ $('a').each(function() {
+ var href = $(this).attr('href');
+ var search = $(this).attr('search');
+ var hrefAdd = 'live_edit&liveToken=' + get('liveToken') + '&ad=' + get('ad') + '&id_shop=' + get('id_shop');
+ if (href != undefined && href != '#' && href.substr(0, baseDir.length) == baseDir) {
+ if (search.length == 0)
+ {
+ $(this).attr('search', hrefAdd);
+ }
+ else
+ {
+ $(this).attr('search', search + '&' + hrefAdd);
+ }
+ }
+ });
+ // populate
+ getHookableList();
+ $('.unregisterHook').unbind('click').click(function() {
+ id = $(this).attr('id');
+ $(this).parent().parent().parent().fadeOut('slow', function() {
+ $(this).remove();
+ });
+ return false;
+ });
+ $('#cancelMove').unbind('click').click(function() {
+ $('#' + cancelMove + '').sortable('cancel');
+ return false;
+ });
+ $('#saveLiveEdit').unbind('click').click(function() {
+ saveModulePosition();
+ return false;
+ });
+ $('#closeLiveEdit').unbind('click').click(function() {
+ $("#live_edit_feedback_str").html('');
+ $("#fancy").attr('href', '#live_edit_feedback');
+ $("#fancy").trigger("click");
+ });
+ $('.add_module_live_edit').unbind('click').click(function() {
+ $("#live_edit_feedback_str").html('');
+ $("#fancy").attr('href', '#live_edit_feedback');
+ $("#fancy").trigger("click");
+ var id = $(this).attr('id');
+ getHookableModuleList(id.substr(4, id.length));
+ return false;
+ });
+ $('.dndHook').each(function() {
+ var id_hook = $(this).attr('id');
+ var new_target_id = '';
+ var old_target = '';
+ var cancel = false;
+ $('#' + id_hook + '').sortable({
+ opacity: 0.5,
+ cursor: 'move',
+ connectWith: '.dndHook',
+ receive: function(event, ui) {
+ if (new_target_id == '') {
+ new_target_id = event.target.id;
+ }
+ },
+ start: function(event, ui) {
+ new_target_id = ui.item[0].parentNode.id;
+ },
+ stop: function(event, ui) {
+ if (cancel)
+ {
+ $(this).sortable('cancel');
+ }
+ else
+ {
+ old_target = event.target.id;
+ cancelMove = old_target;
+ if (new_target_id == '')
+ new_target_id = old_target;
+ ids = $(ui.item[0]).attr('id').split('_');
+ newHookId = $("input[value="+new_target_id+"]").attr('name').substr(10);
+ newHookId = newHookId.substr(0, newHookId.length -1);
+ new_id = ids[0] + "_" + newHookId + "_" + ids[2] + "_" + ids[3];
+ $(ui.item[0]).attr('id', new_id);
+ }
+ },
+ change: function(evartent, ui) {
+ new_target_id = $(ui.placeholder).parent().attr('id');
+ ids = ui.item[0].id.split('_');
+ if ($.inArray(ids[5], hookable_list[new_target_id]) != -1) {
+ cancel = false;
+ ui.placeholder.css({
+ visibility: 'visible',
+ border: '1px solid #72CB67',
+ background: '#DFFAD3'
+ });
+ }
+ else
+ {
+ ui.placeholder.css({
+ visibility: 'visible',
+ border: '1px solid #EC9B9B',
+ background: '#FAE2E3'
+ });
+ cancel = true;
+ }
+ }
+ });
+ // WTF
+ $('#' + id_hook + '').disableSelection();
+ });
+});
+// init hookable_list
function getHookableList() {
+ hooks_list = new Array();
+ $("input[name^=hook_list]}").each(function(e){
+ hooks_list.push($(this).val());
+ // +$(this).val();
+ });
+
$.ajax({
- type: 'GET',
+ type: 'POST',
url: baseDir + ad + '/ajax.php',
async: true,
dataType: 'json',
- data: 'ajax=true&getHookableList&hooks_list=' + hooks_list + '&modules_list=' + modules_list + '&id_shop=' + get('id_shop'),
+ data: {ajax:"true",
+ 'getHookableList':1,
+ 'hooks_list' : hooks_list,
+ modules_list : modules_list,
+ id_shop : get('id_shop')
+ },
success: function(jsonData) {
if (jsonData.hasError) {
var errors = '';
for (error in jsonData.errors) //IE6 bug fix
- if (error != 'indexOf') errors += jsonData.errors[error] + "\n";
- alert(errors);
- } else hookable_list = jsonData;
+ if (error != 'indexOf')
+ errors += jsonData.errors[error] + "\n";
+ alert(errors);
+ }
+ else
+ hookable_list = jsonData;// create and fill input array
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
$('#live_edit_feedback_str').html('');
@@ -149,6 +184,7 @@ function getHookableModuleList(hook) {
});
}
function saveModulePosition() {
+ $("input.dynamic-input-save-position").remove();
$("#live_edit_feedback_str").html('');
$("#fancy").attr('href', '#live_edit_feedback');
$("#fancy").trigger("click");
@@ -157,47 +193,56 @@ function saveModulePosition() {
str += '&' + hooks_list[i] + '=';
$('#' + hooks_list[i] + ' > .dndModule').each(function() {
ids = $(this).attr('id').split('_');
- str += ids[1] + '_' + ids[3] + ',';
+ $("#liveEdit-action-form")
+ .append(' ');
});
- str = str.substr(0, str.length - 1);
+
}
+ $("#liveEdit-action-form")
+ .append(' ');
+ datas = $("#liveEdit-action-form").serializeArray();
+
$.ajax({
- type: 'GET',
- url: baseDir + ad + '/ajax.php',
+ type: 'POST',
+ url: baseDir + ad + "/ajax.php",
async: true,
dataType: 'json',
- data: 'ajax=true&saveHook&hooks_list=' + hooks_list + str + '&id_shop=' + get('id_shop'),
+ data: datas,
success: function(jsonData) {
- $('#live_edit_feedback_str').html('');
+ $('#live_edit_feedback_str').html('');
timer = setTimeout("hideFeedback()", 3000);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
$('#live_edit_feedback_str').html('');
}
- });
+}
+)
+
+ return true;
}
function closeFancybox() {
- clearTimeout(timer);
- $.fancybox.close();
- $('#live_edit_feedback_str').html('');
+ clearTimeout(timer);
+ $.fancybox.close();
+ $('#live_edit_feedback_str').html('');
}
function closeLiveEdit(){
window.location.href = window.location.protocol+'//'+window.location.host+window.location.pathname;
}
function hideFeedback() {
- $('#live_edit_feed_back').fadeOut('slow', function() {
- $.fancybox.close();
- $('#live_edit_feedback_str').html('');
- });
+ $('#live_edit_feed_back').fadeOut('slow', function() {
+ $.fancybox.close();
+ $('#live_edit_feedback_str').html('');
+ });
};
function get(name) {
- var regexS = "[\\?&]" + name + "=([^]*)";
- var regex = new RegExp(regexS);
- var results = regex.exec(window.location.href);
- if (results == null) {
- return "";
- } else {
- return results[1];
- }
+ var regexS = "[\\?&]" + name + "=([^]*)";
+ var regex = new RegExp(regexS);
+ var results = regex.exec(window.location.href);
+ if (results == null) {
+ return "";
+ }
+ else {
+ return results[1];
+ }
}
diff --git a/themes/default/index.tpl b/themes/default/index.tpl
index 04a4a1b6d..319d97a78 100644
--- a/themes/default/index.tpl
+++ b/themes/default/index.tpl
@@ -24,4 +24,4 @@
* International Registered Trademark & Property of PrestaShop SA
*}
-{$HOOK_HOME}
\ No newline at end of file
+{$HOOK_HOME}
diff --git a/themes/default/layout.tpl b/themes/default/layout.tpl
new file mode 100644
index 000000000..edbec661a
--- /dev/null
+++ b/themes/default/layout.tpl
@@ -0,0 +1,37 @@
+{*
+* 2007-2011 PrestaShop
+*
+* NOTICE OF LICENSE
+*
+* This source file is subject to the Academic Free License (AFL 3.0)
+* that is bundled with this package in the file LICENSE.txt.
+* It is also available through the world-wide-web at this URL:
+* http://opensource.org/licenses/afl-3.0.php
+* If you did not receive a copy of the license and are unable to
+* obtain it through the world-wide-web, please send an email
+* to license@prestashop.com so we can send you a copy immediately.
+*
+* DISCLAIMER
+*
+* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
+* versions in the future. If you wish to customize PrestaShop for your
+* needs please refer to http://www.prestashop.com for more information.
+*
+* @author PrestaShop SA
+* @copyright 2007-2011 PrestaShop SA
+* @version Release: $Revision$
+* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+* International Registered Trademark & Property of PrestaShop SA
+*}
+{if isset($display_header)}
+ {include file='./header.tpl' HOOK_HEADER=$HOOK_HEADER}
+{/if}
+{if isset($template)}
+ {$template}
+{/if}
+{if isset($display_footer)}
+ {include file='./footer.tpl'}
+{/if}
+{if isset($live_edit)}
+ {$live_edit}
+{/if}
diff --git a/themes/live_edit.tpl b/themes/live_edit.tpl
index 431c933c2..9cc7b0235 100644
--- a/themes/live_edit.tpl
+++ b/themes/live_edit.tpl
@@ -24,8 +24,8 @@
* International Registered Trademark & Property of PrestaShop SA
*}