bagnz0r

ConstantContact.php

Nov 2nd, 2011
400
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php defined('SYSPATH') or die('No direct script access.');
  2.  
  3. class ConstantContact extends EmailService {
  4.    
  5.     /**
  6.     * Auth flow
  7.     */
  8.     public $auth_flow = 'basic';
  9.    
  10.     /**
  11.     * API
  12.     */
  13.     protected $api = 'https://api.constantcontact.com/ws/customers/';
  14.    
  15.     /**
  16.     * Constructing the object
  17.     *
  18.     * @throws Kohana_Exception
  19.     */
  20.     public function __construct()
  21.     {
  22.         // Call the parent
  23.         parent::__construct();
  24.    
  25.         // Load config
  26.         $config = Kohana::config('emailservices.constantcontact');
  27.    
  28.         // Check vars
  29.         if (!isset($config['consumer_key']))
  30.             throw new Kohana_Exception('No consumer key!');
  31.  
  32.         if (!isset($config['callback']))
  33.             throw new Kohana_Exception('No callback URL defined!');
  34.            
  35.         // Consumer key
  36.         $this->consumer_key = $config['consumer_key'];
  37.    
  38.         // Callback
  39.         $this->callback = $config['callback'];
  40.     }
  41.    
  42.     /**
  43.      * Getting lists of contacts
  44.      *
  45.      * @param serialized_string $credentials
  46.      * @return array
  47.      */
  48.     public function get_contact_lists($credentials)
  49.     {
  50.         // Make request
  51.         $response = $this->make_request('lists', $credentials);
  52.        
  53.         // Empty array
  54.         $result = array();
  55.        
  56.         // Go through entire response to build array
  57.         foreach ($response->entry as $entry)
  58.         {
  59.             $result[(string)$entry->content->ContactList->attributes()->id] = 'constant contact/' . (string)$entry->content->ContactList->Name;
  60.         }
  61.        
  62.         return $result;
  63.     }
  64.    
  65.     public function get_emails($credentials)
  66.     {
  67.         // Make request
  68.         $response = $this->make_request('settings/emailaddresses', $credentials);
  69.  
  70.         // Emtpy array
  71.         $result = array();
  72.        
  73.         // Go through entire response to build array
  74.         foreach ($response->entry as $entry)
  75.         {
  76.             $result[(string)$entry->id] = array(
  77.                 'title' => (string)$entry->title,
  78.                 'link' => (string)$entry->link->attributes()->href,
  79.                 'email' => (string)$entry->content->Email->EmailAddress,
  80.                 'status' => (string)$entry->content->Email->Status,
  81.             );
  82.         }
  83.        
  84.         return $result;
  85.     }
  86.    
  87.     /**
  88.      * Getting campaigns
  89.      *
  90.      * @param serialized_string $credentials
  91.      * @return array
  92.      */
  93.     public function get_campaigns($credentials)
  94.     {
  95.         // Make request
  96.         $response = $this->make_request('campaigns', $credentials);
  97.        
  98.         // Empty array
  99.         $result = array();
  100.        
  101.         // Go through entire response to build array
  102.         foreach ($response->entry as $entry)
  103.         {
  104.             $result[(string)$entry->id] = array(
  105.                 'link' => (string)$entry->link->attributes(),
  106.                 'title' => (string)$entry->title,
  107.                 'updated' => (string)$entry->updated,
  108.                 'author' => (string)$entry->author->name,
  109.                 'name' => (string)$entry->content->Campaign->Name,
  110.                 'status' => (string)$entry->content->Campaign->Status,
  111.                 'date' => (string)$entry->content->Campaign->Date,
  112.             );
  113.         }
  114.        
  115.         return $result;
  116.     }
  117.    
  118.     /**
  119.      * Creating an email campaign
  120.      *
  121.      * @param array $data Model_Ads()->get() array with email
  122.      * @param array $emails Array of emails retrieved by get_emails() method
  123.      * @param array $lists Array of lists retrieved by get_contact_lists() method
  124.      * @param serialized_string $credentials
  125.      */
  126.     public function create_campaign($data, $emails, $lists, $credentials)
  127.     {
  128.         // Status of campaign
  129.         $status = 'Draft';
  130.        
  131.         // First the header
  132.         $options = array(
  133.             CURLOPT_HTTPHEADER => array(
  134.                 'Content-Type' => 'application/atom+xml',
  135.             ),
  136.         );
  137.        
  138.         // Unserialize credentials for use with building data
  139.         $unserialized = unserialize($credentials);
  140.  
  141.         // Get the RFC3339 timestamp
  142.         $timestamp = date(DateTime::RFC3339);
  143.        
  144.         // Prepare contacts lists data
  145.         $list_data = array();
  146.         $list_data = $this->prepare_contact_lists_data($lists, $list_data);
  147.        
  148.         // Prepare email data
  149.         $email_data = array();
  150.         list($email, $email_data) = $this->prepare_email_data($emails, $email_data);
  151.  
  152.        
  153.         // Spawn new AtomBuilder to create data for this request
  154.         $atom_builder = new AtomBuilder(array(
  155.             // The one and only entry
  156.             array(
  157.                 // Request basics required by atom specification
  158.                 'link' => array(
  159.                     'href' => '/ws/customers/' . $unserialized['username'] . '/campaigns',
  160.                     'rel' => 'edit',
  161.                 ),
  162.                 'id' => array(
  163.                     '@field' => $this->build_ws_url('campaigns', $unserialized, false),
  164.                 ),
  165.                 'title' => array(
  166.                     'type' => 'text',
  167.                     '@field' => $data['title'],
  168.                 ),
  169.                 'updated' => array(
  170.                     '@field' => $timestamp,
  171.                 ),
  172.                 'author' => array(
  173.                     '@sub:name' => array(
  174.                         '@field' => 'AdSwaps',
  175.                     ),
  176.                 ),
  177.                
  178.                 // This is content of the campaign
  179.                 'content' => array(
  180.                     'type' => 'application/vnd.ctct+xml',
  181.                     '@sub:Campaign' => array(
  182.                         'xmlns' => 'http://ws.constantcontact.com/ns/1.0/',
  183.                         'id' => $this->build_ws_url('campaigns', $unserialized, false),
  184.                        
  185.                         // Campaign information
  186.                         '@sub:Name' => array(
  187.                             '@field' => $data['title'],
  188.                         ),
  189.                         '@sub:Status' => array(
  190.                             '@field' => $status,
  191.                         ),
  192.                         '@sub:Date' => array(
  193.                             '@field' => $timestamp,
  194.                         ),
  195.                        
  196.                         // Message meta
  197.                         '@sub:Subject' => array(
  198.                             '@field' => $data['email_subject'],
  199.                         ),
  200.                         '@sub:FromName' => array(
  201.                             '@field' => $email,
  202.                         ),
  203.                         '@sub:ViewAsWebpage' => array(
  204.                             '@field' => 'No',
  205.                         ),
  206.                         '@sub:ViewAsWebpageLinkText' => array(
  207.                             '@field' => '',
  208.                         ),
  209.                         '@sub:ViewAsWebpageText' => array(
  210.                             '@field' => '',
  211.                         ),
  212.                        
  213.                         // We do not need a permission reminder
  214.                         '@sub:PermissionReminder' => array(
  215.                             '@field' => 'NO',
  216.                         ),
  217.                         '@sub:PermissionReminderText' => array(
  218.                             '@field' => '',
  219.                         ),
  220.                        
  221.                         // Message greeting
  222.                         '@sub:GreetingSalutation' => array(
  223.                             '@field' => 'Dear',
  224.                         ),
  225.                         '@sub:GreetingName' => array(
  226.                             '@field' => 'FirstName',
  227.                         ),
  228.                         '@sub:GreetingString' => array(
  229.                             '@field' => 'Greetings!',
  230.                         ),
  231.                        
  232.                         // Do not include forward email
  233.                         '@sub:IncludeForwardEmail' => array(
  234.                             '@field' => 'NO',
  235.                         ),
  236.                         '@sub:ForwardEmailLinkText' => array(
  237.                             '@field' => '',
  238.                         ),
  239.                        
  240.                         // Do not include subscribe link
  241.                         '@sub:IncludeSubscribeLink' => array(
  242.                             '@field' => 'NO',
  243.                         ),
  244.                         '@sub:SubscribeLinkText' => array(
  245.                             '@field' => '',
  246.                         ),
  247.                        
  248.                         // The email contents
  249.                         '@sub:EmailContentFormat' => array(
  250.                             '@field' => 'HTML',
  251.                         ),
  252.                         '@sub:EmailContent' => array(
  253.                             '@field' => htmlentities($data['email_contents']),
  254.                         ),
  255.                         '@sub:EmailTextContent' => array(
  256.                             '@field' => htmlentities('<Text>' . strip_tags($data['email_contents']) . '</Text>'),
  257.                         ),
  258.                         '@sub:StyleSheet' => array(
  259.                             '@field' => '',
  260.                         ),
  261.                         '@sub:ContactLists' => $list_data,
  262.                         '@sub:FromEmail' => $email_data,
  263.                     ),
  264.                 ),
  265.                 'source' => array(
  266.                     '@sub:id' => array(
  267.                         '@field' => $this->build_ws_url('campaigns', $credentials, false),
  268.                     ),
  269.                     '@sub:title' => array(
  270.                         'type' => 'text',
  271.                         '@field' => 'Campaigns',
  272.                     ),
  273.                     '@sub:link' => array(
  274.                         'href' => 'campaigns',
  275.                         'rel' => 'self',
  276.                     ),
  277.                     '@sub:author' => array(
  278.                         '@sub:name' => array(
  279.                             '@field' => $unserialized['username'],
  280.                         ),
  281.                     ),
  282.                     '@sub:updated' => array(
  283.                         '@field' => $timestamp,
  284.                     ),
  285.                 ),
  286.             ),
  287.         ));
  288.        
  289.         // Free useful memory
  290.         unset($unserialized);
  291.        
  292.         // Make the request
  293.         try {
  294.             $result = $this->make_request('campaigns', $credentials, $atom_builder->get(false), 'post', $options);
  295.         }
  296.        
  297.         // Catch the exception
  298.         catch (Exception $e)
  299.         {
  300.             Kohana::$log->add(Kohana::ERROR, $e->getMessage());
  301.             return $e->getMessage();
  302.         }
  303.        
  304.         return $result;
  305.     }
  306.    
  307.     /**
  308.      * Checking and saving credentials
  309.      * @param array $credentials
  310.      * @return TRUE|FALSE
  311.      */
  312.     public function check_and_save_credentials($credentials)
  313.     {
  314.         // Prepare request
  315.         list($credentials, $url, $options) = $this->prepare_ws_request('contacts', $credentials);
  316.        
  317.         // Create request
  318.         try {
  319.             if ($this->request_create($url, null, 'get', $options))
  320.                 if (!TokenDB::save($this->encode_credentials($credentials), 'credentials', 'constantcontact'))
  321.                     return false;
  322.         }
  323.            
  324.         // Catch the exception
  325.         catch (Exception $e)
  326.         {
  327.             Kohana::$log->add(Kohana::ERROR, $e->getMessage());
  328.             return false;
  329.         }
  330.        
  331.         return true;
  332.     }
  333.    
  334.     /**
  335.      * Making web service request
  336.      *
  337.      * @param string $resource
  338.      * @param serialized_string $credentials
  339.      * @param array $params
  340.      * @param string $method Can be either 'get' or 'post'
  341.      * @return SimpleXMLElement
  342.      */
  343.     public function make_request($resource, $credentials, $params = null, $method = 'get', $opt = null)
  344.     {
  345.         // Prepare request
  346.         list($credentials, $url, $options) = $this->prepare_ws_request($resource, $credentials, true);
  347.        
  348.         // Join options
  349.         if (!is_null($opt))
  350.             $options = array_merge($options, $opt);
  351.        
  352.         // Make the request
  353.         try {
  354.             $result = $this->request_create($url, $params, $method, $options);
  355.         }
  356.        
  357.         // Catch the exception
  358.         catch (Exception $e)
  359.         {
  360.             Kohana::$log->add(Kohana::ERROR, $e->getMessage());
  361.             return $e->getMessage();
  362.         }
  363.        
  364.         // Decode and return result
  365.         return new SimpleXMLElement($result);
  366.     }
  367.    
  368.     /**
  369.      * Preparing web service request
  370.      * @param array $credentials
  371.      * @param bool $decode
  372.      * @return array
  373.      */
  374.     protected function prepare_ws_request($resource, $credentials, $decode = false)
  375.     {
  376.         // Decode credentials
  377.         if ($decode)
  378.             $credentials = $this->decode_credentials($credentials);
  379.        
  380.         // Build URL
  381.         $url = $this->build_ws_url($resource, $credentials);
  382.        
  383.         // Join credentials
  384.         $credentials_joined = $this->join_key($credentials);
  385.        
  386.         // Prepare basic auth
  387.         $options = $this->basic_auth($credentials_joined);
  388.        
  389.         // We don't need joined credentials anymore
  390.         unset($credentials_joined);
  391.        
  392.         // Return stuff
  393.         return array(
  394.             $credentials,
  395.             $url,
  396.             $options,
  397.         );
  398.     }
  399.    
  400.     /**
  401.      * Encoding credentials
  402.      *
  403.      * @param array $credentials
  404.      * @return serialized_string
  405.      */
  406.     protected function encode_credentials($credentials)
  407.     {
  408.         // Encode password
  409.         $credentials['password'] = base64_encode($credentials['password']);
  410.        
  411.         // Serialize
  412.         return serialize($credentials);
  413.     }
  414.    
  415.     /**
  416.      * Decoding credentials
  417.      *
  418.      * @param serialized_string $credentials
  419.      * @return array
  420.      */
  421.     protected function decode_credentials($credentials)
  422.     {
  423.         // Unserialize
  424.         $credentials = unserialize($credentials);
  425.        
  426.         // Decode password
  427.         $credentials['password'] = base64_decode($credentials['password']);
  428.        
  429.         return $credentials;
  430.     }
  431.    
  432.     /**
  433.      * Joining credentials with consumer key
  434.      *
  435.      * @param array $credentials
  436.      * @return array
  437.      */
  438.     protected function join_key($credentials)
  439.     {
  440.         $credentials['username'] = $this->consumer_key . '%' . $credentials['username'];
  441.         return $credentials;
  442.     }
  443.    
  444.     /**
  445.      * Preparing list data for campaign creation
  446.      *
  447.      * @param array $lists
  448.      * @param array $list_data
  449.      */
  450.     protected function prepare_contact_lists_data($lists, $list_data)
  451.     {
  452.         foreach ($lists as $id => $name)
  453.         {
  454.             $list_data = array_merge($list_data, array(
  455.                 '@sub:ContactList' => array(
  456.                     'id' => $id,
  457.                     '@sub:link' => array(
  458.                         'xmlns' => 'http://www.w3.org/2005/Atom',
  459.                         'href' => str_replace('http://api.constantcontact.com', '', $id),
  460.                         'rel' => 'self',
  461.                     ),
  462.                 ),
  463.             ));
  464.         }
  465.        
  466.         return $list_data;
  467.     }
  468.    
  469.     /**
  470.      * Preparing email data for campaign creation
  471.      *
  472.      * @param array $emails
  473.      * @param array $email_data
  474.      */
  475.     protected function prepare_email_data($emails, $email_data)
  476.     {
  477.         foreach ($emails as $id => $data)
  478.         {
  479.             $email_data = array_merge($email_data, array(
  480.                 '@sub:Email' => array(
  481.                     'id' => $id,
  482.                     '@sub:link' => array(
  483.                         'xmlns' => 'http://www.w3.org/2005/Atom',
  484.                         'href' => $data['link'],
  485.                         'rel' => 'self',
  486.                     ),
  487.                 ),
  488.                 '@sub:EmailAddress' => array(
  489.                     '@field' => $data['email'],
  490.                 )
  491.             ));
  492.            
  493.             $email = $data['email'];
  494.         }
  495.        
  496.         return array(
  497.             $email,
  498.             $email_data,
  499.         );
  500.     }
  501.    
  502.     /**
  503.      * Building web service URL
  504.      *
  505.      * @param string $resource
  506.      * @param array $credentials
  507.      * @return string
  508.      */
  509.     protected function build_ws_url($resource, $credentials, $https = true)
  510.     {
  511.         $api = $this->api;
  512.         $https ? : $api = str_replace('https://', 'http://', $api);
  513.        
  514.         return $api . $credentials['username'] .'/' . $resource;
  515.     }
  516. }
RAW Paste Data