CiviCRM Community Forums (archive)

*

News:

Have a question about CiviCRM?
Get it answered quickly at the new
CiviCRM Stack Exchange Q+A site

This forum was archived on 25 November 2017. Learn more.
How to get involved.
What to do if you think you've found a bug.



  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • Problem with email update through API
Pages: [1]

Author Topic: Problem with email update through API  (Read 2042 times)

rogerco

  • I post occasionally
  • **
  • Posts: 66
  • Karma: 5
Problem with email update through API
July 23, 2009, 01:19:48 am
I have been trying to use civicrm_contact_add( &$params ) as documented on http://wiki.civicrm.org/confluence/display/CRMDOC/Contact+APIs to update a user's email address but I can't seem to get it to work.

I discover on searching that there seems to have been a major change in the API and civicrm_contact_add is now deprecated and there might be a new one called civicrm_contact_update( &$params, $create_new = false ) but there doesn't seem to be any documentation for it. There is a refernce to this:

http://fisheye.civicrm.org/browse/CiviCRM/branches/v2.2/api/v2/Contact.php?r1=21021&r2=20395&u=3&ignore=&k=


As I understood civicrm_contact_add this should work to update the contact's email address:
Code: [Select]
//update contact record
$params = array( 'email'  => $post['email'], 'contact_id' => $civiId, 'contact_type'  => 'Individual');
$contact = civicrm_contact_add( $params );

but nothing happens.

I notice that there is a comment around line 66 in the fisheye above that implies that updating email address is known not to work - is this correct?

What is the approved way to update a contact's email address - should I simply poke an update query directly on table civicrm_address rather than trying to use the API? Since I am only changing an existing contact's address this should be safe??????


abrookins

  • I’m new here
  • *
  • Posts: 21
  • Karma: 5
    • Redspire (Blog)
Re: Problem with email update through API
July 23, 2009, 09:41:09 am
I've been using civicrm_location_udpate() for this.

Here's an example of updating a contact's email address at the default location:

Code: [Select]
   
    civicrm_initialize( );
    require_once 'api/v2/Location.php';
    require_once 'CRM/Core/BAO/LocationType.php';

    // You should have the contact ID.
    $cid = 23;

    // Note the array structure.
    $email = array(array('email' => 'andrew@example.com'));

    $location_types  =& CRM_Core_PseudoConstant::locationType(false);
    $default_location_type =& CRM_Core_BAO_LocationType::getDefault();

    if(!$default_location_type) {
        return;
    }
 
    // Get the default location type
    $location_type = array(
                            'id' => $default_location_type->id,
                            'name' => $location_types[$default_location_type->id],
    );
 
    $params = array(
                    'contact_id' => $cid,
                    'email' => $email,
                    'location_type_id' => $location_type['id'],
        );
 
    $result = civicrm_location_update($params);

     if(civicrm_error($result)) {
        echo $result['error_message'];
     }
     else {
         print_r($result);
     }

And here's an example where we add an email address into the default location, preserving any addresses already there:

Code: [Select]
       
    // Do all the location type stuff from the first example.  Then...

    $emails = array();

    // Get any existing email addresses, so we can add them back in on update.
    // Otherwise, civicrm_location_update() will clear the existing ones.
    $params = array(
                     'contact_id' => $cid,
                     'location_type' => $location_type['name'],
    );

    $locations = civicrm_location_get($params);

    foreach($locations[1]['email'] as $existing_email) {
        $emails[] = array('email' => $existing_email['email']);
    }
 
    $emails[] = array('email' => 'andrew@example.com');

    // Update the existing contact with old and new email addresses.
    $params = array(
                    'contact_id' => $cid,
                    'email' => $emails,
                    'location_type_id' => $location_type['id'],
    );

    $result = civicrm_location_update($params);

    if(civicrm_error($result)) {
        echo $result['error_message']
    }
    else {
        print_r($result);
    }

rogerco

  • I post occasionally
  • **
  • Posts: 66
  • Karma: 5
Re: Problem with email update through API
July 24, 2009, 02:34:56 am
Of course, thanks redspire, I hadn't spotted that there is a separate api for handling locations since a contact might have multiple locations (and a location might have multiple emails)

However in practice I am going with the solution below which relies on the schema not changing but is much much simpler to implement.

What I am doing is providing a front end form where a registered website user who is also a CiviCRM contact can change her password and email address and have the changes made both to the CMS user record and the CiviCRM contact/location records.

email addresses have to be unique in the CMS user records, and I am assuming/imposing that if a member wants to change their user email address they also want that address changed wherever it appears in their CiviCRM records - so this will include any location entry that uses that email. (in my case an email address can not be used by more than one CiviCRM contact)

There isn't an API (as far as I can see) to update the civicrm-uf-match table which links together the CMS user record and the CiviCRM contact record, so I have to poke that one directly anyway. Given that I want to globally change the email address, it is easiest just to update the civicrm_email table directly.
Code: [Select]
// having checked that the CiviCRM contact exists, collected old and new email addresses, etc...
// this is a Joomla function - use Drupal equivalent if in Drupal
$db = JFactory::getDBO();
// update the contact email table - will alter all instances of the old email
$sql = "UPDATE civicrm_email SET email='".$newemail."' WHERE (email = '".$oldemail."') ";
$db->setQuery($sql);
if (!$result = $db->query()) {
echo $db->stderr(); //in reality provide some better error handling
return false;
}
// now update the uf_match record
$sql = "UPDATE civicrm_uf_match SET uf_name='".$newemail."' WHERE (uf_name = '".$oldemail."') ";
$db->setQuery($sql);
if (!$result = $db->query()) {
echo $db->stderr();  // if this failed you'd better restore the civicrm_email records !
return false;
}
// now go on and update the CMS user record

Pages: [1]
  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • Problem with email update through API

This forum was archived on 2017-11-26.