diff --git a/.gitignore b/.gitignore index 035aaa4c5..891e865a8 100644 --- a/.gitignore +++ b/.gitignore @@ -114,4 +114,23 @@ modules/uspscarrier modules/wexpay modules/yotpo modules/zingaya +modules/bankwire +modules/blockwishlist +modules/carriercompare +modules/cashondelivery +modules/cheque +modules/dateofdelivery +modules/editorial +modules/favoriteproducts +modules/feeder +modules/followup +modules/gapi +modules/loyalty +modules/mailalerts +modules/newsletter +modules/productcomments +modules/pscleaner +modules/referralprogram +modules/sendtoafriend +modules/watermark admin-dev/themes/default/bower_components diff --git a/admin-dev/themes/default/template/controllers/carrier_wizard/helpers/form/form.tpl b/admin-dev/themes/default/template/controllers/carrier_wizard/helpers/form/form.tpl index f6ddbe690..7daee2ae5 100644 --- a/admin-dev/themes/default/template/controllers/carrier_wizard/helpers/form/form.tpl +++ b/admin-dev/themes/default/template/controllers/carrier_wizard/helpers/form/form.tpl @@ -59,14 +59,9 @@

+ +
diff --git a/admin-dev/themes/default/template/helpers/uploader/simple.tpl b/admin-dev/themes/default/template/helpers/uploader/simple.tpl index 8da9a642d..8d8bbd0b7 100644 --- a/admin-dev/themes/default/template/helpers/uploader/simple.tpl +++ b/admin-dev/themes/default/template/helpers/uploader/simple.tpl @@ -49,7 +49,7 @@
{else}
-
+
diff --git a/classes/controller/FrontController.php b/classes/controller/FrontController.php index fee2d0924..3ad4f2e42 100644 --- a/classes/controller/FrontController.php +++ b/classes/controller/FrontController.php @@ -162,7 +162,7 @@ class FrontControllerCore extends Controller /* Theme is missing */ if (!is_dir(_PS_THEME_DIR_)) - die(sprintf(Tools::displayError('Current theme unavailable "%s". Please check your theme directory name and permissions.'), basename(rtrim(_PS_THEME_DIR_, '/\\')))); + throw new PrestaShopException((sprintf(Tools::displayError('Current theme unavailable "%s". Please check your theme directory name and permissions.'), basename(rtrim(_PS_THEME_DIR_, '/\\'))))); if (Configuration::get('PS_GEOLOCATION_ENABLED')) if (($newDefault = $this->geolocationManagement($this->context->country)) && Validate::isLoadedObject($newDefault)) diff --git a/classes/exception/PrestaShopException.php b/classes/exception/PrestaShopException.php index 465bf0ddd..7cc56f203 100644 --- a/classes/exception/PrestaShopException.php +++ b/classes/exception/PrestaShopException.php @@ -66,14 +66,15 @@ class PrestaShopExceptionCore extends Exception echo ''.((isset($trace['class'])) ? $trace['class'] : '').((isset($trace['type'])) ? $trace['type'] : '').$trace['function'].''; echo ' - [line '.$current_line.' - '.$relative_file.']'; - if (count($trace['args'])) + if (isset($trace['args']) && count($trace['args'])) echo ' - ['.count($trace['args']).' Arguments]'; else echo ' - [0 Argument]'; if ($relative_file) $this->displayFileDebug($trace['file'], $trace['line'], $id); - $this->displayArgsDebug($trace['args'], $id); + if (isset($trace['args']) && count($trace['args'])) + $this->displayArgsDebug($trace['args'], $id); echo ''; } echo ''; diff --git a/config/config.inc.php b/config/config.inc.php index 763f3a135..22d6f9ea3 100644 --- a/config/config.inc.php +++ b/config/config.inc.php @@ -93,13 +93,14 @@ $context = Context::getContext(); try { $context->shop = Shop::initialize(); + if (Tools::isEmpty($theme_name = $context->shop->getTheme()) && !defined('_PS_ADMIN_DIR_')) + throw new PrestaShopException(Tools::displayError('Current theme unselected. Please check your theme configuration.')); } catch (PrestaShopException $e) { $e->displayMessage(); } - -define('_THEME_NAME_', $context->shop->getTheme()); +define('_THEME_NAME_', $theme_name); define('__PS_BASE_URI__', $context->shop->getBaseURI()); /* Include all defines related to base uri and theme name */ diff --git a/controllers/admin/AdminCategoriesController.php b/controllers/admin/AdminCategoriesController.php index de4877ab0..7acdccd79 100644 --- a/controllers/admin/AdminCategoriesController.php +++ b/controllers/admin/AdminCategoriesController.php @@ -477,9 +477,8 @@ class AdminCategoriesControllerCore extends AdminController 'display_image' => true, 'image' => $image_url ? $image_url : false, 'size' => $image_size, - 'delete_url' => self::$currentIndex.'&'.$this->identifier.'='.$this->id.'&token='.$this->token.'&deleteImage=1', + 'delete_url' => self::$currentIndex.'&'.$this->identifier.'='.$this->_category->id.'&token='.$this->token.'&deleteImage=1', 'hint' => $this->l('Upload a category logo from your computer.'), - 'col' => 4 ), array( 'type' => 'text', @@ -602,7 +601,7 @@ class AdminCategoriesControllerCore extends AdminController { if (!in_array($this->display, array('edit', 'add'))) $this->multishop_context_group = false; - if (Tools::isSubmit('forcedeleteImage') || (isset($_FILES['image']) && $_FILES['image']['size'] > 0)) + if (Tools::isSubmit('forcedeleteImage') || (isset($_FILES['image']) && $_FILES['image']['size'] > 0) || Tools::getValue('deleteImage')) { $this->processForceDeleteImage(); if (Tools::isSubmit('forcedeleteImage')) diff --git a/controllers/admin/AdminProductsController.php b/controllers/admin/AdminProductsController.php index da1761cce..c65f0ce85 100644 --- a/controllers/admin/AdminProductsController.php +++ b/controllers/admin/AdminProductsController.php @@ -444,6 +444,120 @@ class AdminProductsControllerCore extends AdminController } } + public function ajaxProcessAddAttachment() + { + if (isset($_FILES['attachment_file'])) + { + if ((int)$_FILES['attachment_file']['error'] === 1) + { + $_FILES['attachment_file']['error'] = array(); + + $max_upload = (int)ini_get('upload_max_filesize'); + $max_post = (int)ini_get('post_max_size'); + $upload_mb = min($max_upload, $max_post); + $_FILES['attachment_file']['error'][] = sprintf( + $this->l('The file %1$s exceeds the size allowed by the server. The limit is set to %2$d MB.'), + ''.$_FILES['attachment_file']['name'].' ', + ''.$upload_mb.'' + ); + } + + $_FILES['attachment_file']['error'] = array(); + + $is_attachment_name_valid = false; + $attachment_names = Tools::getValue('attachment_name'); + $attachment_descriptions = Tools::getValue('attachment_description'); + + if (!isset($attachment_names) || !$attachment_names) + $attachment_names = array(); + + if (!isset($attachment_descriptions) || !$attachment_descriptions) + $attachment_descriptions = array(); + + foreach ($attachment_names as $lang => $name) + { + if (Tools::strlen($name) > 0) + $is_attachment_name_valid = true; + + if (!Validate::isGenericName($name)) + $_FILES['attachment_file']['error'][] = sprintf(Tools::displayError('Invalid name for %s language'), Language::getLanguage((int)$lang)['name']); + elseif (Tools::strlen($name) > 32) + $_FILES['attachment_file']['error'][] = sprintf(Tools::displayError('The name for %1s language is too long (%2d chars max).'), Language::getLanguage((int)$lang)['name'], 32); + } + + foreach ($attachment_descriptions as $lang => $description) + if (!Validate::isCleanHtml($description)) + $_FILES['attachment_file']['error'][] = sprintf(Tools::displayError('Invalid description for %s language'), Language::getLanguage((int)$lang)['name']); + + if (!$is_attachment_name_valid) + $_FILES['attachment_file']['error'][] = Tools::displayError('An attachment name is required.'); + + if (empty($_FILES['attachment_file']['error'])) + { + if (is_uploaded_file($_FILES['attachment_file']['tmp_name'])) + { + if ($_FILES['attachment_file']['size'] > (Configuration::get('PS_ATTACHMENT_MAXIMUM_SIZE') * 1024 * 1024)) + $_FILES['attachment_file']['error'][] = sprintf( + $this->l('The file is too large. Maximum size allowed is: %1$d kB. The file you\'re trying to upload is: %2$d kB.'), + (Configuration::get('PS_ATTACHMENT_MAXIMUM_SIZE') * 1024), + number_format(($_FILES['attachment_file']['size'] / 1024), 2, '.', '') + ); + else + { + do $uniqid = sha1(microtime()); + while (file_exists(_PS_DOWNLOAD_DIR_.$uniqid)); + if (!copy($_FILES['attachment_file']['tmp_name'], _PS_DOWNLOAD_DIR_.$uniqid)) + $_FILES['attachment_file']['error'][] = $this->l('File copy failed'); + @unlink($_FILES['attachment_file']['tmp_name']); + } + } + else + $_FILES['attachment_file']['error'][] = Tools::displayError('The file is missing.'); + + if (empty($_FILES['attachment_file']['error']) && isset($uniqid)) + { + $attachment = new Attachment(); + + foreach ($attachment_names as $lang => $name) + $attachment->name[(int)$lang] = $name; + + foreach ($attachment_descriptions as $lang => $description) + $attachment->description[(int)$lang] = $description; + + $attachment->file = $uniqid; + $attachment->mime = $_FILES['attachment_file']['type']; + $attachment->file_name = $_FILES['attachment_file']['name']; + + if (empty($attachment->mime) || Tools::strlen($attachment->mime) > 128) + $_FILES['attachment_file']['error'][] = Tools::displayError('Invalid file extension'); + if (!Validate::isGenericName($attachment->file_name)) + $_FILES['attachment_file']['error'][] = Tools::displayError('Invalid file name'); + if (Tools::strlen($attachment->file_name) > 128) + $_FILES['attachment_file']['error'][] = Tools::displayError('The file name is too long.'); + if (empty($this->errors)) + { + $res = $attachment->add(); + if (!$res) + $_FILES['attachment_file']['error'][] = Tools::displayError('This attachment was unable to be loaded into the database.'); + else + { + $_FILES['attachment_file']['id_attachment'] = $attachment->id; + $_FILES['attachment_file']['filename'] = $attachment->name[$this->context->employee->id_lang]; + $id_product = (int)Tools::getValue($this->identifier); + $res = $attachment->attachProduct($id_product); + if (!$res) + $_FILES['attachment_file']['error'][] = Tools::displayError('We were unable to associate this attachment to a product.'); + } + } + else + $_FILES['attachment_file']['error'][] = Tools::displayError('Invalid file'); + } + } + + die(Tools::jsonEncode($_FILES)); + } + } + /** * Upload new attachment * @@ -3472,7 +3586,8 @@ class AdminProductsControllerCore extends AdminController 'default_form_language' => (int)Configuration::get('PS_LANG_DEFAULT'), 'attachment_name' => $attachment_name, 'attachment_description' => $attachment_description, - 'PS_ATTACHMENT_MAXIMUM_SIZE' => Configuration::get('PS_ATTACHMENT_MAXIMUM_SIZE') + 'PS_ATTACHMENT_MAXIMUM_SIZE' => Configuration::get('PS_ATTACHMENT_MAXIMUM_SIZE'), + 'post_max_size' => (Configuration::get('PS_ATTACHMENT_MAXIMUM_SIZE') * 1024 * 1024) )); } else @@ -3481,7 +3596,27 @@ class AdminProductsControllerCore extends AdminController else $this->displayWarning($this->l('You must save this product before adding attachements.')); - $this->tpl_form_vars['custom_form'] = $data->fetch(); + $admin_webpath = str_ireplace(_PS_ROOT_DIR_, '', _PS_ADMIN_DIR_); + $admin_webpath = preg_replace('/^'.preg_quote(DIRECTORY_SEPARATOR, '/').'/', '', $admin_webpath); + $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'; + + $html = ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + + $this->tpl_form_vars['custom_form'] = $html.$data->fetch(); } public function initFormInformations($product) diff --git a/js/admin_carrier_wizard.js b/js/admin_carrier_wizard.js index b762d488e..0430ed030 100644 --- a/js/admin_carrier_wizard.js +++ b/js/admin_carrier_wizard.js @@ -23,6 +23,7 @@ * International Registered Trademark & Property of PrestaShop SA */ +var fees_is_hide = false; $(document).ready(function() { bind_inputs(); @@ -30,7 +31,7 @@ $(document).ready(function() { if (parseInt($('input[name="is_free"]:checked').val())) is_freeClick($('input[name="is_free"]:checked')); displayRangeType(); - + checkAllZones(); }); function initCarrierWizard() @@ -70,7 +71,7 @@ function displayRangeType() function onShowStepCallback() { - $('.anchor li a').each( function () { + $('.anchor li a').each(function () { $(this).closest('li').addClass($(this).attr('class')); }); $('#carrier_logo_block').prependTo($('div.content').filter(function() { return $(this).css('display') != 'none' }).find('.defaultForm').find('fieldset')); @@ -151,13 +152,13 @@ function displaySummary() var range_inf = summary_translation_undefined; var range_sup = summary_translation_undefined; - $('tr.range_inf td input').each( function() + $('tr.range_inf td input').each(function() { if (!isNaN(parseFloat($(this).val())) && (range_inf == summary_translation_undefined || parseFloat(range_inf) > parseFloat($(this).val()))) range_inf = $(this).val(); }); - $('tr.range_sup td input').each( function(){ + $('tr.range_sup td input').each(function(){ if (!isNaN(parseFloat($(this).val())) && (range_sup == summary_translation_undefined || parseFloat(range_sup) < parseFloat($(this).val()))) range_sup = $(this).val(); @@ -218,7 +219,7 @@ function validateSteps(fromStep, toStep) { is_ok = false; - $('input').focus( function () { + $('div.input-group input').focus(function () { $(this).removeClass('field_error'); }); displayError(datas.errors, fromStep); @@ -254,7 +255,7 @@ function resizeWizard() function bind_inputs() { - $('input').focus( function () { + $('div.input-group input').focus(function () { $(this).removeClass('field_error'); $('.wizard_error').fadeOut('fast', function () { $(this).remove()}); }); @@ -264,7 +265,7 @@ function bind_inputs() { index = $(this).closest('td').index(); $('tr.range_sup td:eq('+index+'), tr.range_inf td:eq('+index+'), tr.fees_all td:eq('+index+'), tr.delete_range td:eq('+index+')').remove(); - $('tr.fees').each( function () { + $('tr.fees').each(function () { $(this).find('td:eq('+index+')').remove(); }); rebuildTabindex(); @@ -272,25 +273,32 @@ function bind_inputs() return false; }); - $('tr.fees td input:checkbox').off('change').on('change', function () { + $('tr.fees td input:checkbox').off('change').on('change', function () + { if($(this).is(':checked')) { - $(this).closest('tr').find('td').each( function () { + $(this).closest('tr').find('td').each(function () { index = $(this).index(); if ($('tr.fees_all td:eq('+index+')').hasClass('validated')) - $(this).find('input:text').removeAttr('disabled'); + { + enableGlobalFees(index); + $(this).find('div.input-group input:text').removeAttr('disabled'); + } + else + disabledGlobalFees(index); }); } else - $(this).closest('tr').find('td').find('input:text').attr('disabled', 'disabled'); + $(this).closest('tr').find('td').find('div.input-group input:text').attr('disabled', 'disabled'); + return false; }); - $('tr.range_sup td input:text, tr.range_inf td input:text').focus( function () { + $('tr.range_sup td input:text, tr.range_inf td input:text').focus(function () { $(this).removeClass('field_error'); }); - $('tr.range_sup td input:text, tr.range_inf td input:text').keypress( function (evn) { + $('tr.range_sup td input:text, tr.range_inf td input:text').keypress(function (evn) { index = $(this).closest('td').index(); if (evn.keyCode == 13) { @@ -302,7 +310,7 @@ function bind_inputs() } }); - $('tr.fees_all td input:text').keypress( function (evn) { + $('tr.fees_all td input:text').keypress(function (evn) { index = $(this).parent('td').index(); if (evn.keyCode == 13) return false; @@ -314,8 +322,8 @@ function bind_inputs() wait: 1000, callback: function() { index = $(this.el).closest('td').index(); - range_sup = $('tr.range_sup td:eq('+index+')').children('input:text').val().trim(); - range_inf = $('tr.range_inf td:eq('+index+')').children('input:text').val().trim(); + range_sup = $('tr.range_sup td:eq('+index+')').find('div.input-group input:text').val().trim(); + range_inf = $('tr.range_inf td:eq('+index+')').find('div.input-group input:text').val().trim(); if (range_sup != '' && range_inf != '') { if (validateRange(index)) @@ -330,7 +338,7 @@ function bind_inputs()    index = $(this).closest('td').index(); val = $(this).val(); $(this).val(''); - $('tr.fees').each( function () { + $('tr.fees').each(function () { $(this).find('td:eq('+index+') input:text:enabled').val(val); }); @@ -369,31 +377,32 @@ function is_freeClick(elt) var is_free = $(elt); if (parseInt(is_free.val())) hideFees(); - else + else if (fees_is_hide) showFees(); } function hideFees() { - $('tr.range_inf td, tr.range_sup td, tr.fees_all td, tr.fees td').each( function () { + $('tr.range_inf td, tr.range_sup td, tr.fees_all td, tr.fees td').each(function () { if ($(this).index() >= 2) { $(this).find('input:text, button').val('').attr('disabled', 'disabled').css('background-color', '#999999').css('border-color', '#999999'); $(this).css('background-color', '#999999'); } }); + fees_is_hide = true; } function showFees() { - $('tr.range_inf td, tr.range_sup td, tr.fees_all td, tr.fees td').each( function () { + $('tr.range_inf td, tr.range_sup td, tr.fees_all td, tr.fees td').each(function () { if ($(this).index() >= 2) { //enable only if zone is active tr = $(this).closest('tr'); validate = $('tr.fees_all td:eq('+$(this).index()+')').hasClass('validated'); if ($(tr).index() > 2 && $(tr).find('td:eq(1) input').attr('checked') && validate || !$(tr).hasClass('range_sup') || !$(tr).hasClass('range_inf')) - $(this).find('input:text').removeAttr('disabled'); + $(this).find('div.input-group input:text').removeAttr('disabled'); $(this).find('input:text, button').css('background-color', '').css('border-color', ''); $(this).find('button').css('background-color', '').css('border-color', '').removeAttr('disabled'); $(this).css('background-color', ''); @@ -409,38 +418,38 @@ function validateRange(index) $('tr.range_inf td input:text').removeClass('field_error'); is_ok = true; - range_sup = parseFloat($('tr.range_sup td:eq('+index+')').find('input:text').val().trim()); - range_inf = parseFloat($('tr.range_inf td:eq('+index+')').find('input:text').val().trim()); + range_sup = parseFloat($('tr.range_sup td:eq('+index+')').find('div.input-group input:text').val().trim()); + range_inf = parseFloat($('tr.range_inf td:eq('+index+')').find('div.input-group input:text').val().trim()); if (isNaN(range_sup) || range_sup.length === 0) { - $('tr.range_sup td:eq('+index+')').find('input:text').addClass('field_error'); + $('tr.range_sup td:eq('+index+')').find('div.input-group input:text').addClass('field_error'); is_ok = false; displayError([invalid_range], $("#carrier_wizard").smartWizard('currentStep')); } else if (is_ok && (isNaN(range_inf) || range_inf.length === 0)) { - $('tr.range_inf td:eq('+index+')').closest('input:text').addClass('field_error'); + $('tr.range_inf td:eq('+index+')').closest('div.input-group input:text').addClass('field_error'); is_ok = false; displayError([invalid_range], $("#carrier_wizard").smartWizard('currentStep')); } else if (is_ok && range_inf >= range_sup) { - $('tr.range_sup td:eq('+index+')').find('input:text').addClass('field_error'); - $('tr.range_inf td:eq('+index+')').find('input:text').addClass('field_error'); + $('tr.range_sup td:eq('+index+')').find('div.input-group input:text').addClass('field_error'); + $('tr.range_inf td:eq('+index+')').find('div.input-group input:text').addClass('field_error'); is_ok = false; displayError([invalid_range], $("#carrier_wizard").smartWizard('currentStep')); } else if (is_ok && index > 2) //check range only if it's not the first range { - $('tr.range_sup td').not('.range_type, .range_sign, tr.range_sup td:last').each( function () + $('tr.range_sup td').not('.range_type, .range_sign, tr.range_sup td:last').each(function () { if ($('tr.fees_all td:eq('+index+')').hasClass('validated')) { is_ok = false; curent_index = $(this).index(); - current_sup = $(this).find('input').val(); + current_sup = $(this).find('div.input-group input').val(); current_inf = $('tr.range_inf td:eq('+curent_index+') input').val(); if ($('tr.range_inf td:eq('+curent_index+1+') input').length) @@ -458,8 +467,8 @@ function validateRange(index) if (!is_ok) { - $('tr.range_sup td:eq('+index+')').find('input:text').addClass('field_error'); - $('tr.range_inf td:eq('+index+')').find('input:text').addClass('field_error'); + $('tr.range_sup td:eq('+index+')').find('div.input-group input:text').addClass('field_error'); + $('tr.range_inf td:eq('+index+')').find('div.input-group input:text').addClass('field_error'); displayError([range_is_overlapping], $("#carrier_wizard").smartWizard('currentStep')); } else @@ -470,28 +479,34 @@ function validateRange(index) function enableZone(index) { - $('tr.fees').each( function () { - if ($(this).find('td:eq(1)').children('input[type=checkbox]:checked').length) - $(this).find('td:eq('+index+')').children('input').removeAttr('disabled'); + $('tr.fees').each(function () { + if ($(this).find('td:eq(1)').find('input[type=checkbox]:checked').length) + $(this).find('td:eq('+index+')').find('div.input-group input').removeAttr('disabled'); }); } function disableZone(index) { - $('tr.fees').each( function () { - $(this).find('td:eq('+index+')').children('input').attr('disabled', 'disabled'); + $('tr.fees').each(function () { + $(this).find('td:eq('+index+')').find('div.input-group input').attr('disabled', 'disabled'); }); } +function checkAllRanges() +{ + +} + function enableRange(index) { - $('tr.fees').each( function () { + $('tr.fees').each(function () { //only enable fees for enabled zones if ($(this).find('td').find('input:checkbox').attr('checked') == 'checked') enableZone(index); }); $('tr.fees_all td:eq('+index+')').addClass('validated').removeClass('not_validated'); - if ($('.zone input[type=checkbox]:checked').length) + + //if ($('.zone input[type=checkbox]:checked').length) enableGlobalFees(index); bind_inputs(); } @@ -499,18 +514,26 @@ function enableRange(index) function enableGlobalFees(index) { $('span.fees_all').show(); - $('tr.fees_all td:eq('+index+')').find('input').show().removeAttr('disabled'); - $('tr.fees_all td:eq('+index+')').find('.currency_sign').show(); + $('tr.fees_all td:eq('+index+')').find('div.input-group input').show().removeAttr('disabled'); + $('tr.fees_all td:eq('+index+')').find('div.input-group .currency_sign').show(); } +function disabledGlobalFees(index) +{ + $('span.fees_all').hide(); + $('tr.fees_all td:eq('+index+')').find('div.input-group input').hide().attr('disabled', 'disabled'); + $('tr.fees_all td:eq('+index+')').find('div.input-group .currency_sign').hide(); +} + + function disableRange(index) { - $('tr.fees').each( function () { + $('tr.fees').each(function () { //only enable fees for enabled zones if ($(this).find('td').find('input:checkbox').attr('checked') == 'checked') disableZone(index); }); - $('tr.fees_all td:eq('+index+')').find('input').attr('disabled', 'disabled'); + $('tr.fees_all td:eq('+index+')').find('div.input-group input').attr('disabled', 'disabled'); $('tr.fees_all td:eq('+index+')').removeClass('validated').addClass('not_validated'); } @@ -529,7 +552,7 @@ function add_new_range() $('tr.range_inf td:last').after('
'); $('tr.fees_all td:last').after('
'); - $('tr.fees').each( function () { + $('tr.fees').each(function () { $(this).find('td:last').after('
'+currency_sign+'
'); }); $('tr.delete_range td:last').after('