Let the platform do the work

Email Addresses

Overview

Recommended approaches when working with email addresses in Sugar.

Client Side

Recommended approaches when accessing email addresses in Sugar from a client.

Sidecar

Sidecar is the JavaScript UI framework that users interact within their browsers.

Fetching Email Addresses in Sidecar

In Sidecar, the email field will return an array of email addresses and their properties for the record. Given the model, you can fetch it using:

  var emailAddresses = model.get('email');

Note: In the past, developers could use model.get("email1") to fetch the primary email address. While this currently does work, these legacy email fields are deprecated and may be subject to removal in an upcoming Sugar release.

Fetching a Primary Email Address in Sidecar

To fetch the primary email address for a bean, you can use app.utils.getPrimaryEmailAddress():

  var primaryEmailAddress = app.utils.getPrimaryEmailAddress(model);
Fetching an Email Address by Properties in Sidecar

To fetch an email address based on properties such as invalid_email, you can use app.utils.getEmailAddress(). This function will return the first email address that matches the options or an empty string if not found. An example is shown below:

  var emailAddress = app.utils.getEmailAddress(model, {invalid_email: true});

If you have complex filtering rules, you can use _.find() to fetch an email address:

  var emailAddress = _.find(model.get('email'), function(emailAddress){ 
    if (emailAddress.invalid_email == true) {
        return emailAddress;
    }
});
Validating Email Addresses in Sidecar

To validate an email address, you can use app.utils.isValidEmailAddress():

  var isValid = app.utils.isValidEmailAddress(emailAddress);

Note: This function is more permissive and does not conform exactly to the RFC standards used on the server. As such, the email address will be validated again on the server when the record is saved, which could still fail validation. More information can be found in the email address validation section.

Iterating Email Address in Sidecar

To iterate through email addresses on a model, you can use _.each():

  _.each(model.get('email'), function(emailAddress) {
    console.log(emailAddress.email_address);
});

Updating Email Addresses in Sidecar

This section covers how to manipulate the email addresses for a model.

Adding Email Addresses in Sidecar

In Sidecar, you can add email addresses to a model using the custom function below:

  function addAddress(model, email) {
    var existingAddresses = model.get('email') ? app.utils.deepCopy(model.get('email')) : [],
        dupeAddress = _.find(existingAddresses, function(address){
            return (address.email_address === email);
        }),
        success = false;

    if (_.isUndefined(dupeAddress)) {
        existingAddresses.push({
            email_address: email,
            primary_address: (existingAddresses.length === 0),
            opt_out: app.config.newEmailAddressesOptedOut || false
        });
        model.set('email', existingAddresses);
        success = true;
    }

    return success;
}
Removing Email Addresses in Sidecar

In Sidecar, you can remove email addresses from a model using the custom function below:

  function removeAddress(model, email) {
    var existingAddresses = app.utils.deepCopy(model.get('email'));
    var index = false;
    _.find(existingAddresses, function(emailAddress, idx){ 
        if (emailAddress.email_address === email) {
            index = idx;
            return true;
        }
    });
    var primaryAddressRemoved = false;

    if (index !== false) {
        primaryAddressRemoved = !!existingAddresses[index]['primary_address'];
    }

    //Reject this index from existing addresses
    existingAddresses = _.reject(existingAddresses, function (emailInfo, i) { return i == index; });

    // If a removed address was the primary email, we still need at least one address to be set as the primary email
    if (primaryAddressRemoved) {
        //Let's pick the first one
        var address = _.first(existingAddresses);
        if (address) {
            address.primary_address = true;
        }
    }

    model.set('email', existingAddresses);
    return primaryAddressRemoved;
}

Server Side

Recommended approaches when accessing email addresses in Sugar from the server.

SugarBean

The SugarBean is Sugars PHP core object model.

Fetching Email Addresses Using the SugarBean

Using the SugarBean, the $bean->emailAddress->addresses property will return an array of email addresses and its properties. The $bean->emailAddress property makes use of the EmailAddress class which is located in ./modules/EmailAddresses/EmailAddress.php. An example is shown below:

  $emailAddresses = $bean->emailAddress->addresses;
Fetching a Primary Email Address Using the SugarBean

To fetch the primary email address for a bean, you can use $bean->emailAddress->getPrimaryAddress():

  $primaryEmailAddress = $bean->emailAddress->getPrimaryAddress($bean);

Another alternative is to use the email_addresses_primary relationship:

  $primaryEmailAddress = false;
if ($this->load_relationship('email_addresses_primary')) {
    $relatedBeans = $this->email_addresses_primary->getBeans();
    if (!empty($relatedBeans)) {
        $primaryEmailAddress = current($relatedBeans);
    }
}

You may also choose to iterate the email address list with a foreach(). An example function is shown below:

  function getPrimaryEmailAddress($bean)
{
    foreach ($bean->emailAddress->addresses as $emailAddress) {
        if ($emailAddress['primary_address'] == true) {
            return $emailAddress;
        }
    }

    return false;
}
Fetching an Email Address by Properties Using the SugarBean

To fetch an email address based on properties such as invalid_email, you can use a foreach():

  $result = false;
foreach ($bean->emailAddress->addresses as $emailAddress) {
    if ($emailAddress['invalid_email']) {
        $result = $emailAddress;
        break;
    }
}
Validating Email Addresses Using the SugarBean

To validate an email address, you can use $bean->emailAddress->isValidEmail():

  $isValid = $bean->emailAddress->isValidEmail($emailAddress);

Note: The EmailAddress::isValidEmail method leverages the PHPMailer library bundled with Sugar, specifically the PHPMailer::validateAddress method, which validates the address according to the RFC 5321 and RFC 5322 standards. More information can be found in the email address validation section.

Iterating Email Addresses Using the SugarBean

To iterate through email addresses on a bean, you can use foreach():

  foreach ($bean->emailAddress->addresses as $emailAddress) {
    $GLOBALS['log']->info($emailAddress['email_address']);
}
Fetching Beans by Email Address Using the SugarBean

To fetch all beans related to an email address you can use getBeansByEmailAddress():

  $beans = $bean->emailAddress->getBeansByEmailAddress($emailAddress);

If you don't have a bean available, you may choose to create a new EmailAddress object:

  $sea = BeanFactory::newBean('EmailAddresses');
$sea->getBeansByEmailAddress($emailAddress);

Updating Email Addresses Using the SugarBean

This section covers how to manipulate the email addresses for a bean.

Adding Email Addresses Using the SugarBean

To add an email address to the bean, you can use $bean->emailAddress->addAddress():

  $bean->emailAddress->addAddress('address@sugar.crm');

Note: The addAddress() function has additional parameters that are defaulted for determining if the email address is a primary, reply to, invalid, or opted out email address. You can also specify an id for the email address and whether or not the email address should be validated.

  function addAddress($addr, $primary=false, $replyTo=false, $invalid=false, $optOut=false, $email_id = null, $validate = true)
Removing Email Addresses Using the SugarBean

To remove an email address you can use $bean->emailAddress->removeAddress():

  $bean->emailAddress->removeAddress('address@sugar.crm');

PDF Templates

Using the Sugar PDF templates, you can reference the primary email address of the bean using:

  {$fields.email_addresses_primary.email_address}

REST API

Sugar comes out of the box with an API that can be called from custom applications utilizing the REST interface. The API can be used to mass create and update records in Sugar with external data. For more information on the REST API in Sugar, please refer to the Web Services documentation.

Creating Email Addresses Using the REST API

When creating records in Sugar through the API, modules with relationships to email addresses can utilize the email link field to specify email addresses for a record. Using the email link field, you can specify multiple email addresses to assign to the record. You may specify the following additional information regarding each email address being added:

Property Description
invalid_email Specify this email address as being invalid
opt_out Specify this email address as being opted out. More information on opt-outs can be found in the Emails documentation.
primary_address Specify this email address as the primary

Using the /<module> POST endpoint, you can send the following JSON payload to create a contact record with multiple email addresses using the email link field:
POST URL: http://<site url>/rest/v<version>/Contacts

  {
   "first_name":"Rob",
   "last_name":"Robertson",
   "email":[
      {
         "email_address":"rob.robertson@sugar.crm",
         "primary_address":"1",
         "invalid_email":"0",
         "opt_out":"0"
      },
      {
         "email_address":"rob@sugar.crm",
         "primary_address":"0",
         "invalid_email":"0",
         "opt_out":"1"
      }
   ]
}

For more information on the /<module>/:record POST endpoint, you can refer to your instance's help documentation found at:

http://<site url>/rest/v<version>/help

Or you can reference the <module> POST PHP example.

Updating Email Addresses Using the REST API

When updating existing records in Sugar through the API, modules with relationships to email addresses can use the email link field to specify email addresses for a record. Using the email link field, you can specify multiple email addresses to update the record with. You may specify the following additional information regarding each email address being added:

  • invalid_email : Specify this email address as being invalid
  • opt_out : Specify this email address as being opted out
  • primary_address : Specify this email address as the primary

Using the /<module>/:record PUT endpoint, you can send the following JSON payload to update a contact record with multiple email addresses:
PUT URL: http://<site url>/rest/v<version>/Contacts/<record id>

  {
   "email":[
      {
         "email_address":"rob.robertson@sugar.crm",
         "primary_address":"1",
         "invalid_email":"0",
         "opt_out":"0"
      },
      {
         "email_address":"rob@sugar.crm",
         "primary_address":"0",
         "invalid_email":"0",
         "opt_out":"1"
      }
   ]
}

For more information on the /<module>/:record PUT endpoint, you can refer to your instance's help documentation found at:

http://<site url>/rest/v<version>/help

You want to reference the <module>/:record PUT PHP example.

Legacy Email Fields

The legacy email fields in Sugar are deprecated and may be subject to removal in an upcoming Sugar release. When using the email1 field, the default functionality is to import the email address specified as the primary address.

Legacy Email Field Description
email1 The text value of primary email address. Does not indicate if the email address is valid or opted-out.
email2 The text value of first non-primary email address. Does not indicate if the email address is valid or opted-out.

Note: For importing multiple email addresses with properties, you will need to use the email link field.

Creating Email Addresses Using Direct SQL

When importing records into Sugar directly via the database, it is important that you understand the data structure involved before loading data. Email addresses are not stored directly on the table for the module being imported in but are related via the email_addr_bean_rel table.

The table structure for email addresses can be seen from the database via the following SQL statement:

  SELECT
 email_addr_bean_rel.bean_id,
 email_addr_bean_rel.bean_module,
 email_addresses.email_address
FROM email_addr_bean_rel
INNER JOIN email_addresses
 ON email_addresses.id = email_addr_bean_rel.email_address_id
 AND email_addr_bean_rel.deleted = 0
WHERE email_addresses.deleted = 0;

Checking for Duplicates

Email addresses can become duplicated in Sugar from a variety of sources including API calls, imports, and from data entry. There are a few ways to have the system check for duplicate contact records, but not many of those methods work for checking email addresses for duplicates. The following section will demonstrate how to find and clean up duplicate email addresses using SQL.

The following SQL query can be used to locate if any email addresses are being used against more than one bean record within Sugar:

  SELECT
 email_addresses.email_address,
 COUNT(*) AS email_address_count
FROM email_addr_bean_rel
INNER JOIN email_addresses
 ON email_addresses.id = email_addr_bean_rel.email_address_id
 AND email_addr_bean_rel.deleted = 0
WHERE email_addresses.deleted = 0
GROUP BY email_addresses.email_address
HAVING COUNT(*) > 1;

Note: If you convert a Lead record to a Contact record, both the Lead and the Contact will be related to the same Email Address and will return as having duplicates in this query. You can add the following line to the WHERE clause to filter the duplicate check down to only one bean type:

  AND email_addr_bean_rel.bean_module = 'Contacts'

Email addresses can not only be duplicated in the system but can occasionally be missing critical data. Each bean record with an email address assigned to it should have an email address designated the primary. The following query will locate any bean records that have at least one email address, where there is not an email address designated as the primary:

  SELECT
 email_addr_bean_rel.bean_module,
 email_addr_bean_rel.bean_id,
 COUNT(*) AS email_count,
 COUNT(primary_email_addr_bean_rel.id) AS primary_email_count
FROM email_addr_bean_rel
LEFT JOIN email_addr_bean_rel primary_email_addr_bean_rel
 ON primary_email_addr_bean_rel.bean_module = email_addr_bean_rel.bean_module
 AND primary_email_addr_bean_rel.bean_id = email_addr_bean_rel.bean_id
 AND primary_email_addr_bean_rel.primary_address = '1'
 AND primary_email_addr_bean_rel.deleted = '0'
WHERE email_addr_bean_rel.deleted = '0'
GROUP BY email_addr_bean_rel.bean_module,
 email_addr_bean_rel.bean_id
HAVING primary_email_count < 1;

Note: If you are a SugarCloud customer, you can open up a case with Sugar Support to have this query run for you.

Removing Duplicates

If it is determined you have duplicate email addresses being used in your system, you can use the following query to clean up the records:

  START TRANSACTION;
CREATE 
 TABLE email_addr_bean_rel_tmp
SELECT
 *
FROM email_addr_bean_rel
WHERE deleted = '0'
GROUP BY email_address_id,
 bean_module,
 bean_id
ORDER BY primary_address DESC;
TRUNCATE TABLE email_addr_bean_rel;
INSERT INTO email_addr_bean_rel
 SELECT
 *
 FROM email_addr_bean_rel_tmp;
SELECT
 COUNT(*) AS repetitions,
 date_modified,
 bean_id,
 bean_module
FROM email_addr_bean_rel
WHERE deleted = '0'
GROUP BY bean_id,
 bean_module,
 email_address_id
HAVING repetitions > 1;
COMMIT;

Note: If you are a SugarCloud customer, you can open up a case with Sugar Support to have this query run for you.