From a265bec7caedb094d1c44fdf65725d3dbe166a99 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 23 Aug 2020 02:38:56 +0200 Subject: [PATCH] NEW Events in agenda for contact FIX Saving contacts of an events --- htdocs/admin/agenda.php | 3 +- htdocs/comm/action/card.php | 3 +- htdocs/comm/action/class/actioncomm.class.php | 15 ++++++-- htdocs/contact/card.php | 23 ++++++++++++ htdocs/core/actions_sendmails.inc.php | 35 +++++++++++-------- htdocs/core/class/html.formactions.class.php | 2 +- ...terface_50_modAgenda_ActionsAuto.class.php | 35 ++++++++++++++----- htdocs/cron/list.php | 6 ++-- .../mysql/data/llx_c_action_trigger.sql | 4 +++ .../install/mysql/migration/12.0.0-13.0.0.sql | 4 +++ htdocs/langs/en_US/agenda.lang | 2 ++ htdocs/langs/en_US/errors.lang | 1 + 12 files changed, 101 insertions(+), 32 deletions(-) diff --git a/htdocs/admin/agenda.php b/htdocs/admin/agenda.php index 382f242b7e7..1a29595a9ab 100644 --- a/htdocs/admin/agenda.php +++ b/htdocs/admin/agenda.php @@ -165,6 +165,7 @@ if (!empty($triggers)) if ($module == 'member') $module = 'adherent'; if ($module == 'project') $module = 'projet'; if ($module == 'proposal_supplier') $module = 'supplier_proposal'; + if ($module == 'contact') $module = 'societe'; // If 'element' value is myobject@mymodule instead of mymodule $tmparray = explode('@', $module); @@ -172,7 +173,7 @@ if (!empty($triggers)) $module = $tmparray[1]; } - //print 'module='.$module.'
'; + //print 'module='.$module.' code='.$trigger['code'].'
'; if (!empty($conf->$module->enabled)) { // Discard special case: If option FICHINTER_CLASSIFY_BILLED is not set, we discard both trigger FICHINTER_CLASSIFY_BILLED and FICHINTER_CLASSIFY_UNBILLED diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 72ffd2b6bba..eb723013f81 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -248,7 +248,7 @@ if (empty($reshook) && $action == 'add') if (!$error) { // Initialisation objet actioncomm - $object->priority = GETPOST("priority") ?GETPOST("priority") : 0; + $object->priority = GETPOST("priority") ? GETPOST("priority") : 0; $object->fulldayevent = (!empty($fulldayevent) ? 1 : 0); $object->location = GETPOST("location"); $object->label = trim(GETPOST('label')); @@ -1706,6 +1706,7 @@ if ($id > 0) } print ''; } + // Categories if ($conf->categorie->enabled) { print ''.$langs->trans("Categories").''; diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 4fb80592adf..1e860217d03 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -492,7 +492,7 @@ class ActionComm extends CommonObject $sql .= ((isset($this->socid) && $this->socid > 0) ? $this->socid : "null").", "; $sql .= ((isset($this->fk_project) && $this->fk_project > 0) ? $this->fk_project : "null").", "; $sql .= " '".$this->db->escape($this->note_private)."', "; - $sql .= ((isset($this->contact_id) && $this->contact_id > 0) ? $this->contact_id : "null").", "; + $sql .= ((isset($this->contact_id) && $this->contact_id > 0) ? $this->contact_id : "null").", "; // deprecated, use ->socpeopleassigned $sql .= (isset($user->id) && $user->id > 0 ? $user->id : "null").", "; $sql .= ($userownerid > 0 ? $userownerid : "null").", "; $sql .= ($userdoneid > 0 ? $userdoneid : "null").", "; @@ -1141,8 +1141,17 @@ class ActionComm extends CommonObject if (!empty($socid)) $sql .= " AND a.fk_soc = ".$socid; if (!empty($elementtype)) { - if ($elementtype == 'project') $sql .= ' AND a.fk_project = '.$fk_element; - else $sql .= " AND a.fk_element = ".(int) $fk_element." AND a.elementtype = '".$elementtype."'"; + if ($elementtype == 'project') { + $sql .= ' AND a.fk_project = '.$fk_element; + } + elseif ($elementtype == 'contact') { + $sql .= ' AND a.id IN'; + $sql .= " (SELECT fk_actioncomm FROM ".MAIN_DB_PREFIX."actioncomm_resources WHERE"; + $sql .= " element_type = 'socpeople' AND fk_element = ".$fk_element.')'; + } + else { + $sql .= " AND a.fk_element = ".(int) $fk_element." AND a.elementtype = '".$elementtype."'"; + } } if (!empty($filter)) $sql .= $filter; if ($sortorder && $sortfield) $sql .= $db->order($sortfield, $sortorder); diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index eeb51e65442..97ae42c3122 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -1527,6 +1527,29 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) print ""; + //Select mail models is same action as presend + if (GETPOST('modelselected')) { + $action = 'presend'; + } + + if ($action != 'presend') + { + print '
'; + + print '
'; + + $MAXEVENT = 10; + + $morehtmlright = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-list-alt imgforviewmode', DOL_URL_ROOT.'/contact/agenda.php?id='.$object->id); + + // List of actions on element + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; + $formactions = new FormActions($db); + $somethingshown = $formactions->showactions($object, 'contact', $object->socid, 1, '', $MAXEVENT, '', $morehtmlright); // Show all action for thirdparty + + print '
'; + } + // Presend form $modelmail = 'contact'; $defaulttopic = 'Information'; diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index bc38d9839af..4cfa0531a08 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -114,12 +114,11 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST $result = $object->fetch($id); $sendtosocid = 0; // Id of related thirdparty - if (method_exists($object, "fetch_thirdparty") && !in_array($object->element, array('societe', 'member', 'user', 'expensereport', 'contact'))) + if (method_exists($object, "fetch_thirdparty") && !in_array($object->element, array('member', 'user', 'expensereport', 'societe', 'contact'))) { - $result = $object->fetch_thirdparty(); - if ($object->element == 'user' && $result == 0) $result = 1; // Even if not found, we consider ok + $resultthirdparty = $object->fetch_thirdparty(); $thirdparty = $object->thirdparty; - $sendtosocid = $thirdparty->id; + if (is_object($thirdparty)) $sendtosocid = $thirdparty->id; } elseif ($object->element == 'member' || $object->element == 'user') { $thirdparty = $object; @@ -133,11 +132,15 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST } elseif ($object->element == 'societe') { $thirdparty = $object; - if ($thirdparty->id > 0) $sendtosocid = $thirdparty->id; + if (is_object($thirdparty) && $thirdparty->id > 0) $sendtosocid = $thirdparty->id; } elseif ($object->element == 'contact') { $contact = $object; - if ($contact->id > 0) $sendtosocid = $contact->fetch_thirdparty()->id; + if ($contact->id > 0) { + $contact->fetch_thirdparty(); + $thirdparty = $contact->thirdparty; + if (is_object($thirdparty) && $thirdparty->id > 0) $sendtosocid = $thirdparty->id; + } } else dol_print_error('', "Use actions_sendmails.in.php for an element/object '".$object->element."' that is not supported"); if (is_object($hookmanager)) @@ -145,7 +148,9 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST $parameters = array(); $reshook = $hookmanager->executeHooks('initSendToSocid', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks } - } else $thirdparty = $mysoc; + } else { + $thirdparty = $mysoc; + } if ($result > 0) { @@ -170,23 +175,24 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST // Recipients are provided into free text $tmparray[] = trim($_POST['sendto']); } + if (count($receiver) > 0) { + // Recipient was provided from combo list foreach ($receiver as $key=>$val) { - // Recipient was provided from combo list - if ($val == 'thirdparty') // Key selected means currentthird party (may be usd for current member or current user too) + if ($val == 'thirdparty') // Key selected means current third party ('thirdparty' may be used for current member or current user too) { $tmparray[] = dol_string_nospecial($thirdparty->getFullName($langs), ' ', array(",")).' <'.$thirdparty->email.'>'; } - // Recipient was provided from combo list elseif ($val == 'contact') // Key selected means current contact { $tmparray[] = dol_string_nospecial($contact->getFullName($langs), ' ', array(",")).' <'.$contact->email.'>'; + $sendtoid[] = $contact->id; } elseif ($val) // $val is the Id of a contact { $tmparray[] = $thirdparty->contact_get_property((int) $val, 'email'); - $sendtoid[] = $val; + $sendtoid[] = ((int) $val); } } } @@ -232,10 +238,11 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST elseif ($val == 'contact') // Key selected means current contact { $tmparray[] = dol_string_nospecial($contact->name, ' ', array(",")).' <'.$contact->email.'>'; + //$sendtoid[] = $contact->id; TODO Add also id of contact in CC ? } elseif ($val) // $val is the Id of a contact { $tmparray[] = $thirdparty->contact_get_property((int) $val, 'email'); - //$sendtoid[] = $val; TODO Add also id of contact in CC ? + //$sendtoid[] = ((int) $val); TODO Add also id of contact in CC ? } } } @@ -415,7 +422,7 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST if (empty($actiontypecode)) $actiontypecode = 'AC_OTH_AUTO'; // Event insert into agenda automatically $object->socid = $sendtosocid; // To link to a company - $object->sendtoid = $sendtoid; // To link to contact addresses. This is an array. + $object->sendtoid = $sendtoid; // To link to contact-addresses. This is an array. $object->actiontypecode = $actiontypecode; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...) $object->actionmsg = $actionmsg; // Long text (@todo Replace this with $message, we already have details of email in dedicated properties) $object->actionmsg2 = $actionmsg2; // Short text ($langs->transnoentities('MailSentBy')...); @@ -486,7 +493,7 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST $action = 'presend'; } } else { - $langs->load("other"); + $langs->load("errors"); setEventMessages($langs->trans('ErrorFailedToReadObject', $object->element), null, 'errors'); dol_syslog('Failed to read data of object id='.$object->id.' element='.$object->element); $action = 'presend'; diff --git a/htdocs/core/class/html.formactions.class.php b/htdocs/core/class/html.formactions.class.php index 9baec43790c..4ec8e29c966 100644 --- a/htdocs/core/class/html.formactions.class.php +++ b/htdocs/core/class/html.formactions.class.php @@ -157,7 +157,7 @@ class FormActions * Show list of actions for element * * @param Object $object Object - * @param string $typeelement 'invoice','propal','order','invoice_supplier','order_supplier','fichinter' + * @param string $typeelement 'invoice', 'propal', 'order', 'invoice_supplier', 'order_supplier', 'fichinter' * @param int $socid Socid of user * @param int $forceshowtitle Show title even if there is no actions to show * @param string $morecss More css on table diff --git a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php index 1d70938e87c..0874698456f 100644 --- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php +++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php @@ -56,7 +56,7 @@ class InterfaceActionsAuto extends DolibarrTriggers * $object->actiontypecode (translation action code: AC_OTH, ...) * $object->actionmsg (note, long text) * $object->actionmsg2 (label, short text) - * $object->sendtoid (id of contact or array of ids) + * $object->sendtoid (id of contact or array of ids of contacts) * $object->socid (id of thirdparty) * $object->fk_project * $object->fk_element @@ -71,7 +71,7 @@ class InterfaceActionsAuto extends DolibarrTriggers */ public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf) { - if (empty($conf->agenda->enabled)) return 0; // Module not active, we do nothing + if (empty($conf->agenda->enabled)) return 0; // Module not active, we do nothing $key = 'MAIN_AGENDA_ACTIONAUTO_'.$action; @@ -92,7 +92,6 @@ class InterfaceActionsAuto extends DolibarrTriggers if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("NewCompanyToDolibarr", $object->name); $object->actionmsg = $langs->transnoentities("NewCompanyToDolibarr", $object->name); - if (!empty($object->prefix)) $object->actionmsg .= " (".$object->prefix.")"; $object->sendtoid = 0; $object->socid = $object->id; @@ -105,7 +104,17 @@ class InterfaceActionsAuto extends DolibarrTriggers // Parameters $object->sendtoid defined by caller //$object->sendtoid=0; - } elseif ($action == 'CONTRACT_VALIDATE') + } elseif ($action == 'CONTACT_CREATE') + { + // Load translation files required by the page + $langs->loadLangs(array("agenda", "other", "companies")); + + if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities("CONTACT_CREATEInDolibarr", $object->getFullName($langs)); + $object->actionmsg = $langs->transnoentities("CONTACT_CREATEInDolibarr", $object->getFullName($langs)); + + $object->sendtoid = array($object->id => $object->id); + $object->socid = $object->socid; + } elseif ($action == 'CONTRACT_VALIDATE') { // Load translation files required by the page $langs->loadLangs(array("agenda", "other", "contracts")); @@ -769,8 +778,9 @@ class InterfaceActionsAuto extends DolibarrTriggers $object->sendtoid = 0; } // TODO Merge all previous cases into this generic one - else // $action = BILL_DELETE, TICKET_CREATE, TICKET_MODIFY, TICKET_DELETE, ... + else // $action = BILL_DELETE, TICKET_CREATE, TICKET_MODIFY, TICKET_DELETE, CONTACT_SENTBYMAIL, ... { + // Note: We are here only if $conf->global->MAIN_AGENDA_ACTIONAUTO_action is on (tested at begining of this function). // Note that these key can be set in agenda setup, only if defined into c_action_trigger // Load translation files required by the page @@ -779,7 +789,9 @@ class InterfaceActionsAuto extends DolibarrTriggers if (empty($object->actionmsg2)) $object->actionmsg2 = $langs->transnoentities($action."InDolibarr", $object->ref); if (empty($object->actionmsg)) $object->actionmsg = $langs->transnoentities($action."InDolibarr", $object->ref); - $object->sendtoid = 0; + if (! isset($object->sendtoid) || ! is_array($object->sendtoid)) { + $object->sendtoid = 0; + } } $object->actionmsg = $langs->transnoentities("Author").': '.$user->login."\n".$object->actionmsg; @@ -797,12 +809,12 @@ class InterfaceActionsAuto extends DolibarrTriggers $object->actionmsg = dol_concatdesc($object->actionmsg, "\n".$langs->transnoentities("AttachedFiles").': '.$attachs); } } - require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; $contactforaction = new Contact($this->db); $societeforaction = new Societe($this->db); // Set contactforaction if there is only 1 contact. + if (is_array($object->sendtoid)) { if (count($object->sendtoid) == 1) $contactforaction->fetch(reset($object->sendtoid)); @@ -838,7 +850,7 @@ class InterfaceActionsAuto extends DolibarrTriggers $actioncomm->durationp = 0; $actioncomm->percentage = -1; // Not applicable $actioncomm->socid = $societeforaction->id; - $actioncomm->contact_id = $contactforaction->id; + $actioncomm->contact_id = $contactforaction->id; // deprecated, use ->socpeopleassigned instead $actioncomm->authorid = $user->id; // User saving action $actioncomm->userownerid = $user->id; // Owner of action // Fields defined when action is an email (content should be into object->actionmsg to be added into note, subject into object->actionms2 to be added into label) @@ -852,7 +864,7 @@ class InterfaceActionsAuto extends DolibarrTriggers $actioncomm->errors_to = $object->errors_to; // Object linked (if link is for thirdparty, contact, project it is a recording error. We should not have links in link table - // for such objects because there is already a dedicated field into table llx_actioncomm. + // for such objects because there is already a dedicated field into table llx_actioncomm or llx_actioncomm_resources. if (!in_array($elementtype, array('societe', 'contact', 'project'))) { $actioncomm->fk_element = $elementid; @@ -865,6 +877,11 @@ class InterfaceActionsAuto extends DolibarrTriggers if (property_exists($object, 'sendtouserid') && is_array($object->sendtouserid) && count($object->sendtouserid) > 0) { $actioncomm->userassigned = $object->sendtouserid; } + if (property_exists($object, 'sendtoid') && is_array($object->sendtoid) && count($object->sendtoid) > 0) { + foreach($object->sendtoid as $val) { + $actioncomm->socpeopleassigned[$val] = $val; + } + } $ret = $actioncomm->create($user); // User creating action diff --git a/htdocs/cron/list.php b/htdocs/cron/list.php index 45c938da7bf..4b70b229ae1 100644 --- a/htdocs/cron/list.php +++ b/htdocs/cron/list.php @@ -347,7 +347,7 @@ if (!empty($conf->global->CRON_WARNING_DELAY_HOURS)) $text .= $langs->trans("War print info_admin($text); print '
'; -$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; +//$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; $selectedfields = ''; //$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); @@ -432,11 +432,11 @@ if ($num > 0) print ''; // Label - print ''; + print ''; if (!empty($obj->label)) { $object->ref = $langs->trans($obj->label); - print $object->getNomUrl(0, '', 1); + print ''.$object->getNomUrl(0, '', 1).''; $object->ref = $obj->rowid; } else { //print $langs->trans('CronNone'); diff --git a/htdocs/install/mysql/data/llx_c_action_trigger.sql b/htdocs/install/mysql/data/llx_c_action_trigger.sql index dee1200389c..d54ac24a203 100644 --- a/htdocs/install/mysql/data/llx_c_action_trigger.sql +++ b/htdocs/install/mysql/data/llx_c_action_trigger.sql @@ -128,7 +128,11 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MRP_MO_PRODUCED','MO produced','Executed when a MO is produced','bom',661); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MRP_MO_DELETE','MO deleted','Executed when a MO is deleted','bom',662); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MRP_MO_CANCEL','MO canceled','Executed when a MO is canceled','bom',663); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTACT_CREATE','Contact address created','Executed when a contact is created','contact',50); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTACT_SENTBYMAIL','Mails sent from third party card','Executed when you send email from contact adress card','contact',51); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTACT_DELETE','Contact address deleted','Executed when a contact is deleted','contact',52); -- actions not enabled by default : they are excluded when we enable the module Agenda (except TASK_...) insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('TASK_CREATE','Task created','Executed when a project task is created','project',150); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('TASK_MODIFY','Task modified','Executed when a project task is modified','project',151); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('TASK_DELETE','Task deleted','Executed when a project task is deleted','project',152); + diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql index 4611c47ae37..d82bf2200ac 100644 --- a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql +++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql @@ -260,3 +260,7 @@ ALTER TABLE llx_projet ADD COLUMN email_msgid varchar(255); ALTER TABLE llx_ticket ADD COLUMN email_msgid varchar(255); ALTER TABLE llx_actioncomm ADD COLUMN reply_to varchar(255); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTACT_CREATE','Contact address created','Executed when a contact is created','contact',50); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTACT_SENTBYMAIL','Mails sent from third party card','Executed when you send email from contact adress card','contact',51); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTACT_DELETE','Contact address deleted','Executed when a contact is deleted','contact',52); + diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index 976b3f7acf2..d048a758996 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -86,6 +86,8 @@ ProposalDeleted=Proposal deleted OrderDeleted=Order deleted InvoiceDeleted=Invoice deleted DraftInvoiceDeleted=Draft invoice deleted +CONTACT_CREATEInDolibarr=Contact %s created +CONTACT_DELETEInDolibarr=Contact %s deleted PRODUCT_CREATEInDolibarr=Product %s created PRODUCT_MODIFYInDolibarr=Product %s modified PRODUCT_DELETEInDolibarr=Product %s deleted diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 62f028b45e4..13a4581fc38 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -242,6 +242,7 @@ ErrorTooManyDifferentValueForSelectedGroupBy=Found too many different value (mor ErrorReplaceStringEmpty=Error, the string to replace into is empty ErrorProductNeedBatchNumber=Error, product '%s' need a lot/serial number ErrorProductDoesNotNeedBatchNumber=Error, product '%s' does not accept a lot/serial number +ErrorFailedToReadObject=Error, failed to read object of type %s # Warnings WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup. WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user.