* @copyright 2007-2011 PrestaShop SA * @version Release: $Revision: 7556 $ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * International Registered Trademark & Property of PrestaShop SA */ class AdminCustomers extends AdminTab { public function __construct() { $this->table = 'customer'; $this->className = 'Customer'; $this->lang = false; $this->edit = true; $this->view = true; $this->delete = true; $this->deleted = true; $this->requiredDatabase = true; $this->_select = '(YEAR(CURRENT_DATE)-YEAR(`birthday`)) - (RIGHT(CURRENT_DATE, 5) $this->l('M'), 2 => $this->l('F'), 9 => $this->l('?')); $this->fieldsDisplay = array( 'id_customer' => array('title' => $this->l('ID'), 'align' => 'center', 'width' => 25), 'id_gender' => array('title' => $this->l('Gender'), 'width' => 25, 'align' => 'center', 'icon' => array(1 => 'male.gif', 2 => 'female.gif', 'default' => 'unknown.gif'), 'orderby' => false, 'type' => 'select', 'select' => $genders, 'filter_key' => 'a!id_gender'), 'lastname' => array('title' => $this->l('Last Name'), 'width' => 80), 'firstname' => array('title' => $this->l('First name'), 'width' => 60), 'email' => array('title' => $this->l('E-mail address'), 'width' => 120, 'maxlength' => 19), 'age' => array('title' => $this->l('Age'), 'width' => 30, 'search' => false), 'active' => array('title' => $this->l('Enabled'), 'width' => 25, 'align' => 'center', 'active' => 'status', 'type' => 'bool', 'orderby' => false), 'newsletter' => array('title' => $this->l('News.'), 'width' => 25, 'align' => 'center', 'type' => 'bool', 'callback' => 'printNewsIcon', 'orderby' => false), 'optin' => array('title' => $this->l('Opt.'), 'width' => 25, 'align' => 'center', 'type' => 'bool', 'callback' => 'printOptinIcon', 'orderby' => false), 'date_add' => array('title' => $this->l('Registration'), 'width' => 30, 'type' => 'date', 'align' => 'right'), 'connect' => array('title' => $this->l('Connection'), 'width' => 60, 'type' => 'datetime', 'search' => false)); $this->optionTitle = $this->l('Customers options'); $this->_fieldsOptions = array( 'PS_PASSWD_TIME_FRONT' => array('title' => $this->l('Regenerate password:'), 'desc' => $this->l('Security minimum time to wait to regenerate the password'),'validation' => 'isUnsignedInt', 'cast' => 'intval', 'size' => 5, 'type' => 'text', 'suffix' => ' '.$this->l('minutes')) ); parent::__construct(); } public function postProcess() { global $currentIndex; if (Tools::isSubmit('submitDel'.$this->table) OR Tools::isSubmit('delete'.$this->table)) { $deleteForm = '
'.$this->l('How do you want to delete your customer(s)?').' '.$this->l('You have two ways to delete a customer, please choose what you want to do.').'

'; foreach ($_POST as $key => $value) if (is_array($value)) foreach ($value as $val) $deleteForm .= ''; else $deleteForm .= ''; $deleteForm .= '
 
'; } if (Tools::getValue('submitAdd'.$this->table)) { $groupList = Tools::getValue('groupBox'); /* Checking fields validity */ $this->validateRules(); if (!sizeof($this->_errors)) { $id = (int)(Tools::getValue('id_'.$this->table)); if (isset($id) AND !empty($id)) { if ($this->tabAccess['edit'] !== '1') $this->_errors[] = Tools::displayError('You do not have permission to edit here.'); else { $object = new $this->className($id); if (Validate::isLoadedObject($object)) { $customer_email = strval(Tools::getValue('email')); // check if e-mail already used if ($customer_email != $object->email) { $customer = new Customer(); $customer->getByEmail($customer_email); if ($customer->id) $this->_errors[] = Tools::displayError('An account already exists for this e-mail address:').' '.$customer_email; } if (!is_array($groupList) OR sizeof($groupList) == 0) $this->_errors[] = Tools::displayError('Customer must be in at least one group.'); else if (!in_array(Tools::getValue('id_default_group'), $groupList)) $this->_errors[] = Tools::displayError('Default customer group must be selected in group box.'); // Updating customer's group if (!sizeof($this->_errors)) { $object->cleanGroups(); if (is_array($groupList) AND sizeof($groupList) > 0) $object->addGroups($groupList); } } else $this->_errors[] = Tools::displayError('An error occurred while loading object.').' '.$this->table.' '.Tools::displayError('(cannot load object)'); } } else { if ($this->tabAccess['add'] === '1') { $object = new $this->className(); $this->copyFromPost($object, $this->table); if (!$object->add()) $this->_errors[] = Tools::displayError('An error occurred while creating object.').' '.$this->table.' ('.mysql_error().')'; elseif (($_POST[$this->identifier] = $object->id /* voluntary */) AND $this->postImage($object->id) AND !sizeof($this->_errors) AND $this->_redirect) { // Add Associated groups $group_list = Tools::getValue('groupBox'); if (is_array($group_list) && sizeof($group_list) > 0) $object->addGroups($group_list, true); $parent_id = (int)(Tools::getValue('id_parent', 1)); // Save and stay on same form if (Tools::isSubmit('submitAdd'.$this->table.'AndStay')) Tools::redirectAdmin($currentIndex.'&'.$this->identifier.'='.$object->id.'&conf=3&update'.$this->table.'&token='.$this->token); // Save and back to parent if (Tools::isSubmit('submitAdd'.$this->table.'AndBackToParent')) Tools::redirectAdmin($currentIndex.'&'.$this->identifier.'='.$parent_id.'&conf=3&token='.$this->token); // Default behavior (save and back) Tools::redirectAdmin($currentIndex.($parent_id ? '&'.$this->identifier.'='.$object->id : '').'&conf=3&token='.$this->token); } } else $this->_errors[] = Tools::displayError('You do not have permission to add here.'); } } } elseif (Tools::isSubmit('delete'.$this->table) AND $this->tabAccess['delete'] === '1') { switch (Tools::getValue('deleteMode')) { case 'real': $this->deleted = false; Discount::deleteByIdCustomer((int)(Tools::getValue('id_customer'))); break; case 'deleted': $this->deleted = true; break; default: echo $deleteForm; if (isset($_POST['delete'.$this->table])) unset($_POST['delete'.$this->table]); if (isset($_GET['delete'.$this->table])) unset($_GET['delete'.$this->table]); break; } } elseif (Tools::isSubmit('submitDel'.$this->table) AND $this->tabAccess['delete'] === '1') { switch (Tools::getValue('deleteMode')) { case 'real': $this->deleted = false; foreach (Tools::getValue('customerBox') as $id_customer) Discount::deleteByIdCustomer((int)($id_customer)); break; case 'deleted': $this->deleted = true; break; default: echo $deleteForm; if (isset($_POST['submitDel'.$this->table])) unset($_POST['submitDel'.$this->table]); if (isset($_GET['submitDel'.$this->table])) unset($_GET['submitDel'.$this->table]); break; } } elseif (Tools::isSubmit('submitGuestToCustomer') AND Tools::getValue('id_customer')) { if ($this->tabAccess['edit'] === '1') { $customer = new Customer((int)Tools::getValue('id_customer')); if (!Validate::isLoadedObject($customer)) $this->_errors[] = Tools::displayError('This customer does not exist.'); if (Customer::customerExists($customer->email)) $this->_errors[] = Tools::displayError('This customer already exist as non-guest.'); elseif ($customer->transformToCustomer(Tools::getValue('id_lang', Configuration::get('PS_LANG_DEFAULT')))) Tools::redirectAdmin($currentIndex.'&'.$this->identifier.'='.$customer->id.'&conf=3&token='.$this->token); else $this->_errors[] = Tools::displayError('An error occurred while updating customer.'); } else $this->_errors[] = Tools::displayError('You do not have permission to edit here.'); }elseif (Tools::isSubmit('changeNewsletterVal') AND Tools::getValue('id_customer')) { $id_customer = (int)Tools::getValue('id_customer'); $customer = new Customer($id_customer); if (!Validate::isLoadedObject($customer)) $this->_errors[] = Tools::displayError('An error occurred while updating customer.'); $update = Db::getInstance()->Execute('UPDATE `'._DB_PREFIX_.'customer` SET newsletter = '.($customer->newsletter ? 0 : 1).' WHERE `id_customer` = '.(int)($customer->id)); if (!$update) $this->_errors[] = Tools::displayError('An error occurred while updating customer.'); Tools::redirectAdmin($currentIndex.'&token='.$this->token); }elseif (Tools::isSubmit('changeOptinVal') AND Tools::getValue('id_customer')) { $id_customer = (int)Tools::getValue('id_customer'); $customer = new Customer($id_customer); if (!Validate::isLoadedObject($customer)) $this->_errors[] = Tools::displayError('An error occurred while updating customer.'); $update = Db::getInstance()->Execute('UPDATE `'._DB_PREFIX_.'customer` SET optin = '.($customer->optin ? 0 : 1).' WHERE `id_customer` = '.(int)($customer->id)); if (!$update) $this->_errors[] = Tools::displayError('An error occurred while updating customer.'); Tools::redirectAdmin($currentIndex.'&token='.$this->token); } return parent::postProcess(); } public function viewcustomer() { global $currentIndex, $cookie, $link; $irow = 0; $configurations = Configuration::getMultiple(array('PS_LANG_DEFAULT', 'PS_CURRENCY_DEFAULT')); $defaultLanguage = (int)($configurations['PS_LANG_DEFAULT']); $defaultCurrency = (int)($configurations['PS_CURRENCY_DEFAULT']); if (!($customer = $this->loadObject())) return; $customerStats = $customer->getStats(); $addresses = $customer->getAddresses($defaultLanguage); $products = $customer->getBoughtProducts(); $discounts = Discount::getCustomerDiscounts($defaultLanguage, (int)$customer->id, false, false); $orders = Order::getCustomerOrders((int)$customer->id, true); $carts = Cart::getCustomerCarts((int)$customer->id); $groups = $customer->getGroups(); $messages = CustomerThread::getCustomerMessages((int)$customer->id); $referrers = Referrer::getReferrers((int)$customer->id); if ($totalCustomer = Db::getInstance()->getValue('SELECT SUM(total_paid_real) FROM '._DB_PREFIX_.'orders WHERE id_customer = '.$customer->id.' AND valid = 1')) { Db::getInstance()->getValue('SELECT SQL_CALC_FOUND_ROWS COUNT(*) FROM '._DB_PREFIX_.'orders WHERE valid = 1 GROUP BY id_customer HAVING SUM(total_paid_real) > '.$totalCustomer); $countBetterCustomers = (int)Db::getInstance()->getValue('SELECT FOUND_ROWS()') + 1; } else $countBetterCustomers = '-'; echo '
'.$customer->firstname.' '.$customer->lastname.'
'.$customer->email.'

'.$this->l('ID:').' '.sprintf('%06d', $customer->id).'
'.$this->l('Registration date:').' '.Tools::displayDate($customer->date_add, (int)($cookie->id_lang), true).'
'.$this->l('Last visit:').' '.($customerStats['last_visit'] ? Tools::displayDate($customerStats['last_visit'], (int)($cookie->id_lang), true) : $this->l('never')).'
'.($countBetterCustomers != '-' ? $this->l('Rank: #').' '.(int)$countBetterCustomers.'
' : '').'
'.$this->l('Newsletter:').' '.($customer->newsletter ? '' : '').'
'.$this->l('Opt-in:').' '.($customer->optin ? '' : '').'
'.$this->l('Age:').' '.$customerStats['age'].' '.((!empty($customer->birthday['age'])) ? '('.Tools::displayDate($customer->birthday, (int)($cookie->id_lang)).')' : $this->l('unknown')).'

'.$this->l('Last update:').' '.Tools::displayDate($customer->date_upd, (int)($cookie->id_lang), true).'
'.$this->l('Status:').' '.($customer->active ? '' : ''); if ($customer->isGuest()) { echo '
'.$this->l('This customer is registered as').' '.$this->l('guest').''; if (!Customer::customerExists($customer->email)) { echo '

'.$this->l('This feature generates a random password and sends an e-mail to the customer').'
'; } else echo '
'.$this->l('A registered customer account exists with the same email address').''; echo '
'; } echo '
 
'; echo '
'.$this->l('Add a private note').'

'.$this->l('This note will be displayed to all the employees but not to the customer.').'


 
'; echo '

'.$this->l('Messages').' ('.sizeof($messages).')

'; if (sizeof($messages)) { echo ' '; foreach ($messages AS $message) echo ''; echo '
'.$this->l('Status').' '.$this->l('Message').' '.$this->l('Sent on').'
'.$message['status'].' '.substr(strip_tags(html_entity_decode($message['message'], ENT_NOQUOTES, 'UTF-8')), 0, 75).'... '.Tools::displayDate($message['date_add'], (int)($cookie->id_lang), true).'
 
'; } else echo $customer->firstname.' '.$customer->lastname.' '.$this->l('has never contacted you.'); // display hook specified to this page : AdminCustomers if (($hook = Module::hookExec('adminCustomers', array('id_customer' => $customer->id))) !== false) echo '
'.$hook.'
'; echo '
 
'; echo '

'.$this->l('Groups').' ('.sizeof($groups).')

'; if ($groups AND sizeof($groups)) { echo ' '; $tokenGroups = Tools::getAdminToken('AdminGroups'.(int)(Tab::getIdFromClassName('AdminGroups')).(int)($cookie->id_employee)); foreach ($groups AS $group) { $objGroup = new Group($group); echo ' '; } echo '
'.$this->l('ID').' '.$this->l('Name').' '.$this->l('Actions').'
'.$objGroup->id.' '.$objGroup->name[$defaultLanguage].'
'; } echo '
 
'; echo '

'.$this->l('Orders').' ('.sizeof($orders).')

'; if ($orders AND sizeof($orders)) { $totalOK = 0; $ordersOK = array(); $ordersKO = array(); $tokenOrders = Tools::getAdminToken('AdminOrders'.(int)Tab::getIdFromClassName('AdminOrders').(int)$cookie->id_employee); foreach ($orders AS $order) if ($order['valid']) { $ordersOK[] = $order; $totalOK += $order['total_paid_real']; } else $ordersKO[] = $order; $orderHead = ' '; $orderFoot = '
'.$this->l('ID').' '.$this->l('Date').' '.$this->l('Products').' '.$this->l('Total paid').' '.$this->l('Payment').' '.$this->l('State').' '.$this->l('Actions').'
'; if ($countOK = sizeof($ordersOK)) { echo '

'.$this->l('Valid orders:').' '.$countOK.' '.$this->l('for').' '.Tools::displayPrice($totalOK, new Currency($defaultCurrency)).'

'.$orderHead; foreach ($ordersOK AS $order) echo ' '.$order['id_order'].' '.Tools::displayDate($order['date_add'], (int)($cookie->id_lang)).' '.$order['nb_products'].' '.Tools::displayPrice($order['total_paid_real'], new Currency((int)($order['id_currency']))).' '.$order['payment'].' '.$order['order_state'].' '; echo $orderFoot.'
'; } if ($countKO = sizeof($ordersKO)) { echo '

'.$this->l('Invalid orders:').' '.$countKO.'

'.$orderHead; foreach ($ordersKO AS $order) echo ' '.$order['id_order'].' '.Tools::displayDate($order['date_add'], (int)($cookie->id_lang)).' '.$order['nb_products'].' '.Tools::displayPrice($order['total_paid_real'], new Currency((int)($order['id_currency']))).' '.$order['payment'].' '.$order['order_state'].' '; echo $orderFoot.'
 
'; } } else echo $customer->firstname.' '.$customer->lastname.' '.$this->l('has not placed any orders yet'); if ($products AND sizeof($products)) { echo '
 

'.$this->l('Products').' ('.sizeof($products).')

'; $tokenOrders = Tools::getAdminToken('AdminOrders'.(int)(Tab::getIdFromClassName('AdminOrders')).(int)($cookie->id_employee)); foreach ($products AS $product) echo ' '; echo '
'.$this->l('Date').' '.$this->l('Name').' '.$this->l('Quantity').' '.$this->l('Actions').'
'.Tools::displayDate($product['date_add'], (int)($cookie->id_lang), true).' '.$product['product_name'].' '.$product['product_quantity'].'
'; } echo '
 

'.$this->l('Addresses').' ('.sizeof($addresses).')

'; if (sizeof($addresses)) { echo ' '; $tokenAddresses = Tools::getAdminToken('AdminAddresses'.(int)(Tab::getIdFromClassName('AdminAddresses')).(int)($cookie->id_employee)); foreach ($addresses AS $address) echo ' '; echo '
'.$this->l('Company').' '.$this->l('Name').' '.$this->l('Address').' '.$this->l('Country').' '.$this->l('Phone number(s)').' '.$this->l('Actions').'
'.($address['company'] ? $address['company'] : '--').' '.$address['firstname'].' '.$address['lastname'].' '.$address['address1'].($address['address2'] ? ' '.$address['address2'] : '').' '.$address['postcode'].' '.$address['city'].' '.$address['country'].' '.($address['phone'] ? ($address['phone'].($address['phone_mobile'] ? '
'.$address['phone_mobile'] : '')) : ($address['phone_mobile'] ? '
'.$address['phone_mobile'] : '--')).'
'; } else echo $customer->firstname.' '.$customer->lastname.' '.$this->l('has not registered any addresses yet').'.'; echo '
 

'.$this->l('Discounts').' ('.sizeof($discounts).')

'; if (sizeof($discounts)) { echo ' '; $tokenDiscounts = Tools::getAdminToken('AdminDiscounts'.(int)(Tab::getIdFromClassName('AdminDiscounts')).(int)($cookie->id_employee)); foreach ($discounts AS $discount) { echo ' '; } echo '
'.$this->l('ID').' '.$this->l('Code').' '.$this->l('Type').' '.$this->l('Value').' '.$this->l('Qty available').' '.$this->l('Status').' '.$this->l('Actions').'
'.$discount['id_discount'].' '.$discount['name'].' '.$discount['type'].' '.$discount['value'].' '.$discount['quantity_for_user'].' '.$this->l('Status').'
'; } else echo $customer->firstname.' '.$customer->lastname.' '.$this->l('has no discount vouchers').'.'; echo '
 
'; echo '

'.$this->l('Carts').' ('.sizeof($carts).')

'; if ($carts AND sizeof($carts)) { echo ' '; $tokenCarts = Tools::getAdminToken('AdminCarts'.(int)(Tab::getIdFromClassName('AdminCarts')).(int)($cookie->id_employee)); foreach ($carts AS $cart) { $cartI = new Cart((int)($cart['id_cart'])); $summary = $cartI->getSummaryDetails(); $currency = new Currency((int)($cart['id_currency'])); $carrier = new Carrier((int)($cart['id_carrier'])); echo ' '; } echo '
'.$this->l('ID').' '.$this->l('Date').' '.$this->l('Total').' '.$this->l('Carrier').' '.$this->l('Actions').'
'.sprintf('%06d', $cart['id_cart']).' '.Tools::displayDate($cart['date_add'], (int)($cookie->id_lang), true).' '.Tools::displayPrice($summary['total_price'], $currency).' '.$carrier->name.'
'; } else echo $this->l('No cart available').'.'; echo '
'; $interested = Db::getInstance()->ExecuteS('SELECT DISTINCT id_product FROM '._DB_PREFIX_.'cart_product cp INNER JOIN '._DB_PREFIX_.'cart c on c.id_cart = cp.id_cart WHERE c.id_customer = '.(int)$customer->id.' AND cp.id_product NOT IN ( SELECT product_id FROM '._DB_PREFIX_.'orders o inner join '._DB_PREFIX_.'order_detail od ON o.id_order = od.id_order WHERE o.valid = 1 AND o.id_customer = '.(int)$customer->id.')'); if (count($interested)) { echo '

'.$this->l('Products').' ('.count($interested).')

'; foreach ($interested as $p) { $product = new Product((int)$p['id_product'], false, $cookie->id_lang); echo ' '; } echo '
'.(int)$product->id.' '.Tools::htmlentitiesUTF8($product->name).'
'; } echo '
 
'; /* Last connections */ $connections = $customer->getLastConnections(); if (sizeof($connections)) { echo '

'.$this->l('Last connections').'

'; foreach ($connections as $connection) echo ''; echo '
'.$this->l('Date').' '.$this->l('Pages viewed').' '.$this->l('Total time').' '.$this->l('Origin').' '.$this->l('IP Address').'
'.Tools::displayDate($connection['date_add'], (int)($cookie->id_lang), true).' '.(int)($connection['pages']).' '.$connection['time'].' '.($connection['http_referer'] ? preg_replace('/^www./', '', parse_url($connection['http_referer'], PHP_URL_HOST)) : $this->l('Direct link')).' '.$connection['ipaddress'].'
 
'; } if (sizeof($referrers)) { echo '

'.$this->l('Referrers').'

'; foreach ($referrers as $referrer) echo ''; echo '
'.$this->l('Date').' '.$this->l('Name').'
'.Tools::displayDate($referrer['date_add'], (int)($cookie->id_lang), true).' '.$referrer['name'].'
 
'; } echo ' '.$this->l('Back to customer list').'
'; } public function displayForm($isMainTab = true) { global $currentIndex; parent::displayForm(); if (!($obj = $this->loadObject(true))) return; $birthday = explode('-', $this->getFieldValue($obj, 'birthday')); $customer_groups = Tools::getValue('groupBox', $obj->getGroups()); $groups = Group::getGroups($this->_defaultFormLanguage, true); echo '
'.($obj->id ? '' : '').'
'.$this->l('Customer').'
getFieldValue($obj, 'id_gender') == 1 ? 'checked="checked" ' : '').'/> getFieldValue($obj, 'id_gender') == 2 ? 'checked="checked" ' : '').'/> getFieldValue($obj, 'id_gender') == 9 OR !$this->getFieldValue($obj, 'id_gender')) ? 'checked="checked" ' : '').'/>
* '.$this->l('Invalid characters:').' 0-9!<>,;?=+()@#"�{}_$%: 
* '.$this->l('Forbidden characters:').' 0-9!<>,;?=+()@#"�{}_$%: 
'.(!$obj->id ? '*' : '').'

'.($obj->id ? $this->l('Leave blank if no change') : $this->l('5 characters min., only letters, numbers, or').' -_').'

*
'; $sl_year = ($this->getFieldValue($obj, 'birthday')) ? $birthday[0] : 0; $years = Tools::dateYears(); $sl_month = ($this->getFieldValue($obj, 'birthday')) ? $birthday[1] : 0; $months = Tools::dateMonths(); $sl_day = ($this->getFieldValue($obj, 'birthday')) ? $birthday[2] : 0; $days = Tools::dateDays(); $tab_months = array( $this->l('January'), $this->l('February'), $this->l('March'), $this->l('April'), $this->l('May'), $this->l('June'), $this->l('July'), $this->l('August'), $this->l('September'), $this->l('October'), $this->l('November'), $this->l('December')); echo '
'; echo '
getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/> getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/>

'.$this->l('Allow or disallow this customer to log in').'

getFieldValue($obj, 'newsletter') ? 'checked="checked" ' : '').'/> getFieldValue($obj, 'newsletter') ? 'checked="checked" ' : '').'/>

'.$this->l('Customer will receive your newsletter via e-mail').'

getFieldValue($obj, 'optin') ? 'checked="checked" ' : '').'/> getFieldValue($obj, 'optin') ? 'checked="checked" ' : '').'/>

'.$this->l('Customer will receive your ads via e-mail').'

'.$this->l('Apply non-cumulative rules (e.g., price, display method, reduction)').'

'; if (sizeof($groups)) { echo ' '; $irow = 0; foreach ($groups as $group) { echo ' '; } echo '
'.$this->l('ID').' '.$this->l('Group name').'
'.' '.$group['id_group'].'

'.$this->l('Check all the box(es) of groups of which the customer is to be a member').' *

'; } else echo '

'.$this->l('No group created').'

'; echo '
* '.$this->l('Required field').'
'; } public function getList($id_lang, $orderBy = NULL, $orderWay = NULL, $start = 0, $limit = NULL) { global $cookie; return parent::getList((int)($cookie->id_lang), !Tools::getValue($this->table.'Orderby') ? 'date_add' : NULL, !Tools::getValue($this->table.'Orderway') ? 'DESC' : NULL); } public function beforeDelete($object) { return $object->isUsed(); } }