diff --git a/admin-dev/themes/template/address.tpl b/admin-dev/themes/template/address.tpl index a2eadb41e..41e6d38a3 100644 --- a/admin-dev/themes/template/address.tpl +++ b/admin-dev/themes/template/address.tpl @@ -24,4 +24,4 @@ * International Registered Trademark & Property of PrestaShop SA *} -{$list} \ No newline at end of file +{$content} \ No newline at end of file diff --git a/admin-dev/themes/template/layout.tpl b/admin-dev/themes/template/layout.tpl index 70eb4fae5..bc9ab21ac 100644 --- a/admin-dev/themes/template/layout.tpl +++ b/admin-dev/themes/template/layout.tpl @@ -71,6 +71,6 @@ {/if} -{$content} +{$page} {include file='footer.tpl'} diff --git a/classes/AdminController.php b/classes/AdminController.php index 2f47d32f1..e3b8880fd 100644 --- a/classes/AdminController.php +++ b/classes/AdminController.php @@ -32,6 +32,8 @@ class AdminControllerCore extends Controller /** @var string Security token */ public $token; + protected $_object; + /** @var string shop | group_shop */ public $shopLinkType; @@ -80,7 +82,9 @@ class AdminControllerCore extends Controller protected $noLink; protected $specificConfirmDelete; protected $colorOnBackground; - + /** @string Action to perform : 'edit', 'view', 'add', ... */ + protected $action; + protected $_includeContainer = true; public function __construct() { @@ -97,6 +101,7 @@ class AdminControllerCore extends Controller $controller = substr($controller,0,-10); parent::__construct(); + // if this->template is empty, // generate the filename from the classname, without "Controller" suffix if (empty($this->template)) @@ -127,6 +132,8 @@ class AdminControllerCore extends Controller ); if (!$this->identifier) $this->identifier = 'id_'.$this->table; if (!$this->_defaultOrderBy) $this->_defaultOrderBy = $this->identifier; + $this->tabAccess = Profile::getProfileAccess($this->context->employee->id_profile, $this->id); + // Fix for AdminHome if ($controller == 'AdminHome') $_POST['token'] = $this->token; @@ -387,7 +394,6 @@ class AdminControllerCore extends Controller { $object = new $this->className(); $this->copyFromPost($object, $this->table); - // d($object); if (!$object->add()) $this->_errors[] = Tools::displayError('An error occurred while creating object.').' '.$this->table.' ('.Db::getInstance()->getMsgError().')'; elseif (($_POST[$this->identifier] = $object->id /* voluntary */) AND $this->postImage($object->id) AND !sizeof($this->_errors) AND $this->_redirect) @@ -516,6 +522,77 @@ class AdminControllerCore extends Controller } } + /** + * Display form + */ + public function displayForm($firstCall = true) + { + $content = ''; + $allowEmployeeFormLang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0; + if ($allowEmployeeFormLang && !$this->context->cookie->employee_form_lang) + $this->context->cookie->employee_form_lang = (int)(Configuration::get('PS_LANG_DEFAULT')); + $useLangFromCookie = false; + $this->_languages = Language::getLanguages(false); + if ($allowEmployeeFormLang) + foreach ($this->_languages AS $lang) + if ($this->context->cookie->employee_form_lang == $lang['id_lang']) + $useLangFromCookie = true; + if (!$useLangFromCookie) + $this->_defaultFormLanguage = (int)(Configuration::get('PS_LANG_DEFAULT')); + else + $this->_defaultFormLanguage = (int)($this->context->cookie->employee_form_lang); + + // Only if it is the first call to displayForm, otherwise it has already been defined + if ($firstCall) + { + $content .=' + '; + } + return $content; + } + + /** + * Load class object using identifier in $_GET (if possible) + * otherwise return an empty object, or die + * + * @param boolean $opt Return an empty object if load fail + * @return object + */ + protected function loadObject($opt = false) + { + if ($id = (int)(Tools::getValue($this->identifier)) AND Validate::isUnsignedId($id)) + { + if (!$this->_object) + $this->_object = new $this->className($id); + if (Validate::isLoadedObject($this->_object)) + return $this->_object; + $this->_errors[] = Tools::displayError('Object cannot be loaded (not found)'); + } + elseif ($opt) + { + $this->_object = new $this->className(); + return $this->_object; + } + else + $this->_errors[] = Tools::displayError('Object cannot be loaded (identifier missing or invalid)'); + + $this->displayErrors(); + } + /** * Check if the token is valid, else display a warning page */ @@ -562,8 +639,7 @@ class AdminControllerCore extends Controller } public function display() { - if(!empty($this->content)) - $this->context->smarty->assign('content', $this->content); + $this->context->smarty->assign('content', $this->content); $this->context->smarty->assign('meta_title',$this->meta_title); @@ -574,24 +650,23 @@ class AdminControllerCore extends Controller $default_tpl = substr($class_name,0,-10).'.tpl'; if (file_exists($this->context->smarty->template_dir.'/'.$default_tpl)) { - $this->template = $default_tpl; + $this->template = $default_tpladdress; } else $this->template = 'content.tpl'; } else - $content = $this->context->smarty->fetch($this->template); + $page = $this->context->smarty->fetch($this->template); if ($this->content_only) - echo $content; + echo $page; else { $this->context->smarty->assign('warnings',$this->warnings); - $content = $this->context->smarty->fetch($this->template); - + $page = $this->context->smarty->fetch($this->template); } - $this->context->smarty->assign('content',$content); + $this->context->smarty->assign('page', $page); $this->context->smarty->display($this->layout); } @@ -764,6 +839,41 @@ class AdminControllerCore extends Controller */ public function initContent() { + if ($this->_errors) + $this->content = $this->displayErrors(); + else + { + if ($this->action == 'edit' && $this->id_entity) + { + $this->content .= $this->displayForm(); + if ($this->tabAccess['view']){ + if (Tools::getValue('back')) + $this->context->smarty->assign('back', Tools::safeOutput(Tools::getValue('back'))); + else + $this->context->smarty->assign('back', Tools::safeOutput(Tools::getValue(self::$currentIndex.'&token='.$this->token))); + } + // move to form.tpl + $this->content .= '

'.((Tools::getValue('back')) ? $this->l('Back') : $this->l('Back to list')).'
'; + } + elseif ($this->action == 'list') + { + $this->getList($this->context->language->id); + + $helper = new HelperList(); + $helper->view = $this->view; + $helper->edit = $this->edit; + $helper->delete = $this->delete; + $helper->duplicate = $this->duplicate; + $helper::$currentIndex = self::$currentIndex; + $helper->table = $this->table; + $helper->shopLink = $this->shopLink; + $helper->shopLinkType = $this->shopLinkType; + $helper->identifier = $this->identifier; + $helper->token = $this->token; + $this->content .= $helper->generateList($this->_list, $this->fieldsDisplay); + } + } + } /** @@ -916,11 +1026,52 @@ class AdminControllerCore extends Controller } elseif (strncmp($key, $this->table.'OrderBy', 7) === 0 OR strncmp($key, $this->table.'Orderway', 12) === 0) $this->context->cookie->$key = $value; + + // Code from postProcess + if (isset($_GET['update'.$this->table]) && isset($_GET['id_'.$this->table])) + { + if ($this->tabAccess['edit'] === '1' OR ($this->table == 'employee' AND $this->context->employee->id == Tools::getValue('id_employee'))) + { + $this->action = 'edit'; + $this->id_entity = (int)$_GET['id_'.$this->table]; + } + else + $this->_errors[] = Tools::displayError('You do not have permission to edit here.'); + } } + /** + * Display errors + */ public function displayErrors() { - p($this->_errors); + if ($nbErrors = count($this->_errors) AND $this->_includeContainer) + { + $content = ' +
X'; + if (count($this->_errors) == 1) + $content .= $this->_errors[0]; + else + { + $content .= $nbErrors.' '.$this->l('errors').'
    '; + foreach ($this->_errors AS $error) + $content .= '
  1. '.$error.'
  2. '; + $content .= '
'; + } + $content .= '
'; + } + // @TODO includesubtab + $this->includeSubTab('displayErrors'); + return $content; } /** @@ -1027,4 +1178,214 @@ class AdminControllerCore extends Controller $this->_list = Db::getInstance()->ExecuteS($sql); $this->_listTotal = Db::getInstance()->getValue('SELECT FOUND_ROWS() AS `'._DB_PREFIX_.$this->table.'`'); } + + /** + * Return field value if possible (both classical and multilingual fields) + * + * Case 1 : Return value if present in $_POST / $_GET + * Case 2 : Return object value + * + * @param object $obj Object + * @param string $key Field name + * @param integer $id_lang Language id (optional) + * @return string + */ + protected function getFieldValue($obj, $key, $id_lang = NULL) + { + if ($id_lang) + $defaultValue = ($obj->id AND isset($obj->{$key}[$id_lang])) ? $obj->{$key}[$id_lang] : ''; + else + $defaultValue = isset($obj->{$key}) ? $obj->{$key} : ''; + + return Tools::getValue($key.($id_lang ? '_'.$id_lang : ''), $defaultValue); + } + + /** + * Manage page display (form, list...) + * + * @param string $className Allow to validate a different class than the current one + */ + public function validateRules($className = false) + { + if (!$className) + $className = $this->className; + + /* Class specific validation rules */ + $rules = call_user_func(array($className, 'getValidationRules'), $className); + + if ((sizeof($rules['requiredLang']) OR sizeof($rules['sizeLang']) OR sizeof($rules['validateLang']))) + { + /* Language() instance determined by default language */ + $defaultLanguage = new Language((int)(Configuration::get('PS_LANG_DEFAULT'))); + + /* All availables languages */ + $languages = Language::getLanguages(false); + } + + /* Checking for required fields */ + foreach ($rules['required'] AS $field) + if (($value = Tools::getValue($field)) == false AND (string)$value != '0') + if (!Tools::getValue($this->identifier) OR ($field != 'passwd' AND $field != 'no-picture')) + $this->_errors[] = $this->l('the field').' '.call_user_func(array($className, 'displayFieldName'), $field, $className).' '.$this->l('is required'); + + /* Checking for multilingual required fields */ + foreach ($rules['requiredLang'] AS $fieldLang) + if (($empty = Tools::getValue($fieldLang.'_'.$defaultLanguage->id)) === false OR $empty !== '0' AND empty($empty)) + $this->_errors[] = $this->l('the field').' '.call_user_func(array($className, 'displayFieldName'), $fieldLang, $className).' '.$this->l('is required at least in').' '.$defaultLanguage->name; + + /* Checking for maximum fields sizes */ + foreach ($rules['size'] AS $field => $maxLength) + if (Tools::getValue($field) !== false AND Tools::strlen(Tools::getValue($field)) > $maxLength) + $this->_errors[] = $this->l('the field').' '.call_user_func(array($className, 'displayFieldName'), $field, $className).' '.$this->l('is too long').' ('.$maxLength.' '.$this->l('chars max').')'; + + /* Checking for maximum multilingual fields size */ + foreach ($rules['sizeLang'] AS $fieldLang => $maxLength) + foreach ($languages AS $language) + if (Tools::getValue($fieldLang.'_'.$language['id_lang']) !== false AND Tools::strlen(Tools::getValue($fieldLang.'_'.$language['id_lang'])) > $maxLength) + $this->_errors[] = $this->l('the field').' '.call_user_func(array($className, 'displayFieldName'), $fieldLang, $className).' ('.$language['name'].') '.$this->l('is too long').' ('.$maxLength.' '.$this->l('chars max, html chars including').')'; + + /* Overload this method for custom checking */ + $this->_childValidation(); + + /* Checking for fields validity */ + foreach ($rules['validate'] AS $field => $function) + if (($value = Tools::getValue($field)) !== false AND ($field != 'passwd')) + if (!Validate::$function($value)) + $this->_errors[] = $this->l('the field').' '.call_user_func(array($className, 'displayFieldName'), $field, $className).' '.$this->l('is invalid'); + + /* Checking for passwd_old validity */ + if (($value = Tools::getValue('passwd')) != false) + { + if ($className == 'Employee' AND !Validate::isPasswdAdmin($value)) + $this->_errors[] = $this->l('the field').' '.call_user_func(array($className, 'displayFieldName'), 'passwd', $className).' '.$this->l('is invalid'); + elseif ($className == 'Customer' AND !Validate::isPasswd($value)) + $this->_errors[] = $this->l('the field').' '.call_user_func(array($className, 'displayFieldName'), 'passwd', $className).' '.$this->l('is invalid'); + } + + /* Checking for multilingual fields validity */ + foreach ($rules['validateLang'] AS $fieldLang => $function) + foreach ($languages AS $language) + if (($value = Tools::getValue($fieldLang.'_'.$language['id_lang'])) !== false AND !empty($value)) + if (!Validate::$function($value)) + $this->_errors[] = $this->l('the field').' '.call_user_func(array($className, 'displayFieldName'), $fieldLang, $className).' ('.$language['name'].') '.$this->l('is invalid'); + } + + /** + * Overload this method for custom checking + */ + protected function _childValidation() { } + + /** + * Display object details + */ + public function viewDetails() {} + + /** + * Called before deletion + * + * @param object $object Object + * @return boolean + */ + protected function beforeDelete($object) { return true; } + + /** + * Called before deletion + * + * @param object $object Object + * @return boolean + */ + protected function afterDelete($object, $oldId) { return true; } + + protected function afterAdd($object) { return true; } + + protected function afterUpdate($object) { return true; } + + /** + * Check rights to view the current tab + * + * @return boolean + */ + + protected function afterImageUpload() { + return true; + } + + /** + * Copy datas from $_POST to object + * + * @param object &$object Object + * @param string $table Object table + */ + protected function copyFromPost(&$object, $table) + { + /* Classical fields */ + foreach ($_POST AS $key => $value) + if (key_exists($key, $object) AND $key != 'id_'.$table) + { + /* Do not take care of password field if empty */ + if ($key == 'passwd' AND Tools::getValue('id_'.$table) AND empty($value)) + continue; + /* Automatically encrypt password in MD5 */ + if ($key == 'passwd' AND !empty($value)) + $value = Tools::encrypt($value); + $object->{$key} = $value; + } + + /* Multilingual fields */ + $rules = call_user_func(array(get_class($object), 'getValidationRules'), get_class($object)); + if (sizeof($rules['validateLang'])) + { + $languages = Language::getLanguages(false); + foreach ($languages AS $language) + foreach (array_keys($rules['validateLang']) AS $field) + if (isset($_POST[$field.'_'.(int)($language['id_lang'])])) + $object->{$field}[(int)($language['id_lang'])] = $_POST[$field.'_'.(int)($language['id_lang'])]; + } + } + + protected function updateAssoShop($id_object = false) + { + if (!Shop::isMultiShopActivated()) + return ; + + $shopAsso = Shop::getAssoTables(); + $groupShopAsso = GroupShop::getAssoTables(); + if (isset($shopAsso[$this->table]) && $shopAsso[$this->table]['type'] == 'shop') + $type = 'shop'; + else if (isset($groupShopAsso[$this->table]) && $groupShopAsso[$this->table]['type'] == 'group_shop') + $type = 'group_shop'; + else + return ; + + $assos = array(); + foreach ($_POST AS $k => $row) + { + if (!preg_match('/^checkBox'.Tools::toCamelCase($type, true).'Asso_'.$this->table.'_([0-9]+)?_([0-9]+)$/Ui', $k, $res)) + continue; + $id_asso_object = (!empty($res[1]) ? $res[1] : $id_object); + $assos[] = array('id_object' => (int)$id_asso_object, 'id_'.$type => (int)$res[2]); + } + + Db::getInstance()->Execute('DELETE FROM '._DB_PREFIX_.$this->table.'_'.$type.($id_object ? ' WHERE `'.$this->identifier.'`='.(int)$id_object : '')); + foreach ($assos AS $asso) + Db::getInstance()->Execute('INSERT INTO '._DB_PREFIX_.$this->table.'_'.$type.' (`'.pSQL($this->identifier).'`, id_'.$type.') + VALUES('.(int)$asso['id_object'].', '.(int)$asso['id_'.$type].')'); + } + + /** + * Overload this method for custom checking + * + * @param integer $id Object id used for deleting images + * @return boolean + */ + protected function postImage($id) + { + if (isset($this->fieldImageSettings['name']) AND isset($this->fieldImageSettings['dir'])) + return $this->uploadImage($id, $this->fieldImageSettings['name'], $this->fieldImageSettings['dir'].'/'); + elseif (!empty($this->fieldImageSettings)) + foreach ($this->fieldImageSettings AS $image) + if (isset($image['name']) AND isset($image['dir'])) + $this->uploadImage($id, $image['name'], $image['dir'].'/'); + return !sizeof($this->_errors) ? true : false; + } } diff --git a/controllers/admin/AdminAddressesController.php b/controllers/admin/AdminAddressesController.php index 2e8f80a5d..0d939212b 100644 --- a/controllers/admin/AdminAddressesController.php +++ b/controllers/admin/AdminAddressesController.php @@ -157,6 +157,9 @@ class AdminAddressesControllerCore extends AdminController else Tools::redirectAdmin(Tools::getValue('back').'&conf=4'); } + + if (!isset($this->action)) + $this->action = 'list'; } public function getList($id_lang, $orderBy = NULL, $orderWay = NULL, $start = 0, $limit = NULL, $id_lang_shop = NULL) @@ -223,12 +226,12 @@ class AdminAddressesControllerCore extends AdminController public function displayForm($isMainTab = true) { - parent::displayForm(); + $content = parent::displayForm(); if (!($obj = $this->loadObject(true))) return; - echo ' -
+ $content .= ' + '.((int)($obj->id) ? '' : '').' '.(($id_order = (int)(Tools::getValue('id_order'))) ? '' : '').' '.(($address_type = (int)(Tools::getValue('address_type'))) ? '' : '').' @@ -238,17 +241,17 @@ class AdminAddressesControllerCore extends AdminController switch ($this->addressType) { case 'manufacturer': - echo ' + $content .= '
'; $manufacturers = Manufacturer::getManufacturers(); - echo ''; if (!sizeof($manufacturers)) - echo ''; + $content .= ''; foreach ($manufacturers as $manufacturer) - echo ''; - echo ''; - echo '
'; - echo ''; + $content .= ''; + $content .= ''; + $content .= ''; + $content .= ''; break; case 'customer': default: @@ -256,7 +259,7 @@ class AdminAddressesControllerCore extends AdminController { $customer = new Customer($obj->id_customer); $tokenCustomer = Tools::getAdminToken('AdminCustomers'.(int)(Tab::getIdFromClassName('AdminCustomers')).(int)$this->context->employee->id); - echo ' + $content .= '
'.$customer->lastname.' '.$customer->firstname.' ('.$customer->email.')
@@ -264,20 +267,20 @@ class AdminAddressesControllerCore extends AdminController } else { - echo + $content .= '
*
'; } - echo ' + $content .= '

'.$this->l('DNI / NIF / NIE').'

'; - echo ' + $content .= '
* '.$this->l('Invalid characters:').' <>;=#{}  @@ -296,20 +299,20 @@ class AdminAddressesControllerCore extends AdminController { if ($this->addressType != 'manufacturer') { - echo ' + $content .= '
'.$this->l('Invalid characters:').' <>;=#{} 
'; if ((Configuration::get('VATNUMBER_MANAGEMENT') AND file_exists(_PS_MODULE_DIR_.'vatnumber/vatnumber.php')) && VatNumber::isApplicable(Configuration::get('PS_COUNTRY_DEFAULT'))) - echo '
'; + $content .= '
'; else if(Configuration::get('VATNUMBER_MANAGEMENT')) - echo '
'; + $content .= '
'; else - echo'
'; + $content .='
'; - echo ' + $content .= '
@@ -318,7 +321,7 @@ class AdminAddressesControllerCore extends AdminController } elseif ($addr_field_item == 'lastname') { - echo ' + $content .= '
* @@ -328,7 +331,7 @@ class AdminAddressesControllerCore extends AdminController elseif ($addr_field_item == 'firstname') { - echo ' + $content .= '
* @@ -338,7 +341,7 @@ class AdminAddressesControllerCore extends AdminController elseif ($addr_field_item == 'address1') { - echo ' + $content .= '
* @@ -347,7 +350,7 @@ class AdminAddressesControllerCore extends AdminController elseif ($addr_field_item == 'address2') { - echo ' + $content .= '
@@ -356,7 +359,7 @@ class AdminAddressesControllerCore extends AdminController elseif ($addr_field_item == 'postcode') { - echo ' + $content .= '
@@ -365,7 +368,7 @@ class AdminAddressesControllerCore extends AdminController elseif ($addr_field_item == 'city') { - echo ' + $content .= '
* @@ -374,18 +377,18 @@ class AdminAddressesControllerCore extends AdminController elseif ($addr_field_item == 'country' || $addr_field_item == 'Country:name') { - echo ' + $content .= '
* + $content .= ' '; + $content .= ' *
'; - echo ' + $content .= '
@@ -398,7 +401,7 @@ class AdminAddressesControllerCore extends AdminController $id_country_ajax = (int)$this->getFieldValue($obj, 'id_country'); - echo ' + $content .= ' '; + $content .= ' }; }); '; } } // End foreach - echo ' + $content .= '
'; - echo ' + $content .= '
'; - echo ' + $content .= '
'.$this->l('Forbidden characters:').' <>;=#{} 
'; - echo ' + $content .= '
* '.$this->l('Required field').'
'; - echo ' + $content .= ' '; + + return $content; } protected function processAddressFormat() @@ -501,7 +506,7 @@ class AdminAddressesControllerCore extends AdminController return $out; } - public function display() + /*public function initContent() { $this->getList($this->context->language->id); @@ -515,9 +520,8 @@ class AdminAddressesControllerCore extends AdminController $helper->identifier = $this->identifier; $helper->token = $this->token; $this->context->smarty->assign(array('list' => $helper->generateList($this->_list, $this->fieldsDisplay))); + }*/ - parent::display(); - } }