Jump to content

Manage multiple email for ONE customer


LoicCDIP

Recommended Posts

Hi all,

 

First, sorry for my English.

 

I search a module, or a developpement for allow customers to set multiple email in there account. In back-office, I want to set one or tow or many emails for ONE customer.

 

It is possible with a module ? (I think not)

With a specific developpement ?

 

Thanks for your answer !

 

Loïc

Link to comment
Share on other sites

Hi all, I find a solution, in French

 

j'ai crée une table 'customer_MergeMail' où j'ai créé 2 champs:

  • id_customer
  • email

Et j'ai override la classe Customer pour y modifier les connexion des utilisateurs. Mes clients peuvent maintenant se connecter à leur compte depuis plusieurs emails.

/**
    * Return customer instance from its e-mail (optionnaly check password)
    *
    * OVERRIDE: Vérifie Maintenant la table 'customer_MergeMail' pour vérifier si un utilisateur possède plusieurs mails
    * OVERRIDE: Test aussi le mot de passe sans la _COOKIE_KEY_ pour les clients venant de Drupal
    * 
    * @param string $email e-mail
    * @param string $passwd Password is also checked if specified
    * @return Customer instance
    */
   public function getByEmail($email, $passwd = null, $ignore_guest = true) {
      if (!Validate::isEmail($email) || ($passwd && !Validate::isPasswd($passwd)))
         die(Tools::displayError());

      $result = Db::getInstance()->getRow('
		SELECT c.*
		FROM `' . _DB_PREFIX_ . 'customer` c
      INNER JOIN `customer_MergeMail` cm USING(id_customer)
		WHERE (c.`email` = \'' . pSQL($email) . '\' OR cm.`email` =\'' . pSQL($email) . '\')
		' . Shop::addSqlRestriction(Shop::SHARE_CUSTOMER) . '
		' . (isset($passwd) ? 'AND (`passwd` = \'' . pSQL(Tools::encrypt($passwd)) . '\' OR `passwd` = \'' . pSQL(md5($passwd)) . '\')' : '') . '
		AND `deleted` = 0
		' . ($ignore_guest ? ' AND `is_guest` = 0' : ''));

      if (!$result)
         return false;
      $this->id = $result['id_customer'];
      foreach ($result as $key => $value)
         if (array_key_exists($key, $this))
            $this->{$key} = $value;

      return $this;
   }

   /**
    * Retrieve customers by email address
    *
    * OVERRIDE: Vérifie Maintenant la table 'customer_MergeMail' pour vérifier si un utilisateur possède plusieurs mails
    * 
    * @static
    * @param $email
    * @return array
    */
   public static function getCustomersByEmail($email) {
      $sql = 'SELECT *
               FROM `' . _DB_PREFIX_ . 'customer` c
               INNER JOIN `customer_MergeMail` cm USING(id_customer)
               WHERE (c.`email` = \'' . pSQL($email) . '\' OR cm.`email` =\'' . pSQL($email) . '\')
					' . Shop::addSqlRestriction(Shop::SHARE_CUSTOMER);

      return Db::getInstance()->ExecuteS($sql);
   }

   /**
    * Check if e-mail is already registered in database
    *
    * OVERRIDE: Vérifie Maintenant la table 'customer_MergeMail' pour vérifier si un utilisateur possède plusieurs mails
    * 
    * @param string $email e-mail
    * @param $return_id boolean
    * @param $ignore_guest boolean, to exclude guest customer
    * @return Customer ID if found, false otherwise
    */
   public static function customerExists($email, $return_id = false, $ignore_guest = true) {
      if (!Validate::isEmail($email)) {
         if (defined('_PS_MODE_DEV_') && _PS_MODE_DEV_)
            die(Tools::displayError('Invalid email'));
         return false;
      }

      $result = Db::getInstance()->getValue('
		SELECT `id_customer`
		FROM `' . _DB_PREFIX_ . 'customer` c
      INNER JOIN `customer_MergeMail` cm USING(id_customer)
		WHERE (c.`email` = \'' . pSQL($email) . '\' OR cm.`email` =\'' . pSQL($email) . '\')
		' . Shop::addSqlRestriction(Shop::SHARE_CUSTOMER) . '
		' . ($ignore_guest ? ' AND `is_guest` = 0' : ''));
      return ($return_id ? (int) $result : (bool) $result);
   }

Du coup, prestashop test aussi dans l'autre table si le mail existe.

 

Merci !

Link to comment
Share on other sites

et si au lieu de mettre INNER JOIN ... qui ne sert pas à retourner des valeurs, tu utilisais la syntaxe Exists(select ....

C'est d'ailleurs ce qu'ils ont utilisé pour optimiser les requêtes dans la mise à jour 1.6.1.1

 

SELECT c.*
        FROM `'
. _DB_PREFIX_ . 'customer` c
        WHERE (c.`email` = \''
. pSQL($email) . '\'

          or exists(select 1 from `customer_MergeMail` cm where cm.id_customer = c.id_customer and cm.`email` =\'' . pSQL($email) . '\'))
        '
. Shop::addSqlRestriction(Shop::SHARE_CUSTOMER) . '
        '
. (isset($passwd) ? 'AND (`passwd` = \'' . pSQL(Tools::encrypt($passwd)) . '\' OR `passwd` = \'' . pSQL(md5($passwd)) . '\')' : '') . '
        AND `deleted` = 0
        '
. ($ignore_guest ? ' AND `is_guest` = 0' : ''));

Edited by rvcat (see edit history)
Link to comment
Share on other sites

et puis pour que tes requêtes soient plus rapides, la table customer_MergeMail doit contenir tous les mails les autres mails et le mail de la table customer.

Le champ email tu mets un index id_customer + email.

 

En faisant comme ça tu élimines (c.`email` = \'' . pSQL($email) . '\' or) et tu laisses que le exists(select ...

 

l'instruction or coute un peu cher en temps d'exécution. si tu as 100 clients ça passera si tu as +2000 clients là tu sentira la différence.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...