We all started somewhere! Share your experience on the Get Advice: Let's Get Started Sweepstakes thread and be entered to win a $100 credit on your Constant Contact account.

Need help modifying this PHP Class for adding a contact

SOLVED
Go to solution
JustinV84085
Frequent Participant

Need help modifying this PHP Class for adding a contact

I found this bit of code online, and it works fine for addinga contact to my list. However, there are a couple of things I need this to do:

1) If the contact exists in the Do Not Mail or Removed categories, I need to be able to add them back.

2) How can I modify this to alo insert additional fields? (name, zip, custom1, etc)

Any help is appreciated.

------------------------------------------
The code on my insert page:
------------------------------------------

$myKey    = '######';
$myUn     = '######';
$myPW     = '######';
$addToCC  = $_POST['addToCC'];

if($addToCC  == 1) {
#add user to mailing list
$cc = new ConstantContact( $myKey, $myUN, $myPW );
$result = $cc->addContactToMailingList($email, "https://api.constantcontact.com/ws/customers/######/lists/10");
}


----------------------------------

The PHP class:

----------------------------------

 

class ConstantContact{

private $api_key;
private $user_name;
private $user_pass;
private $auth_pass;

public function __construct($apikey, $username, $userpassword){

$this->api_key = $api_key;
$this->user_name = $username;
$this->user_password = $userpassword;
$this->auth_pass = $apikey . "%" . $username . ":" . $userpassword;

}

public function __destruct(){

}

public function addContactToMailingList($emailAddressOfUser, $contactList){

$contactURL = "https://api.constantcontact.com/ws/customers/{$this->user_name}/contacts";

$contactListToAddTo = $contactList;

$update_date = date("Y-m-d").'T'.date("H:i:s").'+01:00';

$rawEntry = "<entry xmlns='http://www.w3.org/2005/Atom'></entry>";
$xml_object = simplexml_load_string($rawEntry);
$title_node = $xml_object->addChild("title", htmlspecialchars("TitleNode"));
$updated_node = $xml_object->addChild("updated", htmlspecialchars($update_date));
$author_node = $xml_object->addChild("author");
$author_name = $author_node->addChild("name", htmlspecialchars($this->user_name));
$id_node = $xml_object->addChild("id", "data:,none");
$summary_node = $xml_object->addChild("summary", htmlspecialchars("Customer document"));
$summary_node->addAttribute("type", "text");
$content_node = $xml_object->addChild("content");
$content_node->addAttribute("type", "application/vnd.ctct+xml");
$contact_node = $content_node->addChild("Contact", htmlspecialchars("Customer document"));
$contact_node->addAttribute("xmlns", "http://ws.constantcontact.com/ns/1.0/");
$email_node = $contact_node->addChild("EmailAddress", urldecode(htmlspecialchars($emailAddressOfUser)));
$optin_node = $contact_node->addChild("OptInSource", htmlspecialchars('ACTION_BY_CUSTOMER'));
$contactlists_node = $contact_node->addChild("ContactLists");
$contactlist_node = $contactlists_node->addChild("ContactList");
$contactlist_node->addAttribute("id", urldecode(htmlspecialchars($contactListToAddTo)));

$entry = $xml_object->asXML();

$curl_conn = curl_init($contactURL);
// Set up Basic authentication - username and password.
curl_setopt($curl_conn, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl_conn, CURLOPT_USERPWD, $this->auth_pass);
curl_setopt($curl_conn, CURLOPT_FOLLOWLOCATION ,1);
curl_setopt($curl_conn, CURLOPT_POST, 1);
curl_setopt($curl_conn, CURLOPT_POSTFIELDS , $entry);
curl_setopt($curl_conn, CURLOPT_HTTPHEADER, Array("Content-Type:application/atom+xml"));
curl_setopt($curl_conn, CURLOPT_HEADER, 0); // Do not return headers
curl_setopt($curl_conn, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl_conn, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($curl_conn);
curl_close($curl_conn);
echo $response;

//return true;

}

}

1 ACCEPTED SOLUTION
JustinV84085
Frequent Participant

Ok, here is the final code with the latest change in bold. Please let me know if it's ok to do it this way:

 

------------------------------------------

if (!$search)
     {
         $contactObj = new Contact();
         $contactObj->lists = array('https://api.constantcontact.com/ws/customers/#####/lists/10');
         $contactObj->emailAddress = $email;
         $contactObj->firstName = $firstname;
         $contactObj->lastName = $lastname;
 
         // Create the contact
         $Contact = $ConstantContact->addContact($contactObj);
         }
 
    else

     {

         // Get details for the Contact
         $Contact = $ConstantContact->getContactDetails($search[0]);

        if($Contact->status == "Do Not Mail"){

                exit;
        }
 
         // modify Contact properties
     $Contact->lists = array('https://api.constantcontact.com/ws/customers/#####/lists/10');
         $Contact->firstName = $firstname;
         $Contact->lastName = $lastname;
 
         //update the contact
         $Contact = $ConstantContact->updateContact($Contact);
         }

View solution in original post

21 REPLIES 21
bsoder
Employee

Hello,

I would definitely like to help you with your PHP integration.  We actually have a new library that takes care a lot of the code for you.  You can download the library here, and there is also a wiki for it that explains how to use it here.
Here is an example of how to add or update a contact with the library:

<?php  
    include_once('ConstantContact.php');
    $ConstantContact = new ConstantContact('basic', "APIKEY", "USERNAME", "PASSWORD");

    // Search for a contact by Email Address
    $search = $ConstantContact->searchContactsByEmail('example@example.com');


   

    if (!$search) {
        // Get details for the Contact
        $Contact = $ConstantContact->getContactDetails($search[0]);

        $lists = $ConstantContact->getLists();

        $contactObj = new Contact();
        $contactObj->lists = array($lists['lists'][0]->id, $lists['lists'][1]->id);
        $contactObj->emailAddress = 'example@example.com';
        $contactObj->firstName = 'John';
        $contactObj->lastName = 'Doe';

        // Create the contact
        $Contact = $ConstantContact->addContact($contactObj);
    }

    else {

        // modify Contact properties
        $Contact->firstName = "John";
        $Contact->lastName = "Doe";

        //update the contact
        $Contact = $ConstantContact->updateContact($Contact);

    }
?>

If you have any questions about this, or run into any other difficulties, please let me know and we can work from there!

Regards,
Benjamin Soder
NOC Analyst
Constant Contact
JustinV84085
Frequent Participant

I'm getting the following error:

 

Catchable fatal error: Argument 1 passed to ConstantContact::updateContact() must be an instance of Contact, instance of stdClass given, called in /home/mysite/public_html/constantcontact/apitest.php on line 39 and defined in /home/mysite/public_html/constantcontact/ConstantContact.php on line 204

The problem appears to be in your Else block.  While you do create a Contact object in the If block, the Else block creates a generic object called $Contact instead of creating a new Contact() object first and assigning it to $Contact.  For this reason, the correct error is being thrown.  You will need to create a new Contact() object for your Else loop to correctly handle the case that the Contact is found by your search. 

 

In looking at your code closely, it appears that you have all the right code written, just your organization of it is not quite right.  I believe the correct code for what you're looking to do is:

 

 

<?php  
     include_once('ConstantContact.php');
     $ConstantContact = new ConstantContact('basic', "APIKEY", "USERNAME", "PASSWORD");

    // Search for a contact by Email Address
     $search = $ConstantContact->searchContactsByEmail('example@example.com');
 

   

    if (!$search) {
 
        $lists = $ConstantContact->getLists();
 
         $contactObj = new Contact();
         $contactObj->lists = array($lists['lists'][0]->id, $lists['lists'][1]->id);
         $contactObj->emailAddress = 'example@example.com';
         $contactObj->firstName = 'John';
         $contactObj->lastName = 'Doe';
 
        // Create the contact
         $Contact = $ConstantContact->addContact($contactObj);
     }
 
    else {
         // Get details for the Contact
         $Contact = $ConstantContact->getContactDetails($search[0]);
 
        // modify Contact properties
         $Contact->firstName = "John";
         $Contact->lastName = "Doe";
 
        //update the contact
         $Contact = $ConstantContact->updateContact($Contact);
 
    }
 ?>
Dave Berard
Senior Product Manager, Constant Contact

After using your solution, I was able to add the contact successfully, however, if I t mark the contact as removed and then try to re-add the same contact I get the following error:

 

Fatal error: Wrong parameters for Exception([string $exception [, long $code ]]) in /home/mnysite/public_html/constantcontact/Components.php on line 1434

 

Also, how is it determining which list to add the contact? It actually added it to the correct list, but I don't see how this is possible considering I have not defined the listid anywhere. I'm confused.

This code sample makes some assumptions on which lists to add a newly created contact to.  The line that chooses them is:

 

$contactObj->lists = array($lists['lists'][0]->id, $lists['lists'][1]->id);

 

If you want to pick specific lists, you'll need to find the correct lis in the returned $lists array and either hard code the ID (which never changes for a list) or put logic in to make sure the right list(s) are always selected.  Right now, it's just selecting hte first two lists that it finds in the $lists array, which could change depending on how you change the lists in your account by adding and deleting lists.

 

I'm going to make sure Ben gets involved again, I'm not as familiar with the PHP component as he is and am not sure why you are receiving an error when updating. 

Dave Berard
Senior Product Manager, Constant Contact

Regarding the error you are seeing:

Fatal error: Wrong parameters for Exception([string $exception [, long $code ]]) in /home/mnysite/public_html/constantcontact/Components.php on line 1434

 

This is because PHP 5.3 added an optional 3rd parameter to the Exception class, and since we're supplying one, this error is thrown in all versions of PHP prior to 5.3. I have since update the GitHub repository to remove this 3rd argument, so this should now function properly in all versions of PHP 5.1.3+.

 

You can either redownload the library from https://github.com/ctctsupport/ctct_php_library. Or you can change Components.php line 1434 from:

parent::__construct($message, $code, $previous);

 

To:

 

parent::__construct($message, $code);

 

I hope this helps. Please let us know if you have any other questions or concerns. Thanks!

David J

JustinV84085
Frequent Participant

Ok, I can add a contact, but if i mark it as removed and then try to re-add it, I get this:

 

Constant Contact Contact Error: 'lists' was required but not supplied
Constant Contact Contact Error: 'lists' was required but not supplied

Well, I fixed the error by changing the Else statemnt to the following, but the contact is not being added back to the list.

 

 else {

    $lists = $ConstantContact->getLists();
         // Get details for the Contact
         $Contact = $ConstantContact->getContactDetails($search[0]);
 
        // modify Contact properties
     $Contact->lists = array($lists['lists'][0]->id, $lists['lists'][1]->id);
         $Contact->firstName = $firstname;
         $Contact->lastName = $lastname;
 
        //update the contact
         $Contact = $ConstantContact->updateContact($Contact);
 
    }

 

 

Ok, this is interesting. If I add a test email using the code, it gets added. If I then "remove" the address within CC and re-add it, it shows in the list but the status says REMOVED.

The code that you are using worked perfectly fine for me to move a contact from 'Removed' over to an 'Active' contact on a list.  It sounds like the contact is updating correctly, but you are looking at the contact object from when you initially pulled details. It is showing the two lists because you added:

 

$Contact->lists = array($lists['lists'][0]->id, $lists['lists'][1]->id);

 

So when you dump out $Contact, its showing you the lists you added with the status it had at the time, which was removed. Once you have updating the contact, try running:

 

// Search for a contact by Email Address
$search = $ConstantContact->searchContactsByEmail('example@example.com');

// Get details for the Contact
$UpdatedContact = $ConstantContact->getContactDetails($search[0]);

// dump out the results
print_r($UpdatedContact);

 

I hope this helps. Please let us know if this works for you.

David J

JustinV84085
Frequent Participant

Apparently the code only works if you have multiple lists because I deleted all lists except for my default list and now when I attempt to add a contact I get this:

 

 

Constant Contact HTTP Request Exception: Error 400: Contact List id: '' is not valid
Warning: simplexml_load_string() [function.simplexml-load-string]: Entity: line 1: parser error : Start tag expected, '<' not found in /home/mysite/public_html/constantcontact/Collections.php on line 203

Warning: simplexml_load_string() [function.simplexml-load-string]: Error 400: Contact List id: '' is not valid in /home/mysite/public_html/constantcontact/Collections.php on line 203

Warning: simplexml_load_string() [function.simplexml-load-string]: ^ in /home/mysite/public_html/constantcontact/Collections.php on line 203

Fatal error: Call to a member function Attributes() on a non-object in /home/mysite/public_html/constantcontact/Components.php on line 208

If someone would be so kind as to tell me how to hardcode a sigle list ID that would be great and would probably solve the previous errors.

 

Instead of:

 $contactObj->lists = array($lists['lists'][0]->id, $lists['lists'][1]->id);

 

Something like:

 

 $contactObj-> listID = '10'; 

Ok, I think I've got it working. Here's the final code. If you see any issues, please let me know:

 

-----------------

$email = '#####';
$firstname = '#####';
$lastname = '#####';

    $ConstantContact = new ConstantContact('basic', "#####", "#####", "#####");

    // Search for a contact by Email Address
    $search = $ConstantContact->searchContactsByEmail($email);


if (!$search) {
 
        $lists = $ConstantContact->getLists();
 
         $contactObj = new Contact();
         $contactObj->lists = array('https://api.constantcontact.com/ws/customers/#####/lists/10');
         $contactObj->emailAddress = $email;
         $contactObj->firstName = $firstname;
         $contactObj->lastName = $lastname;
 
        // Create the contact
         $Contact = $ConstantContact->addContact($contactObj);
     }
 
    else {
 $lists = $ConstantContact->getLists();
         // Get details for the Contact
         $Contact = $ConstantContact->getContactDetails($search[0]);
 
        // modify Contact properties
    $Contact->lists = array('https://api.constantcontact.com/ws/customers/#####/lists/10');
         $Contact->firstName = $firstname;
         $Contact->lastName = $lastname;
 
        //update the contact
         $Contact = $ConstantContact->updateContact($Contact);

// Search for a contact by Email Address
$search = $ConstantContact->searchContactsByEmail($email);

// Get details for the Contact
$UpdatedContact = $ConstantContact->getContactDetails($search[0]);

// dump out the results
#print_r($UpdatedContact);
 
    }

-------------------------

I'm glad you were able to resolve this. I did want to quickly point out that if you are going to be supplying the list id's manually (hard-coding them), then you can remove the $ConstantContact->getLists() calls as you are no longer using those values.

 

Please let us know if you have any other questions regarding our API.

David J

JustinV84085
Frequent Participant

Thanks for the great support! Just one more question...

 

Currently if I attempt to add an address that is on the Do Not Mail list, it returns the following:

 

Constant Contact HTTP Request Exception: Error 403: Contact ###@###.com has opted-out and may not be resubscribed

 

From my understanding I cannot automatically opt a subscriber back in, so how can I either

 

A) Insert them into the Awaiting Confirmation group and fire off the opt-in confirmation email (the preferred solution, if this is permitted)

 

or

 

B) Ignore the insert completely and suppress any error or message

 

 

Hello,

 

Contacts who have opted out of receiving all mails and have been placed on Do-Not-Mail list must opt themselves in.  The account owner cannot add a contact in Do-Not-Mail list back to a different list.  The action must be initiated by the contact.  When using the API, that means that the <OptInSource> must be ACTION_BY_CONTACT, which can only be used when the API call is the direct result of an action performed by the contact (e.g. clicking a Subscribe button in an application). It is a serious violation of the Constant Contact Terms of Service to use the Opt-in features of the API in any other way (i.e. opting in a contact without his or her action and consent).

 

In order to opt-in a contact, you must take the contact's detail data and modify <ContactLists> to include the contact contact lists in which the contact is signing up.  Then, you use the PUT method to apply the change against the contact resource.

 

Joseph D
Support Engineer, Constant Contact
JustinV84085
Frequent Participant

As for the statement that it opting back in "must be initiated by the contact", I don't think that is entirely true. Your own FAQ has this:

 

"To assist a contact who is having difficulty finding your signup box, you may begin the process by going to the box yourself and entering their email address. They will, however, need to follow the steps listed to confirm the subscription.:

 

My question was simply if there is a way I can do that automatically so that all they need to do is confirm that they wish to opt back in.

 

 

What Joseph is saying is exactly correct, and you want to make sure that you customers are the ones taking this action to opt themselves back in, or else that would be in violation of our terms and conditions. For the library that you are using, You would just need to set the opt in source if that contact was on the Do-Not-Mail list. For example, you could add something like:

 

if($Contact->status == "Do Not Mail"){
    $Contact->optInSource = "ACTION_BY_CONTACT";
}

 

 

I hope this helps to clear up any points of confusion. Please let us know if you have any other questions.

David J

JustinV84085
Frequent Participant

Ok, here is the final code with the latest change in bold. Please let me know if it's ok to do it this way:

 

------------------------------------------

if (!$search)
     {
         $contactObj = new Contact();
         $contactObj->lists = array('https://api.constantcontact.com/ws/customers/#####/lists/10');
         $contactObj->emailAddress = $email;
         $contactObj->firstName = $firstname;
         $contactObj->lastName = $lastname;
 
         // Create the contact
         $Contact = $ConstantContact->addContact($contactObj);
         }
 
    else

     {

         // Get details for the Contact
         $Contact = $ConstantContact->getContactDetails($search[0]);

        if($Contact->status == "Do Not Mail"){

                exit;
        }
 
         // modify Contact properties
     $Contact->lists = array('https://api.constantcontact.com/ws/customers/#####/lists/10');
         $Contact->firstName = $firstname;
         $Contact->lastName = $lastname;
 
         //update the contact
         $Contact = $ConstantContact->updateContact($Contact);
         }

View solution in original post

That flow is fine, so long as the customer is the person taking the action and not you as the site owner.

 

I did want to quickly touch base on the FAQ you are quoting. That is referring to using the Join My Mailing LIst form (JMML) to send an update profile email to a customer. The workaround it is suggesting is to send that emai to the customer, but they would still need to take an action to opt themselves back in. The API does not go through this update profile email step, which is why we need to make sure it is the contact taking the action.

 

I hope this clears things up. Please let us know if you have any further questions. Thanks!

David J

Developer Portal

View API documentation, code samples, get your API key.

Visit Page