Created
March 2, 2023 14:48
-
-
Save caovillanueva/cd9218814cd249f158d5692565e8c43b to your computer and use it in GitHub Desktop.
[PS17 Add extra fields for costumers in 1.7.8] Display fields in front and backend 100%Symphony for ver. 1.7.8. Do not use this tutorial with previous versions. #ps17
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Copyright since 2007 PrestaShop SA and Contributors | |
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA | |
* | |
*/ | |
use PrestaShop\PrestaShop\Adapter\CoreException; | |
use PrestaShop\PrestaShop\Adapter\ServiceLocator; | |
/*** | |
* Class CustomerCore | |
*/ | |
class Customer extends CustomerCore | |
{ | |
public $retail; | |
public $addressC; | |
public $cityC; | |
public $stateC; | |
public $countryC; | |
public $zipC; | |
public $phoneC; | |
public $mobileC; | |
public $aboutus; | |
public $extrainfo; | |
/** | |
* @see ObjectModel::$definition | |
*/ | |
public static $definition = [ | |
'table' => 'customer', | |
'primary' => 'id_customer', | |
'fields' => [ | |
'secure_key' => ['type' => self::TYPE_STRING, 'validate' => 'isMd5', 'copy_post' => false], | |
'lastname' => ['type' => self::TYPE_STRING, 'validate' => 'isCustomerName', 'required' => true, 'size' => 255], | |
'firstname' => ['type' => self::TYPE_STRING, 'validate' => 'isCustomerName', 'required' => true, 'size' => 255], | |
'email' => ['type' => self::TYPE_STRING, 'validate' => 'isEmail', 'required' => true, 'size' => 255], | |
'passwd' => ['type' => self::TYPE_STRING, 'validate' => 'isPasswd', 'required' => true, 'size' => 255], | |
'last_passwd_gen' => ['type' => self::TYPE_STRING, 'copy_post' => false], | |
'id_gender' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'], | |
'birthday' => ['type' => self::TYPE_DATE, 'validate' => 'isBirthDate'], | |
'newsletter' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'], | |
'newsletter_date_add' => ['type' => self::TYPE_DATE, 'copy_post' => false], | |
'ip_registration_newsletter' => ['type' => self::TYPE_STRING, 'copy_post' => false], | |
'optin' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'], | |
'website' => ['type' => self::TYPE_STRING, 'validate' => 'isUrl'], | |
'company' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName'], | |
//MM_ new fields | |
'retail' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName'), | |
'addressC' => array('type' => self::TYPE_STRING,), | |
'aboutus' => array('type' => self::TYPE_STRING,), | |
'extrainfo' => array('type' => self::TYPE_STRING,), | |
'stateC' => array('type' => self::TYPE_STRING,), | |
'countryC' => array('type' => self::TYPE_STRING,), | |
'zipC' => array('type' => self::TYPE_STRING,), | |
'cityC' => array('type' => self::TYPE_STRING,), | |
'phoneC' => array('type' => self::TYPE_STRING,), | |
'mobileC' => array('type' => self::TYPE_STRING,), | |
//End mm_ | |
'siret' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName'], | |
'ape' => ['type' => self::TYPE_STRING, 'validate' => 'isApe'], | |
'outstanding_allow_amount' => ['type' => self::TYPE_FLOAT, 'validate' => 'isFloat', 'copy_post' => false], | |
'show_public_prices' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool', 'copy_post' => false], | |
'id_risk' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedInt', 'copy_post' => false], | |
'max_payment_days' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedInt', 'copy_post' => false], | |
'active' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool', 'copy_post' => false], | |
'deleted' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool', 'copy_post' => false], | |
'note' => ['type' => self::TYPE_HTML, 'size' => 65000, 'copy_post' => false], | |
'is_guest' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool', 'copy_post' => false], | |
'id_shop' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'copy_post' => false], | |
'id_shop_group' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'copy_post' => false], | |
'id_default_group' => ['type' => self::TYPE_INT, 'copy_post' => false], | |
'id_lang' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'copy_post' => false], | |
'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate', 'copy_post' => false], | |
'date_upd' => ['type' => self::TYPE_DATE, 'validate' => 'isDate', 'copy_post' => false], | |
'reset_password_token' => ['type' => self::TYPE_STRING, 'validate' => 'isSha1', 'size' => 40, 'copy_post' => false], | |
'reset_password_validity' => ['type' => self::TYPE_DATE, 'validate' => 'isDateOrNull', 'copy_post' => false], | |
], | |
]; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @Override CustomerFormatter | |
*/ | |
use Symfony\Component\Translation\TranslatorInterface; | |
class CustomerFormatter extends CustomerFormatterCore | |
{ | |
private $translator; | |
private $language; | |
private $ask_for_birthdate = true; | |
private $ask_for_partner_optin = true; | |
private $partner_optin_is_required = true; | |
private $ask_for_password = true; | |
private $password_is_required = true; | |
private $ask_for_new_password = false; | |
public function __construct( | |
TranslatorInterface $translator, | |
Language $language | |
) { | |
$this->translator = $translator; | |
$this->language = $language; | |
} | |
public function setAskForBirthdate($ask_for_birthdate) | |
{ | |
$this->ask_for_birthdate = $ask_for_birthdate; | |
return $this; | |
} | |
public function setAskForPartnerOptin($ask_for_partner_optin) | |
{ | |
$this->ask_for_partner_optin = $ask_for_partner_optin; | |
return $this; | |
} | |
public function setPartnerOptinRequired($partner_optin_is_required) | |
{ | |
$this->partner_optin_is_required = $partner_optin_is_required; | |
return $this; | |
} | |
public function setAskForPassword($ask_for_password) | |
{ | |
$this->ask_for_password = $ask_for_password; | |
return $this; | |
} | |
public function setAskForNewPassword($ask_for_new_password) | |
{ | |
$this->ask_for_new_password = $ask_for_new_password; | |
return $this; | |
} | |
public function setPasswordRequired($password_is_required) | |
{ | |
$this->password_is_required = $password_is_required; | |
return $this; | |
} | |
public function getFormat() | |
{ | |
$format = []; | |
$genders = Gender::getGenders($this->language->id); | |
if ($genders->count() > 0) { | |
$genderField = (new FormField()) | |
->setName('id_gender') | |
->setType('radio-buttons') | |
->setLabel( | |
$this->translator->trans( | |
'Social title', | |
[], | |
'Shop.Forms.Labels' | |
) | |
); | |
foreach ($genders as $gender) { | |
$genderField->addAvailableValue($gender->id, $gender->name); | |
} | |
$format[$genderField->getName()] = $genderField; | |
} | |
$format['firstname'] = (new FormField()) | |
->setName('firstname') | |
->setLabel( | |
$this->translator->trans( | |
'First name', | |
[], | |
'Shop.Forms.Labels' | |
) | |
) | |
->setRequired(true) | |
->addAvailableValue( | |
'comment', | |
$this->translator->trans('Only letters and the dot (.) character, followed by a space, are allowed.', [], 'Shop.Forms.Help') | |
); | |
$format['lastname'] = (new FormField()) | |
->setName('lastname') | |
->setLabel( | |
$this->translator->trans( | |
'Last name', | |
[], | |
'Shop.Forms.Labels' | |
) | |
) | |
->setRequired(true) | |
->addAvailableValue( | |
'comment', | |
$this->translator->trans('Only letters and the dot (.) character, followed by a space, are allowed.', [], 'Shop.Forms.Help') | |
); | |
if (Configuration::get('PS_B2B_ENABLE')) { | |
$format['company'] = (new FormField()) | |
->setName('company') | |
->setType('text') | |
->setLabel($this->translator->trans( | |
'Company', | |
[], | |
'Shop.Forms.Labels' | |
)); | |
$format['siret'] = (new FormField()) | |
->setName('siret') | |
->setType('text') | |
->setLabel($this->translator->trans( | |
// Please localize this string with the applicable registration number type in your country. For example : "SIRET" in France and "Código fiscal" in Spain. | |
'Identification number', | |
[], | |
'Shop.Forms.Labels' | |
)); | |
} | |
$format['email'] = (new FormField()) | |
->setName('email') | |
->setType('email') | |
->setLabel( | |
$this->translator->trans( | |
'Email', | |
[], | |
'Shop.Forms.Labels' | |
) | |
) | |
->setRequired(true); | |
if ($this->ask_for_password) { | |
$format['password'] = (new FormField()) | |
->setName('password') | |
->setType('password') | |
->setLabel( | |
$this->translator->trans( | |
'Password', | |
[], | |
'Shop.Forms.Labels' | |
) | |
) | |
->setRequired($this->password_is_required); | |
} | |
if ($this->ask_for_new_password) { | |
$format['new_password'] = (new FormField()) | |
->setName('new_password') | |
->setType('password') | |
->setLabel( | |
$this->translator->trans( | |
'New password', | |
[], | |
'Shop.Forms.Labels' | |
) | |
); | |
} | |
////////////////////////////////////////////// | |
//MM_ New | |
//Adding extrafields | |
//Unfortunatelly the translation feature in backend does not work well. We need to put conditionals here to make it work. | |
////////////////////////////////////////////// | |
//Translations (the native translations does not work well anymore, use this instead.) | |
if ($this->language->id == 1){//EN | |
$Op_TypeC = ["I'm residential customer", | |
"I'm a residential builder or contractor", | |
"I'm an architect or designer", | |
"I'm a commercial general contractor", | |
"Other"]; | |
$Op_Company = 'Company'; | |
$Op_State = 'State / Province'; | |
$Op_Zip = 'Zip / Postal Code'; | |
$Op_How = 'How did you hear about us?'; | |
$Op_mobileC = 'Cell Phone'; | |
$Op_website = 'Website'; | |
$Op_HowOP = ["Online Search","Online Ads","Print Ads","Word of mouth","i'm already a client","Other"]; | |
$Op_ExtraIn = 'Additional Information'; | |
} | |
if ($this->language->id == 2){//FR | |
$Op_TypeC = ['Je suis un client résidentiel', | |
'Je suis un constructeur résidentiel ou un entrepreneur', | |
'Je suis architecte ou designer', | |
'Je suis un entrepreneur général commercial', | |
'Autre']; | |
$Op_Company = 'Entreprise'; | |
$Op_State = 'Province'; | |
$Op_Zip = 'Code postal'; | |
$Op_How = 'Comment avez-vous entendu parler de nous?'; | |
$Op_mobileC = 'Cellulaire'; | |
$Op_website = 'Site Web'; | |
$Op_HowOP = ["Recherche en ligne","Annonces en ligne","Annonces imprimées (magazines, journaux, etc.)","Bouche à oreille","Je suis déjà client","Autre"]; | |
$Op_ExtraIn = 'Information additionnelle'; | |
} | |
$format['retail'] = (new FormField) | |
->setName('retail') | |
->setType('select') | |
->setLabel( | |
$this->translator->trans( | |
'Client type', [], 'Shop.Forms.MM' | |
) | |
) | |
->addAvailableValue('Residential customer', $Op_TypeC[0]) | |
->addAvailableValue('Residential builder', $Op_TypeC[1]) | |
->addAvailableValue('Architect', $Op_TypeC[2]) | |
->addAvailableValue('General contractor', $Op_TypeC[3]) | |
->addAvailableValue('other', $Op_TypeC[4]) | |
->setRequired(true) | |
; | |
$format['company'] = (new FormField) | |
->setName('company') | |
->setLabel( | |
$this->translator->trans( | |
$Op_Company, [], 'Shop.Forms.Labels' | |
) | |
) | |
->setRequired(false) | |
; | |
$format['addressC'] = (new FormField) | |
->setName('addressC') | |
->setLabel( | |
$this->translator->trans( | |
'Address', [], 'Shop.Forms.Labels' | |
) | |
) | |
->setRequired(true) | |
; | |
$format['cityC'] = (new FormField) | |
->setName('cityC') | |
->setLabel( | |
$this->translator->trans( | |
'City', [], 'Shop.Forms.Labels' | |
) | |
) | |
->setRequired(true) | |
; | |
$format['countryC'] = (new FormField) | |
->setName('countryC') | |
->setType('countrySelect') | |
->setLabel( | |
$this->translator->trans( | |
'Country', [], 'Shop.Forms.Labels' | |
) | |
) | |
->addAvailableValue('Canada', $this->translator->trans( | |
'Canada', [], 'Shop.Forms.Labels' | |
)) | |
->addAvailableValue('United States', $this->translator->trans( | |
'United States', [], 'Shop.Forms.Labels' | |
)) | |
->setRequired(true) | |
; | |
$format['stateC'] = (new FormField) | |
->setName('stateC') | |
->setLabel( | |
$this->translator->trans( | |
$Op_State,[],'Shop.Forms.Labels' | |
) | |
) | |
->setRequired(true) | |
; | |
$format['zipC'] = (new FormField) | |
->setName('zipC') | |
->setLabel( | |
$this->translator->trans( | |
$Op_Zip,[],'Shop.Forms.Labels' | |
) | |
) | |
->setRequired(true) | |
; | |
$format['phoneC'] = (new FormField) | |
->setName('phoneC') | |
->setType('text') | |
->setLabel( | |
$this->translator->trans( | |
'Phone', [], 'Shop.Forms.Labels' | |
) | |
) | |
->setRequired(true) | |
; | |
$format['mobileC'] = (new FormField) | |
->setName('mobileC') | |
->setType('text') | |
->setLabel($Op_mobileC) | |
->setRequired(false) | |
; | |
$format['website'] = (new FormField) | |
->setName('website') | |
->setType("UrlType") | |
->setLabel($Op_website) | |
->setRequired(false) | |
; | |
$format['aboutus'] = (new FormField) | |
->setName('aboutus') | |
->setType('select') | |
->setLabel($Op_How) | |
->addAvailableValue('Online Search',$Op_HowOP[0]) | |
->addAvailableValue('Online Ads',$Op_HowOP[1]) | |
->addAvailableValue('Print Ads',$Op_HowOP[2]) | |
->addAvailableValue('Word of mouth',$Op_HowOP[3]) | |
->addAvailableValue("i'm already a client",$Op_HowOP[4]) | |
->addAvailableValue("Other",$Op_HowOP[5]) | |
->setRequired(true) | |
; | |
$format['extrainfo'] = (new FormField) | |
->setName('extrainfo') | |
->setType('textarea') | |
->setLabel($Op_ExtraIn) | |
->setRequired(false) | |
; | |
//////////////////////////////////////////////////////// | |
//End MM_ | |
//////////////////////////////////////////////////////// | |
if ($this->ask_for_birthdate) { | |
$format['birthday'] = (new FormField()) | |
->setName('birthday') | |
->setType('text') | |
->setLabel( | |
$this->translator->trans( | |
'Birthdate', | |
[], | |
'Shop.Forms.Labels' | |
) | |
) | |
->addAvailableValue('placeholder', Tools::getDateFormat()) | |
->addAvailableValue( | |
'comment', | |
$this->translator->trans('(E.g.: %date_format%)', ['%date_format%' => Tools::formatDateStr('31 May 1970')], 'Shop.Forms.Help') | |
); | |
} | |
if ($this->ask_for_partner_optin) { | |
$format['optin'] = (new FormField()) | |
->setName('optin') | |
->setType('checkbox') | |
->setLabel( | |
$this->translator->trans( | |
'Receive offers from our partners', | |
[], | |
'Shop.Theme.Customeraccount' | |
) | |
) | |
->setRequired($this->partner_optin_is_required); | |
} | |
// ToDo, replace the hook exec with HookFinder when the associated PR will be merged | |
$additionalCustomerFormFields = Hook::exec('additionalCustomerFormFields', ['fields' => &$format], null, true); | |
if (is_array($additionalCustomerFormFields)) { | |
foreach ($additionalCustomerFormFields as $moduleName => $additionnalFormFields) { | |
if (!is_array($additionnalFormFields)) { | |
continue; | |
} | |
foreach ($additionnalFormFields as $formField) { | |
$formField->moduleName = $moduleName; | |
$format[$moduleName . '_' . $formField->getName()] = $formField; | |
} | |
} | |
} | |
// TODO: TVA etc.? | |
return $this->addConstraints($format); | |
} | |
private function addConstraints(array $format) | |
{ | |
$constraints = Customer::$definition['fields']; | |
foreach ($format as $field) { | |
if (!empty($constraints[$field->getName()]['validate'])) { | |
$field->addConstraint( | |
$constraints[$field->getName()]['validate'] | |
); | |
} | |
} | |
return $format; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Copyright since 2007 PrestaShop SA and Contributors | |
* | |
*/ | |
use PrestaShop\PrestaShop\Core\Crypto\Hashing as Crypto; | |
use Symfony\Component\Translation\TranslatorInterface; | |
class CustomerPersister extends CustomerPersisterCore | |
{ | |
private $errors = []; | |
private $context; | |
private $crypto; | |
private $translator; | |
private $guest_allowed; | |
public function __construct( | |
Context $context, | |
Crypto $crypto, | |
TranslatorInterface $translator, | |
$guest_allowed | |
) { | |
$this->context = $context; | |
$this->crypto = $crypto; | |
$this->translator = $translator; | |
$this->guest_allowed = $guest_allowed; | |
} | |
public function getErrors() | |
{ | |
return $this->errors; | |
} | |
public function save(Customer $customer, $clearTextPassword, $newPassword = '', $passwordRequired = true) | |
{ | |
if ($customer->id) { | |
return $this->update($customer, $clearTextPassword, $newPassword, $passwordRequired); | |
} | |
return $this->create($customer, $clearTextPassword); | |
} | |
private function update(Customer $customer, $clearTextPassword, $newPassword, $passwordRequired = true) | |
{ | |
if (!$customer->is_guest && $passwordRequired && !$this->crypto->checkHash( | |
$clearTextPassword, | |
$customer->passwd, | |
_COOKIE_KEY_ | |
)) { | |
$msg = $this->translator->trans( | |
'Invalid email/password combination', | |
[], | |
'Shop.Notifications.Error' | |
); | |
$this->errors['email'][] = $msg; | |
$this->errors['password'][] = $msg; | |
return false; | |
} | |
if (!$customer->is_guest) { | |
$customer->passwd = $this->crypto->hash( | |
$newPassword ? $newPassword : $clearTextPassword, | |
_COOKIE_KEY_ | |
); | |
} | |
if ($customer->is_guest || !$passwordRequired) { | |
// TODO SECURITY: Audit requested | |
if ($customer->id != $this->context->customer->id) { | |
// Since we're updating a customer without | |
// checking the password, we need to check that | |
// the customer being updated is the one from the | |
// current session. | |
// The error message is not great, | |
// but it should only be displayed to hackers | |
// so it should not be an issue :) | |
$this->errors['email'][] = $this->translator->trans( | |
'There seems to be an issue with your account, please contact support', | |
[], | |
'Shop.Notifications.Error' | |
); | |
return false; | |
} | |
} | |
$guest_to_customer = false; | |
if ($clearTextPassword && $customer->is_guest) { | |
$guest_to_customer = true; | |
$customer->is_guest = false; | |
$customer->passwd = $this->crypto->hash( | |
$clearTextPassword, | |
_COOKIE_KEY_ | |
); | |
} | |
if ($customer->is_guest || $guest_to_customer) { | |
// guest cannot update their email to that of an existing real customer | |
if (Customer::customerExists($customer->email, false, true)) { | |
$this->errors['email'][] = $this->translator->trans( | |
'An account was already registered with this email address', | |
[], | |
'Shop.Notifications.Error' | |
); | |
return false; | |
} | |
} | |
if ($customer->email != $this->context->customer->email) { | |
$customer->removeResetPasswordToken(); | |
} | |
$ok = $customer->save(); | |
if ($ok) { | |
$this->context->updateCustomer($customer); | |
$this->context->cart->update(); | |
Hook::exec('actionCustomerAccountUpdate', [ | |
'customer' => $customer, | |
]); | |
if ($guest_to_customer) { | |
$this->sendConfirmationMail($customer); | |
$this->sendConfirmationAdminMail($customer); | |
} | |
} | |
return $ok; | |
} | |
private function create(Customer $customer, $clearTextPassword) | |
{ | |
if (!$clearTextPassword) { | |
if (!$this->guest_allowed) { | |
$this->errors['password'][] = $this->translator->trans( | |
'Password is required', | |
[], | |
'Shop.Notifications.Error' | |
); | |
return false; | |
} | |
/** | |
* Warning: this is only safe provided | |
* that guests cannot log in even with the generated | |
* password. That's the case at least at the time of writing. | |
*/ | |
$clearTextPassword = $this->crypto->hash( | |
microtime(), | |
_COOKIE_KEY_ | |
); | |
$customer->is_guest = true; | |
} | |
$customer->passwd = $this->crypto->hash( | |
$clearTextPassword, | |
_COOKIE_KEY_ | |
); | |
if (Customer::customerExists($customer->email, false, true)) { | |
$this->errors['email'][] = $this->translator->trans( | |
'An account was already registered with this email address', | |
[], | |
'Shop.Notifications.Error' | |
); | |
return false; | |
} | |
$ok = $customer->save(); | |
if ($ok) { | |
$this->context->updateCustomer($customer); | |
$this->context->cart->update(); | |
$this->sendConfirmationMail($customer); | |
Hook::exec('actionCustomerAccountAdd', [ | |
'newCustomer' => $customer, | |
]); | |
} | |
return $ok; | |
} | |
private function sendConfirmationMail(Customer $customer) | |
{ | |
if ($customer->is_guest || !Configuration::get('PS_CUSTOMER_CREATION_EMAIL')) { | |
return true; | |
} | |
return Mail::Send( | |
$this->context->language->id, | |
'account', | |
$this->translator->trans( | |
'Welcome!', | |
[], | |
'Emails.Subject' | |
), | |
[ | |
'{firstname}' => $customer->firstname, | |
'{lastname}' => $customer->lastname, | |
'{email}' => $customer->email, | |
], | |
$customer->email, | |
$customer->firstname . ' ' . $customer->lastname | |
); | |
} | |
private function sendConfirmationAdminMail(Customer $customer) | |
{ | |
if ($customer->is_guest || !Configuration::get('PS_CUSTOMER_CREATION_EMAIL')) { | |
return true; | |
} | |
return Mail::Send( | |
$this->context->language->id, | |
'account_for_admin', | |
$this->translator->trans( | |
'New Client!', | |
array(), | |
'Emails.Subject' | |
), | |
array( | |
'{firstname}' => $customer->firstname, | |
'{lastname}' => $customer->lastname, | |
'{type}' => $customer->retail, | |
'{email}' => $customer->email, | |
'{company}' => $customer->company, | |
'{website}' => $customer->website, | |
'{phone}' => $customer->phoneC, | |
'{mobil}' => $customer->mobileC, | |
'{address}' => $customer->addressC, | |
'{zip}' => $customer->zipC, | |
'{city}' => $customer->cityC, | |
'{state}' => $customer->stateC, | |
'{country}' => $customer->countryC, | |
'{about}' => $customer->aboutus, | |
'{extrainfo}' => $customer->extrainfo | |
), | |
'prestigemetalseo@gmail.com', | |
Configuration::get('PS_SHOP_NAME') | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Copyright since 2007 PrestaShop SA and Contributors | |
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA | |
* | |
* NOTICE OF LICENSE | |
* | |
* This source file is subject to the Open Software License (OSL 3.0) | |
* that is bundled with this package in the file LICENSE.md. | |
* It is also available through the world-wide-web at this URL: | |
* https://opensource.org/licenses/OSL-3.0 | |
* 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 https://devdocs.prestashop.com/ for more information. | |
* | |
* @author PrestaShop SA and Contributors <contact@prestashop.com> | |
* @copyright Since 2007 PrestaShop SA and Contributors | |
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) | |
*/ | |
namespace PrestaShop\PrestaShop\Core\Grid\Query; | |
use Doctrine\DBAL\Connection; | |
use Doctrine\DBAL\Query\QueryBuilder; | |
use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; | |
/** | |
* Class CustomerQueryBuilder builds queries to fetch data for customers grid. | |
*/ | |
final class CustomerQueryBuilder extends AbstractDoctrineQueryBuilder | |
{ | |
/** | |
* @var int | |
*/ | |
private $contextLangId; | |
/** | |
* @var int[] | |
*/ | |
private $contextShopIds; | |
/** | |
* @var DoctrineSearchCriteriaApplicatorInterface | |
*/ | |
private $criteriaApplicator; | |
/** | |
* @param Connection $connection | |
* @param string $dbPrefix | |
* @param DoctrineSearchCriteriaApplicatorInterface $criteriaApplicator | |
* @param int $contextLangId | |
* @param int[] $contextShopIds | |
*/ | |
public function __construct( | |
Connection $connection, | |
$dbPrefix, | |
DoctrineSearchCriteriaApplicatorInterface $criteriaApplicator, | |
$contextLangId, | |
array $contextShopIds | |
) { | |
parent::__construct($connection, $dbPrefix); | |
$this->contextLangId = $contextLangId; | |
$this->contextShopIds = $contextShopIds; | |
$this->criteriaApplicator = $criteriaApplicator; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) | |
{ | |
$searchQueryBuilder = $this->getCustomerQueryBuilder($searchCriteria) | |
->select('c.id_customer, c.firstname, c.lastname, c.email, c.active, c.newsletter, c.optin,c.website') | |
->addSelect('c.date_add, gl.name as social_title, s.name as shop_name, c.company'); //MM_ added website field. | |
$this->appendTotalSpentQuery($searchQueryBuilder); | |
$this->appendLastVisitQuery($searchQueryBuilder); | |
$this->applySorting($searchQueryBuilder, $searchCriteria); | |
$this->criteriaApplicator->applyPagination( | |
$searchCriteria, | |
$searchQueryBuilder | |
); | |
return $searchQueryBuilder; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) | |
{ | |
$countQueryBuilder = $this->getCustomerQueryBuilder($searchCriteria) | |
->select('COUNT(*)'); | |
return $countQueryBuilder; | |
} | |
/** | |
* @param SearchCriteriaInterface $searchCriteria | |
* | |
* @return QueryBuilder | |
*/ | |
private function getCustomerQueryBuilder(SearchCriteriaInterface $searchCriteria) | |
{ | |
$queryBuilder = $this->connection->createQueryBuilder() | |
->from($this->dbPrefix . 'customer', 'c') | |
->leftJoin( | |
'c', | |
$this->dbPrefix . 'gender_lang', | |
'gl', | |
'c.id_gender = gl.id_gender AND gl.id_lang = :context_lang_id' | |
) | |
->leftJoin( | |
'c', | |
$this->dbPrefix . 'shop', | |
's', | |
'c.id_shop = s.id_shop' | |
) | |
->where('c.deleted = 0') | |
->andWhere('c.id_shop IN (:context_shop_ids)') | |
->setParameter('context_shop_ids', $this->contextShopIds, Connection::PARAM_INT_ARRAY) | |
->setParameter('context_lang_id', $this->contextLangId); | |
$this->applyFilters($searchCriteria->getFilters(), $queryBuilder); | |
return $queryBuilder; | |
} | |
/** | |
* @param QueryBuilder $queryBuilder | |
*/ | |
private function appendTotalSpentQuery(QueryBuilder $queryBuilder) | |
{ | |
$totalSpentQueryBuilder = $this->connection->createQueryBuilder() | |
->select('SUM(total_paid_real / conversion_rate)') | |
->from($this->dbPrefix . 'orders', 'o') | |
->where('o.id_customer = c.id_customer') | |
->andWhere('o.id_shop IN (:context_shop_ids)') | |
->andWhere('o.valid = 1') | |
->setParameter('context_shop_ids', $this->contextShopIds, Connection::PARAM_INT_ARRAY); | |
$queryBuilder->addSelect('(' . $totalSpentQueryBuilder->getSQL() . ') as total_spent'); | |
} | |
/** | |
* Append "last visit" column to customers query builder. | |
* | |
* @param QueryBuilder $queryBuilder | |
*/ | |
private function appendLastVisitQuery(QueryBuilder $queryBuilder) | |
{ | |
$lastVisitQueryBuilder = $this->connection->createQueryBuilder() | |
->select('con.date_add') | |
->from($this->dbPrefix . 'guest', 'g') | |
->leftJoin('g', $this->dbPrefix . 'connections', 'con', 'con.id_guest = g.id_guest') | |
->where('g.id_customer = c.id_customer') | |
->orderBy('con.date_add', 'DESC') | |
->setMaxResults(1); | |
$queryBuilder->addSelect('(' . $lastVisitQueryBuilder->getSQL() . ') as connect'); | |
} | |
/** | |
* Apply filters to customers query builder. | |
* | |
* @param array $filters | |
* @param QueryBuilder $qb | |
*/ | |
private function applyFilters(array $filters, QueryBuilder $qb) | |
{ | |
$allowedFilters = [ | |
'id_customer', | |
'social_title', | |
'firstname', | |
'lastname', | |
'email', | |
'website',//MM_ | |
'active', | |
'newsletter', | |
'optin', | |
'date_add', | |
'company', | |
]; | |
foreach ($filters as $filterName => $filterValue) { | |
if (!in_array($filterName, $allowedFilters)) { | |
continue; | |
} | |
if (in_array($filterName, ['active', 'newsletter', 'optin', 'id_customer'])) { | |
$qb->andWhere('c.`' . $filterName . '` = :' . $filterName); | |
$qb->setParameter($filterName, $filterValue); | |
continue; | |
} | |
if ('social_title' === $filterName) { | |
$qb->andWhere('gl.id_gender = :' . $filterName); | |
$qb->setParameter($filterName, $filterValue); | |
continue; | |
} | |
if ('date_add' === $filterName) { | |
if (isset($filterValue['from'])) { | |
$qb->andWhere('c.date_add >= :date_from'); | |
$qb->setParameter('date_from', sprintf('%s 0:0:0', $filterValue['from'])); | |
} | |
if (isset($filterValue['to'])) { | |
$qb->andWhere('c.date_add <= :date_to'); | |
$qb->setParameter('date_to', sprintf('%s 23:59:59', $filterValue['to'])); | |
} | |
continue; | |
} | |
$qb->andWhere('c.`' . $filterName . '` LIKE :' . $filterName); | |
$qb->setParameter($filterName, '%' . $filterValue . '%'); | |
} | |
} | |
/** | |
* Apply sorting so search query builder for customers. | |
* | |
* @param QueryBuilder $searchQueryBuilder | |
* @param SearchCriteriaInterface $searchCriteria | |
*/ | |
private function applySorting(QueryBuilder $searchQueryBuilder, SearchCriteriaInterface $searchCriteria) | |
{ | |
switch ($searchCriteria->getOrderBy()) { | |
case 'id_customer': | |
case 'firstname': | |
case 'lastname': | |
case 'email': | |
case 'website': //MM_ | |
case 'date_add': | |
case 'company': | |
case 'active': | |
case 'newsletter': | |
case 'optin': | |
$orderBy = 'c.' . $searchCriteria->getOrderBy(); | |
break; | |
case 'social_title': | |
$orderBy = 'gl.name'; | |
break; | |
case 'connect': | |
case 'total_spent': | |
$orderBy = $searchCriteria->getOrderBy(); | |
break; | |
default: | |
return; | |
} | |
$searchQueryBuilder->orderBy($orderBy, $searchCriteria->getOrderWay()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Copyright since 2007 PrestaShop SA and Contributors | |
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA | |
* | |
* NOTICE OF LICENSE | |
* | |
* This source file is subject to the Open Software License (OSL 3.0) | |
* that is bundled with this package in the file LICENSE.md. | |
* It is also available through the world-wide-web at this URL: | |
* https://opensource.org/licenses/OSL-3.0 | |
* 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 https://devdocs.prestashop.com/ for more information. | |
* | |
* @author PrestaShop SA and Contributors <contact@prestashop.com> | |
* @copyright Since 2007 PrestaShop SA and Contributors | |
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) | |
*/ | |
namespace PrestaShop\PrestaShop\Adapter\Customer\QueryHandler; | |
use Carrier; | |
use Cart; | |
use CartRule; | |
use Category; | |
use Context; | |
use Currency; | |
use Customer; | |
use CustomerThread; | |
use Db; | |
use Gender; | |
use Group; | |
use Language; | |
use Link; | |
use Order; | |
use PrestaShop\PrestaShop\Adapter\LegacyContext; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerNotFoundException; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerForViewing; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryHandler\GetCustomerForViewingHandlerInterface; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\AddressInformation; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\BoughtProductInformation; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\CartInformation; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\DiscountInformation; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\GeneralInformation; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\GroupInformation; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\LastConnectionInformation; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\MessageInformation; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\OrderInformation; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\OrdersInformation; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\PersonalInformation; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\ProductsInformation; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\ReferrerInformation; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\SentEmailInformation; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\Subscriptions; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\ViewableCustomer; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\ViewedProductInformation; | |
use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; | |
use PrestaShop\PrestaShop\Core\Localization\Locale; | |
use Product; | |
use Referrer; | |
use Shop; | |
use Symfony\Component\Translation\TranslatorInterface; | |
use Tools; | |
use Validate; | |
/** | |
* Handles commands which gets customer for viewing in Back Office. | |
* | |
* @internal | |
*/ | |
final class GetCustomerForViewingHandler implements GetCustomerForViewingHandlerInterface | |
{ | |
/** | |
* @var LegacyContext | |
*/ | |
private $context; | |
/** | |
* @var int | |
*/ | |
private $contextLangId; | |
/** | |
* @var TranslatorInterface | |
*/ | |
private $translator; | |
/** | |
* @var Link | |
*/ | |
private $link; | |
/** | |
* @var Locale | |
*/ | |
private $locale; | |
/** | |
* @param TranslatorInterface $translator | |
* @param int $contextLangId | |
* @param Link $link | |
* @param Locale $locale | |
*/ | |
public function __construct( | |
TranslatorInterface $translator, | |
$contextLangId, | |
Link $link, | |
Locale $locale | |
) { | |
$this->context = new LegacyContext(); | |
$this->contextLangId = $contextLangId; | |
$this->translator = $translator; | |
$this->link = $link; | |
$this->locale = $locale; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function handle(GetCustomerForViewing $query) | |
{ | |
$customerId = $query->getCustomerId(); | |
$customer = new Customer($customerId->getValue()); | |
$this->assertCustomerWasFound($customerId, $customer); | |
Context::getContext()->customer = $customer; | |
return new ViewableCustomer( | |
$customerId, | |
$this->getGeneralInformation($customer), | |
$this->getPersonalInformation($customer), | |
$this->getCustomerOrders($customer), | |
$this->getCustomerCarts($customer), | |
$this->getCustomerProducts($customer), | |
$this->getCustomerMessages($customer), | |
$this->getCustomerDiscounts($customer), | |
$this->getLastEmailsSentToCustomer($customer), | |
$this->getLastCustomerConnections($customer), | |
$this->getCustomerGroups($customer), | |
$this->getCustomerReferrers($customer), | |
$this->getCustomerAddresses($customer) | |
); | |
} | |
/** | |
* @param Customer $customer | |
* | |
* @return GeneralInformation | |
*/ | |
private function getGeneralInformation(Customer $customer) | |
{ | |
return new GeneralInformation( | |
$customer->note, | |
Customer::customerExists($customer->email) | |
); | |
} | |
/** | |
* @param Customer $customer | |
* | |
* @return PersonalInformation | |
*/ | |
private function getPersonalInformation(Customer $customer) | |
{ | |
$customerStats = $customer->getStats(); | |
$gender = new Gender($customer->id_gender, $this->contextLangId); | |
$socialTitle = $gender->name ?: $this->translator->trans('Unknown', [], 'Admin.Orderscustomers.Feature'); | |
if ($customer->birthday && '0000-00-00' !== $customer->birthday) { | |
$birthday = sprintf( | |
$this->translator->trans('%1$d years old (birth date: %2$s)', [], 'Admin.Orderscustomers.Feature'), | |
$customerStats['age'], | |
Tools::displayDate($customer->birthday) | |
); | |
} else { | |
$birthday = $this->translator->trans('Unknown', [], 'Admin.Orderscustomers.Feature'); | |
} | |
$registrationDate = Tools::displayDate($customer->date_add, null, true); | |
$lastUpdateDate = Tools::displayDate($customer->date_upd, null, true); | |
$lastVisitDate = $customerStats['last_visit'] ? | |
Tools::displayDate($customerStats['last_visit'], null, true) : | |
$this->translator->trans('Never', [], 'Admin.Global'); | |
$customerShop = new Shop($customer->id_shop); | |
$customerLanguage = new Language($customer->id_lang); | |
$customerSubscriptions = new Subscriptions( | |
(bool) $customer->newsletter, | |
(bool) $customer->optin | |
); | |
return new PersonalInformation( | |
$customer->aboutus, | |
$customer->lastname, | |
$customer->email, | |
$customer->isGuest(), | |
$socialTitle, | |
$birthday, | |
$customer->retail, //MM_ | |
$customer->company, //MM_ | |
$customer->addressC, //MM_ | |
$customer->cityC, //MM_ | |
$customer->countryC, //MM_ | |
$customer->stateC, //MM_ | |
$customer->zipC, //MM_ | |
$customer->phoneC, //MM_ | |
$customer->mobileC, //MM_ | |
$customer->website, //MM_ | |
$customer->aboutus, //MM_ | |
$customer->extrainfo, //MM_ | |
$registrationDate, | |
$lastUpdateDate, | |
$lastVisitDate, | |
$this->getCustomerRankBySales($customer->id), | |
$customerShop->name, | |
$customerLanguage->name, | |
$customerSubscriptions, | |
(bool) $customer->active | |
); | |
} | |
/** | |
* @param int $customerId | |
* | |
* @return int|null customer rank or null if customer is not ranked | |
*/ | |
private function getCustomerRankBySales($customerId) | |
{ | |
$sql = 'SELECT SUM(total_paid_real) FROM ' . _DB_PREFIX_ . 'orders WHERE id_customer = ' . (int) $customerId . ' AND valid = 1'; | |
if ($totalPaid = Db::getInstance()->getValue($sql)) { | |
$sql = ' | |
SELECT SQL_CALC_FOUND_ROWS COUNT(*) | |
FROM ' . _DB_PREFIX_ . 'orders | |
WHERE valid = 1 | |
AND id_customer != ' . (int) $customerId . ' | |
GROUP BY id_customer | |
HAVING SUM(total_paid_real) > ' . (int) $totalPaid; | |
Db::getInstance()->getValue($sql); | |
return (int) Db::getInstance()->getValue('SELECT FOUND_ROWS()') + 1; | |
} | |
return null; | |
} | |
/** | |
* @param Customer $customer | |
* | |
* @return OrdersInformation | |
*/ | |
private function getCustomerOrders(Customer $customer) | |
{ | |
$validOrders = []; | |
$invalidOrders = []; | |
$orders = Order::getCustomerOrders($customer->id, true); | |
$totalSpent = 0; | |
foreach ($orders as $order) { | |
$order['total_paid_real_not_formated'] = $order['total_paid_real']; | |
$order['total_paid_real'] = $this->locale->formatPrice( | |
$order['total_paid_real'], | |
Currency::getIsoCodeById((int) $order['id_currency']) | |
); | |
if (!isset($order['order_state'])) { | |
$order['order_state'] = $this->translator->trans( | |
'There is no status defined for this order.', | |
[], | |
'Admin.Orderscustomers.Notification' | |
); | |
} | |
$customerOrderInformation = new OrderInformation( | |
(int) $order['id_order'], | |
Tools::displayDate($order['date_add']), | |
$order['payment'], | |
$order['order_state'], | |
(int) $order['nb_products'], | |
$order['total_paid_real'] | |
); | |
if ($order['valid']) { | |
$validOrders[] = $customerOrderInformation; | |
$totalSpent += $order['total_paid_real_not_formated'] / $order['conversion_rate']; | |
} else { | |
$invalidOrders[] = $customerOrderInformation; | |
} | |
} | |
return new OrdersInformation( | |
$this->locale->formatPrice($totalSpent, $this->context->getContext()->currency->iso_code), | |
$validOrders, | |
$invalidOrders | |
); | |
} | |
/** | |
* @param Customer $customer | |
* | |
* @return CartInformation[] | |
*/ | |
private function getCustomerCarts(Customer $customer) | |
{ | |
$carts = Cart::getCustomerCarts($customer->id); | |
$customerCarts = []; | |
foreach ($carts as $cart) { | |
$cart = new Cart((int) $cart['id_cart']); | |
Context::getContext()->cart = $cart; | |
$currency = new Currency($cart->id_currency); | |
Context::getContext()->currency = $currency; | |
$carrier = new Carrier($cart->id_carrier); | |
$summary = $cart->getSummaryDetails(); | |
$customerCarts[] = new CartInformation( | |
sprintf('%06d', $cart->id), | |
Tools::displayDate($cart->date_add, null, true), | |
$this->locale->formatPrice($summary['total_price'], $currency->iso_code), | |
$carrier->name | |
); | |
} | |
Context::getContext()->currency = Currency::getDefaultCurrency(); | |
return $customerCarts; | |
} | |
/** | |
* @param Customer $customer | |
* | |
* @return ProductsInformation | |
*/ | |
private function getCustomerProducts(Customer $customer) | |
{ | |
$boughtProducts = []; | |
$viewedProducts = []; | |
$products = $customer->getBoughtProducts(); | |
foreach ($products as $product) { | |
$boughtProducts[] = new BoughtProductInformation( | |
(int) $product['id_order'], | |
Tools::displayDate($product['date_add'], null, false), | |
$product['product_name'], | |
$product['product_quantity'] | |
); | |
} | |
$sql = ' | |
SELECT DISTINCT cp.id_product, c.id_cart, c.id_shop, cp.id_shop AS cp_id_shop | |
FROM ' . _DB_PREFIX_ . 'cart_product cp | |
JOIN ' . _DB_PREFIX_ . 'cart c ON (c.id_cart = cp.id_cart) | |
JOIN ' . _DB_PREFIX_ . 'product p ON (cp.id_product = p.id_product) | |
WHERE c.id_customer = ' . (int) $customer->id . ' | |
AND NOT EXISTS ( | |
SELECT 1 | |
FROM ' . _DB_PREFIX_ . 'orders o | |
JOIN ' . _DB_PREFIX_ . 'order_detail od ON (o.id_order = od.id_order) | |
WHERE product_id = cp.id_product AND o.valid = 1 AND o.id_customer = ' . (int) $customer->id . ' | |
) | |
'; | |
$viewedProductsData = Db::getInstance()->executeS($sql); | |
foreach ($viewedProductsData as $productData) { | |
$product = new Product( | |
$productData['id_product'], | |
false, | |
$this->contextLangId, | |
$productData['id_shop'] | |
); | |
if (!Validate::isLoadedObject($product)) { | |
continue; | |
} | |
$productUrl = $this->link->getProductLink( | |
$product->id, | |
$product->link_rewrite, | |
Category::getLinkRewrite($product->id_category_default, $this->contextLangId), | |
null, | |
null, | |
$productData['cp_id_shop'] | |
); | |
$viewedProducts[] = new ViewedProductInformation( | |
(int) $product->id, | |
$product->name, | |
$productUrl | |
); | |
} | |
return new ProductsInformation( | |
$boughtProducts, | |
$viewedProducts | |
); | |
} | |
/** | |
* @param Customer $customer | |
* | |
* @return MessageInformation[] | |
*/ | |
private function getCustomerMessages(Customer $customer) | |
{ | |
$customerMessages = []; | |
$messages = CustomerThread::getCustomerMessages((int) $customer->id); | |
$messageStatuses = [ | |
'open' => $this->translator->trans('Open', [], 'Admin.Orderscustomers.Feature'), | |
'closed' => $this->translator->trans('Closed', [], 'Admin.Orderscustomers.Feature'), | |
'pending1' => $this->translator->trans('Pending 1', [], 'Admin.Orderscustomers.Feature'), | |
'pending2' => $this->translator->trans('Pending 2', [], 'Admin.Orderscustomers.Feature'), | |
]; | |
foreach ($messages as $message) { | |
$status = isset($messageStatuses[$message['status']]) ? | |
$messageStatuses[$message['status']] : | |
$message['status']; | |
$customerMessages[] = new MessageInformation( | |
(int) $message['id_customer_thread'], | |
substr(strip_tags(html_entity_decode($message['message'], ENT_NOQUOTES, 'UTF-8')), 0, 75), | |
$status, | |
Tools::displayDate($message['date_add'], null, true) | |
); | |
} | |
return $customerMessages; | |
} | |
/** | |
* @param Customer $customer | |
* | |
* @return DiscountInformation[] | |
*/ | |
private function getCustomerDiscounts(Customer $customer) | |
{ | |
$discounts = CartRule::getCustomerCartRules($this->contextLangId, $customer->id, false, false); | |
$customerDiscounts = []; | |
foreach ($discounts as $discount) { | |
$availableQuantity = $discount['quantity'] > 0 ? (int) $discount['quantity_for_user'] : 0; | |
$customerDiscounts[] = new DiscountInformation( | |
(int) $discount['id_cart_rule'], | |
$discount['code'], | |
$discount['name'], | |
(bool) $discount['active'], | |
$availableQuantity | |
); | |
} | |
return $customerDiscounts; | |
} | |
/** | |
* @param Customer $customer | |
* | |
* @return SentEmailInformation[] | |
*/ | |
private function getLastEmailsSentToCustomer(Customer $customer) | |
{ | |
$emails = $customer->getLastEmails(); | |
$customerEmails = []; | |
foreach ($emails as $email) { | |
$customerEmails[] = new SentEmailInformation( | |
Tools::displayDate($email['date_add'], null, true), | |
$email['language'], | |
$email['subject'], | |
$email['template'] | |
); | |
} | |
return $customerEmails; | |
} | |
/** | |
* @param Customer $customer | |
* | |
* @return LastConnectionInformation[] | |
*/ | |
private function getLastCustomerConnections(Customer $customer) | |
{ | |
$connections = $customer->getLastConnections(); | |
$lastConnections = []; | |
if (!is_array($connections)) { | |
$connections = []; | |
} | |
foreach ($connections as $connection) { | |
$httpReferer = $connection['http_referer'] ? | |
preg_replace('/^www./', '', parse_url($connection['http_referer'], PHP_URL_HOST)) : | |
$this->translator->trans('Direct link', [], 'Admin.Orderscustomers.Notification'); | |
$lastConnections[] = new LastConnectionInformation( | |
$connection['id_connections'], | |
Tools::displayDate($connection['date_add']), | |
$connection['pages'], | |
$connection['time'], | |
$httpReferer, | |
$connection['ipaddress'] | |
); | |
} | |
return $lastConnections; | |
} | |
/** | |
* @param Customer $customer | |
* | |
* @return GroupInformation[] | |
*/ | |
private function getCustomerGroups(Customer $customer) | |
{ | |
$groups = $customer->getGroups(); | |
$customerGroups = []; | |
foreach ($groups as $groupId) { | |
$group = new Group($groupId); | |
$customerGroups[] = new GroupInformation( | |
(int) $group->id, | |
$group->name[$this->contextLangId] | |
); | |
} | |
return $customerGroups; | |
} | |
/** | |
* @param Customer $customer | |
* | |
* @return ReferrerInformation[] | |
*/ | |
private function getCustomerReferrers(Customer $customer) | |
{ | |
$referrers = Referrer::getReferrers($customer->id); | |
$customerReferrers = []; | |
foreach ($referrers as $referrer) { | |
$customerReferrers[] = new ReferrerInformation( | |
Tools::displayDate($referrer['date_add'], null, true), | |
$referrer['name'], | |
$referrer['shop_name'] | |
); | |
} | |
return $customerReferrers; | |
} | |
/** | |
* @param Customer $customer | |
* | |
* @return AddressInformation[] | |
*/ | |
private function getCustomerAddresses(Customer $customer) | |
{ | |
$addresses = $customer->getAddresses($this->contextLangId); | |
$customerAddresses = []; | |
foreach ($addresses as $address) { | |
$company = $address['company'] ?: '--'; | |
$fullAddress = sprintf( | |
'%s %s %s %s', | |
$address['address1'], | |
$address['address2'] ?: '', | |
$address['postcode'], | |
$address['city'] | |
); | |
$customerAddresses[] = new AddressInformation( | |
(int) $address['id_address'], | |
$company, | |
sprintf('%s %s', $address['firstname'], $address['lastname']), | |
$fullAddress, | |
$address['country'], | |
(string) $address['phone'], | |
(string) $address['phone_mobile'] | |
); | |
} | |
return $customerAddresses; | |
} | |
/** | |
* @param CustomerId $customerId | |
* @param Customer $customer | |
* | |
* @throws CustomerNotFoundException | |
*/ | |
private function assertCustomerWasFound(CustomerId $customerId, Customer $customer) | |
{ | |
if (!$customer->id) { | |
throw new CustomerNotFoundException($customerId, sprintf('Customer with id "%s" was not found.', $customerId->getValue())); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Files for Backend: | |
src\PrestaShopBundle\Resources\views\Admin\Sell\Customer\Blocks\View\personal_information.html.twig (Display information in Customer details) | |
src\Core\Domain\Customer\QueryResult\PersonalInformation.php (Get personal customer info) | |
src\Core\Grid\Query\CustomerQueryBuilder.php (Add the new fields to queries.) | |
src\Adapter\Customer\QueryHandler\GetCustomerForViewingHandler.php | |
Overrides: | |
override\classes\form\CustomerFormatter.php | |
override\classes\form\CustomerPersister.php | |
override\classes\Customer.php | |
====== ARCHIVOS PARA AGREGAR UN NUEVO CLIENTE =========== | |
public_html/src/PrestaShopBundle/Form/Admin/Sell/Customer | |
* CustomerType.php | |
## INPUTS--> la comparte con el formulario de edición | |
public_html/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks | |
* form.html.twig | |
## LABELS -> la comparte con el formulario de edicion // | |
public_html/src/Adapter/Customer/CommandHandler | |
* AddCustomerHandler.php | |
public_html/src/Core/Domain/Customer/Command | |
* AddCustomerCommand.php | |
public_html/src/Core/Form/IdentifiableObject/DataHandler | |
* CustomerFormDataHandler.php | |
======= ARCHIVOS PARA EDITAR UN CLIENTE =================== | |
public_html/src/PrestaShopBundle/Form/Admin/Sell/Customer | |
* CustomerType.php | |
public_html/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks | |
* form.html.twig | |
public_html/src/Adapter/Customer/QueryHandler | |
* GetCustomerForEditingHandler.php | |
public_html/src/Adapter/Customer/CommandHandler | |
* EditCustomerHandler.php | |
public_html/src/Core/Domain/Customer/QueryResult | |
* EditableCustomer.php | |
public_html/src/Core/Domain/Customer/Command | |
* EditCustomerCommand.php | |
public_html/src/Core/Form/IdentifiableObject/DataHandler | |
* CustomerFormDataHandler.php | |
public_html/src/Core/Form/IdentifiableObject/DataProvider | |
* CustomerFormDataProvider.php | |
======= vista de datos desde el panel de PRINCIPAL DE CLIENTES ===================== | |
### -----------> (se agregaron las variables y metodos) | |
public_html/src/Core/Domain/Customer/QueryResult/PersonalInformation.php | |
### -----------> (obtiene los valores para la vista) | |
public_html/src/Adapter/Customer/QueryHandler/GetCustomerForViewingHandler.php | |
### -----------> (muestra en info del cliente los datos obtenidos) | |
public_html/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/personal_information.html.twig | |
More info here: | |
https://www.prestashop.com/forums/topic/1046689-a%C3%B1adir-campos-a-formulario-de-registro-en-front-y-back-version-1771/ | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{#** | |
* Copyright since 2007 PrestaShop SA and Contributors | |
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA | |
* | |
* NOTICE OF LICENSE | |
* | |
* This source file is subject to the Open Software License (OSL 3.0) | |
* that is bundled with this package in the file LICENSE.md. | |
* It is also available through the world-wide-web at this URL: | |
* https://opensource.org/licenses/OSL-3.0 | |
* 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 https://devdocs.prestashop.com/ for more information. | |
* | |
* @author PrestaShop SA and Contributors <contact@prestashop.com> | |
* @copyright Since 2007 PrestaShop SA and Contributors | |
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) | |
*#} | |
<div class="card customer-personal-informations-card"> | |
<h3 class="card-header"> | |
<i class="material-icons">person</i> | |
{{ customerInformation.personalInformation.firstName }} | |
{{ customerInformation.personalInformation.lastName }} | |
{{ '[%06d]'|format(customerInformation.customerId.value) }} | |
- | |
<a href="mailto:{{ customerInformation.personalInformation.email }}"> | |
{{ customerInformation.personalInformation.email }} | |
</a> | |
<a href="{{ getAdminLink('AdminCustomers', true, {'id_customer': customerInformation.customerId.value, 'updatecustomer': 1, 'back': app.request.uri}) }}" | |
class="tooltip-link float-right edit-link" | |
data-toggle="pstooltip" | |
title="" | |
data-placement="top" | |
data-original-title="{{ 'Edit'|trans({}, 'Admin.Actions') }}" | |
> | |
<i class="material-icons">edit</i> | |
</a> | |
</h3> | |
<div class="card-body"> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Social Title'|trans({}, 'Admin.Global') }} | |
</div> | |
<div class="customer-social-title col-8"> | |
{{ customerInformation.personalInformation.socialTitle }} | |
</div> | |
</div> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Age'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="col-8 customer-birthday"> | |
{{ customerInformation.personalInformation.birthday }} | |
</div> | |
</div> | |
<!--MM_ Extra fields here:--> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Company'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="col-8 customer-birthday"> | |
{{ customerInformation.personalInformation.company }} | |
</div> | |
</div> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Phone'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="col-8 customer-birthday"> | |
{{ customerInformation.personalInformation.phoneC }} | |
</div> | |
</div> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Mobile'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="col-8 customer-birthday"> | |
{{ customerInformation.personalInformation.mobileC }} | |
</div> | |
</div> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Website'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="col-8 customer-birthday"> | |
{{ customerInformation.personalInformation.website }} | |
</div> | |
</div> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Address'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="col-8 customer-birthday"> | |
{{ customerInformation.personalInformation.addressC }} | |
</div> | |
</div> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Zip Code'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="col-8 customer-birthday"> | |
{{ customerInformation.personalInformation.zipC }} | |
</div> | |
</div> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'City'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="col-8 customer-birthday"> | |
{{ customerInformation.personalInformation.cityC }} | |
</div> | |
</div> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'State'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="col-8 customer-birthday"> | |
{{ customerInformation.personalInformation.stateC }} | |
</div> | |
</div> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Country'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="col-8 customer-birthday"> | |
{{ customerInformation.personalInformation.countryC }} | |
</div> | |
</div> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'How did you hear about us?'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="col-8 customer-birthday"> | |
{{ customerInformation.personalInformation.aboutus }} | |
</div> | |
</div> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Additional Information'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="col-8 customer-birthday"> | |
{{ customerInformation.personalInformation.extrainfo }} | |
</div> | |
</div> | |
<!--End MM_ --> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Registration Date'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="col-8 customer-registration-date"> | |
{{ customerInformation.personalInformation.registrationDate }} | |
</div> | |
</div> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Last Visit'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="col-8 customer-last-visit-date"> | |
{{ customerInformation.personalInformation.lastVisitDate }} | |
</div> | |
</div> | |
{% if customerInformation.personalInformation.rankBySales %} | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Best Customer Rank'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="col-8 customer-sales-rank"> | |
{{ customerInformation.personalInformation.rankBySales }} | |
</div> | |
</div> | |
{% endif %} | |
{% if isMultistoreEnabled %} | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Shop'|trans({}, 'Admin.Global') }} | |
</div> | |
<div class="customer-shop-name col-8"> | |
{{ customerInformation.personalInformation.shopName }} | |
</div> | |
</div> | |
{% endif %} | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Language'|trans({}, 'Admin.Global') }} | |
</div> | |
<div class="col-8 customer-language-name"> | |
{{ customerInformation.personalInformation.languageName }} | |
</div> | |
</div> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Registrations'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="col-8"> | |
{% set isNewsletterSubscribed = customerInformation.personalInformation.subscriptions.newsletterSubscribed %} | |
{% set isPartnerOffersSubscribed = customerInformation.personalInformation.subscriptions.partnerOffersSubscribed %} | |
<span class="customer-newsletter-subscription-status badge badge-{% if isNewsletterSubscribed %}success{% else %}danger{% endif %} rounded"> | |
<i class="material-icons">{% if isNewsletterSubscribed %}check{% else %}cancel{% endif %}</i> | |
{{ 'Newsletter'|trans({}, 'Admin.Global') }} | |
</span> | |
<span class="customer-partner-offers-status badge badge-{% if isPartnerOffersSubscribed %}success{% else %}danger{% endif %} rounded"> | |
<i class="material-icons">{% if isPartnerOffersSubscribed %}check{% else %}cancel{% endif %}</i> | |
{{ 'Partner offers'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</span> | |
</div> | |
</div> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Latest Update'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="customer-latest-update col-8"> | |
{{ customerInformation.personalInformation.lastUpdateDate }} | |
</div> | |
</div> | |
<div class="row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'Status'|trans({}, 'Admin.Global') }} | |
</div> | |
<div class="col-8"> | |
{% set isCustomerActive = customerInformation.personalInformation.active %} | |
<span class="customer-status badge badge-{% if isCustomerActive %}success{% else %}danger{% endif %} rounded"> | |
{% if isCustomerActive %} | |
<i class="material-icons">check</i> | |
{{ 'Active'|trans({}, 'Admin.Global') }} | |
{% else %} | |
<i class="material-icons">cancel</i> | |
{{ 'Inactive'|trans({}, 'Admin.Global') }} | |
{% endif %} | |
</span> | |
</div> | |
</div> | |
{% if customerInformation.personalInformation.guest %} | |
{% form_theme transferGuestAccountForm 'PrestaShopBundle:Admin/TwigTemplateForm:prestashop_ui_kit.html.twig' %} | |
<div class="customer-guest-status row mb-1"> | |
<div class="col-4 text-right"> | |
{{ 'This customer is registered as a Guest.'|trans({}, 'Admin.Orderscustomers.Feature') }} | |
</div> | |
<div class="col-8"> | |
{% if customerInformation.generalInformation.customerBySameEmailExists %} | |
<p>{{ 'A registered customer account using the defined email address already exists. '|trans({}, 'Admin.Orderscustomers.Notification') }}</p> | |
{% else %} | |
{{ form_start(transferGuestAccountForm, {'action': path('admin_customers_transform_guest_to_customer', {'customerId': customerInformation.customerId.value})}) }} | |
{{ form_widget(transferGuestAccountForm.transfer_guest_account) }} | |
<p class="small-text"> | |
{{ 'This feature generates a random password before sending an email to your customer.'|trans({}, 'Admin.Orderscustomers.Help') }} | |
</p> | |
{{ form_end(transferGuestAccountForm) }} | |
{% endif %} | |
</div> | |
</div> | |
{% endif %} | |
</div> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Copyright since 2007 PrestaShop SA and Contributors | |
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA | |
* | |
* NOTICE OF LICENSE | |
* | |
* This source file is subject to the Open Software License (OSL 3.0) | |
* that is bundled with this package in the file LICENSE.md. | |
* It is also available through the world-wide-web at this URL: | |
* https://opensource.org/licenses/OSL-3.0 | |
* 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 https://devdocs.prestashop.com/ for more information. | |
* | |
* @author PrestaShop SA and Contributors <contact@prestashop.com> | |
* @copyright Since 2007 PrestaShop SA and Contributors | |
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) | |
*/ | |
namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; | |
/** | |
* Class PersonalInformation holds personal customer information. | |
*/ | |
class PersonalInformation | |
{ | |
/** | |
* @var string | |
*/ | |
private $firstName; | |
/** | |
* @var string | |
*/ | |
private $lastName; | |
/** | |
* @var string | |
*/ | |
private $email; | |
/** | |
* @var bool | |
*/ | |
private $isGuest; | |
/** | |
* @var string | |
*/ | |
private $socialTitle; | |
/** | |
* @var string | |
*/ | |
private $birthday; | |
/** | |
* @var string | |
*/ | |
/** | |
* MM_Extrafields | |
*/ | |
private $retail; | |
private $company; | |
private $addressC; | |
private $cityC; | |
private $countryC; | |
private $stateC; | |
private $zipC; | |
private $phoneC; | |
private $mobileC; | |
private $website; | |
private $aboutus; | |
private $extrainfo; | |
/** | |
* End MM_ | |
*/ | |
/** | |
* @var string | |
*/ | |
private $registrationDate; | |
/** | |
* @var string | |
*/ | |
private $lastUpdateDate; | |
/** | |
* @var string | |
*/ | |
private $lastVisitDate; | |
/** | |
* @var string | |
*/ | |
private $rankBySales; | |
/** | |
* @var string | |
*/ | |
private $shopName; | |
/** | |
* @var string | |
*/ | |
private $languageName; | |
/** | |
* @var Subscriptions | |
*/ | |
private $subscriptions; | |
/** | |
* @var bool | |
*/ | |
private $isActive; | |
/** | |
* @param string $firstName | |
* @param string $lastName | |
* @param string $email | |
* @param bool $isGuest | |
* @param string $socialTitle | |
* @param string $birthday | |
* @param string $registrationDate | |
* @param string $lastUpdateDate | |
* @param string $lastVisitDate | |
* @param string $rankBySales | |
* @param string $shopName | |
* @param string $languageName | |
* @param Subscriptions $subscriptions | |
* @param bool $isActive | |
*/ | |
public function __construct( | |
$firstName, | |
$lastName, | |
$email, | |
$isGuest, | |
$socialTitle, | |
$birthday, | |
$retail, | |
$company, | |
$addressC, | |
$cityC, | |
$countryC, | |
$stateC, | |
$zipC, | |
$phoneC, | |
$mobileC, | |
$website, | |
$aboutus, | |
$extrainfo, | |
$registrationDate, | |
$lastUpdateDate, | |
$lastVisitDate, | |
$rankBySales, | |
$shopName, | |
$languageName, | |
Subscriptions $subscriptions, | |
$isActive | |
) { | |
$this->firstName = $firstName; | |
$this->lastName = $lastName; | |
$this->email = $email; | |
$this->isGuest = $isGuest; | |
$this->socialTitle = $socialTitle; | |
$this->birthday = $birthday; | |
$this->retail = $retail; | |
$this->company = $company; | |
$this->addressC = $addressC; | |
$this->cityC = $cityC; | |
$this->countryC = $countryC; | |
$this->stateC = $stateC; | |
$this->zipC = $zipC; | |
$this->phoneC = $phoneC; | |
$this->mobileC = $mobileC; | |
$this->website = $website; | |
$this->aboutus = $aboutus; | |
$this->extrainfo = $extrainfo; | |
$this->registrationDate = $registrationDate; | |
$this->lastUpdateDate = $lastUpdateDate; | |
$this->lastVisitDate = $lastVisitDate; | |
$this->rankBySales = $rankBySales; | |
$this->shopName = $shopName; | |
$this->languageName = $languageName; | |
$this->subscriptions = $subscriptions; | |
$this->isActive = $isActive; | |
} | |
/** | |
* @return string | |
*/ | |
public function getFirstName() | |
{ | |
return $this->firstName; | |
} | |
/** | |
* @return string | |
*/ | |
public function getLastName() | |
{ | |
return $this->lastName; | |
} | |
/** | |
* @return string | |
*/ | |
public function getEmail() | |
{ | |
return $this->email; | |
} | |
/** | |
* @return bool | |
*/ | |
public function isGuest() | |
{ | |
return $this->isGuest; | |
} | |
/** | |
* @return string | |
*/ | |
public function getSocialTitle() | |
{ | |
return $this->socialTitle; | |
} | |
/** | |
* @return string | |
*/ | |
public function getBirthday() | |
{ | |
return $this->birthday; | |
} | |
/////////////////////////////////////////////// | |
public function getRetail() | |
{ | |
return $this->retail; | |
} | |
public function getCompany() | |
{ | |
return $this->company; | |
} | |
public function getAddressC() | |
{ | |
return $this->addressC; | |
} | |
public function getCityC() | |
{ | |
return $this->cityC; | |
} | |
public function getCountryC() | |
{ | |
return $this->countryC; | |
} | |
public function getStateC() | |
{ | |
return $this->stateC; | |
} | |
public function getZipC() | |
{ | |
return $this->zipC; | |
} | |
public function getPhoneC() | |
{ | |
return $this->phoneC; | |
} | |
public function getMobileC() | |
{ | |
return $this->mobileC; | |
} | |
public function getWebsite() | |
{ | |
return $this->website; | |
} | |
public function getAboutus() | |
{ | |
return $this->aboutus; | |
} | |
public function getExtrainfo() | |
{ | |
return $this->extrainfo; | |
} | |
///////////////////////////////////////////////////// | |
/** | |
* @return string | |
*/ | |
public function getRegistrationDate() | |
{ | |
return $this->registrationDate; | |
} | |
/** | |
* @return string | |
*/ | |
public function getLastUpdateDate() | |
{ | |
return $this->lastUpdateDate; | |
} | |
/** | |
* @return string | |
*/ | |
public function getLastVisitDate() | |
{ | |
return $this->lastVisitDate; | |
} | |
/** | |
* @return string | |
*/ | |
public function getRankBySales() | |
{ | |
return $this->rankBySales; | |
} | |
/** | |
* @return string | |
*/ | |
public function getShopName() | |
{ | |
return $this->shopName; | |
} | |
/** | |
* @return string | |
*/ | |
public function getLanguageName() | |
{ | |
return $this->languageName; | |
} | |
/** | |
* @return Subscriptions | |
*/ | |
public function getSubscriptions() | |
{ | |
return $this->subscriptions; | |
} | |
/** | |
* @return bool | |
*/ | |
public function isActive() | |
{ | |
return $this->isActive; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment