iContactApi.php 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109
  1. <?php
  2. /**
  3. * @name iContactApi
  4. * @package iContact
  5. * @author iContact <www.icontact.com>
  6. * @description This class is a wrapper for the iContact API.
  7. * It makes integrating iContact into your app as simple as
  8. * calling a method.
  9. * @version 2.0
  10. **/
  11. class iContactApi {
  12. //////////////////////////////////////////////////////////////////////////////
  13. /// Properties //////////////////////////////////////////////////////////////
  14. ////////////////////////////////////////////////////////////////////////////
  15. protected static $oInstance = null; // This holds the instance of this class
  16. protected $iAccountId = null; // This holds the account ID
  17. protected $iClientFolderId = null; // This holds the client folder ID
  18. protected $aConfig = array(); // This is our array for pragmatically overriding configuration constants
  19. protected $aErrors = array(); // This holds the errors encountered with the iContact API
  20. protected $sLastRequest = null; // This holds the last request JSON
  21. protected $sLastResponse = null; // This holds the last response JSON
  22. protected $sRequestUri = null; // This stores the last used URL
  23. protected $bSandbox = false; // This tells the system whether or not to use the iContact Sandbox or not
  24. protected $aSearchParameters = array(); // This is our container for search params
  25. protected $iTotal = 0; // If the results return a total, it will be stored here
  26. protected $aWarnings = array(); // This holds the warnings encountered with the iContact API
  27. //////////////////////////////////////////////////////////////////////////////
  28. /// Singleton ///////////////////////////////////////////////////////////////
  29. ////////////////////////////////////////////////////////////////////////////
  30. /**
  31. * This sets the singleton pattern instance
  32. * @static
  33. * @access public
  34. * @param iContactApi $oInstance Instance to set to
  35. * @return iContactApi $this
  36. **/
  37. public static function setInstance($oInstance) {
  38. self::$oInstance = $oInstance;
  39. // Return instance of class
  40. return self::$oInstance;
  41. }
  42. /**
  43. * This gets the singleton instance
  44. * @static
  45. * @access public
  46. * @return iContactApi $this
  47. **/
  48. public static function getInstance() {
  49. // Check to see if an instance has already
  50. // been created
  51. if (is_null(self::$oInstance)) {
  52. // If not, return a new instance
  53. self::$oInstance = new self();
  54. return self::$oInstance;
  55. } else {
  56. // If so, return the previously created
  57. // instance
  58. return self::$oInstance;
  59. }
  60. }
  61. /**
  62. * This resets the singleton instance to null
  63. * @static
  64. * @access public
  65. * @return void
  66. **/
  67. public static function resetInstance() {
  68. // Reset the instance
  69. self::$oInstance = null;
  70. }
  71. //////////////////////////////////////////////////////////////////////////////
  72. /// Constructor /////////////////////////////////////////////////////////////
  73. ////////////////////////////////////////////////////////////////////////////
  74. /**
  75. * This is our constuctor and simply checks for
  76. * defined constants and configuration values and
  77. * then builds the configuration from that
  78. * @access protected
  79. * @return iContactApi $this
  80. **/
  81. protected function __construct() {
  82. // Check for constants
  83. $aConstantMap = array(
  84. // 'ICONTACT_APIVERSION',
  85. // 'ICONTACT_APISANDBOXURL',
  86. 'ICONTACT_APPID' => 'appId',
  87. // 'ICONTACT_APIURL',
  88. 'ICONTACT_APIUSERNAME' => 'apiUsername',
  89. 'ICONTACT_APIPASSWORD' => 'apiPassword'
  90. );
  91. // Loop through the map
  92. foreach ($aConstantMap as $sConstant => $sConfigKey) {
  93. // Check for the defined constant
  94. if (defined($sConstant)) {
  95. // Set the configuration key to the contant's value
  96. $this->aConfig[$sConfigKey] = constant($sConstant);
  97. }
  98. }
  99. // Return instance
  100. return $this;
  101. }
  102. //////////////////////////////////////////////////////////////////////////////
  103. /// Public //////////////////////////////////////////////////////////////////
  104. ////////////////////////////////////////////////////////////////////////////
  105. /**
  106. * This method adds a contact to your iContact account
  107. * @access public
  108. * @param string $sEmail
  109. * @param string [$sStatus]
  110. * @param string [$sPrefix]
  111. * @param string [$sFirstName]
  112. * @param string [$sLastName]
  113. * @param string [$sSuffix]
  114. * @param string [$sStreet]
  115. * @param string [$sStreet2]
  116. * @param string [$sCity]
  117. * @param string [$sState]
  118. * @param string [$sPostalCode]
  119. * @param string [$sPhone]
  120. * @param string [$sFax]
  121. * @param string [$sBusiness]
  122. *
  123. * @return object
  124. **/
  125. public function addContact($sEmail, $sStatus = 'normal', $sPrefix = null, $sFirstName = null, $sLastName = null, $sSuffix = null, $sStreet = null, $sStreet2 = null, $sCity = null, $sState = null, $sPostalCode = null, $sPhone = null, $sFax = null, $sBusiness = null) {
  126. // Valid statuses
  127. $aValidStatuses = array('normal', 'bounced', 'donotcontact', 'pending', 'invitable', 'deleted');
  128. // Contact placeholder
  129. $aContact = array(
  130. 'email' => $sEmail
  131. );
  132. // Check for a prefix
  133. if (!empty($sPrefix)) {
  134. // Add the new prefix
  135. $aContact['prefix'] = (string) $sPrefix;
  136. }
  137. // Check for a first name
  138. if (!empty($sFirstName)) {
  139. // Add the new first name
  140. $aContact['firstName'] = (string) $sFirstName;
  141. }
  142. // Check for a last name
  143. if (!empty($sLastName)) {
  144. // Add the new last name
  145. $aContact['lastName'] = (string) $sLastName;
  146. }
  147. // Check for a suffix
  148. if (!empty($sSuffix)) {
  149. // Add the new suffix
  150. $aContact['suffix'] = (string) $sSuffix;
  151. }
  152. // Check for a street
  153. if (!empty($sStreet)) {
  154. // Add the new street
  155. $aContact['street'] = (string) $sStreet;
  156. }
  157. // Check for a street2
  158. if (!empty($sStreet2)) {
  159. // Add the new street 2
  160. $aContact['street2'] = (string) $sStreet2;
  161. }
  162. // Check for a city
  163. if (!empty($sCity)) {
  164. // Add the new city
  165. $aContact['city'] = (string) $sCity;
  166. }
  167. // Check for a state
  168. if (!empty($sState)) {
  169. // Add the new state
  170. $aContact['state'] = (string) $sState;
  171. }
  172. // Check for a postal code
  173. if (!empty($sPostalCode)) {
  174. // Add the new postal code
  175. $aContact['postalCode'] = (string) $sPostalCode;
  176. }
  177. // Check for a phone number
  178. if (!empty($sPhone)) {
  179. // Add the new phone number
  180. $aContact['phone'] = (string) $sPhone;
  181. }
  182. // Check for a fax number
  183. if (!empty($sFax)) {
  184. // Add the new fax number
  185. $aContact['fax'] = (string) $sFax;
  186. }
  187. // Check for a business name
  188. if (!empty($sBusiness)) {
  189. // Add the new business
  190. $aContact['business'] = (string) $sBusiness;
  191. }
  192. // Check for a valid status
  193. if (!empty($sStatus) && in_array($sStatus, $aValidStatuses)) {
  194. // Add the new status
  195. $aContact['status'] = $sStatus;
  196. } else {
  197. $aContact['status'] = 'normal';
  198. }
  199. // Make the call
  200. $aContacts = $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/contacts", 'POST', array($aContact), 'contacts');
  201. // Return the contact
  202. return $aContacts[0];
  203. }
  204. /**
  205. * This method adds a custom field or "term"
  206. * to the array of search parameters
  207. * @access public
  208. * @param string $sName
  209. * @param string $sValue
  210. * @return iContactApi $this
  211. **/
  212. public function addCustomQueryField($sName, $sValue) {
  213. // Add the field
  214. $this->aSearchParameters[$sName] = (string) $sValue;
  215. // Return instance
  216. return $this;
  217. }
  218. /**
  219. * This message adds a list to your iContact account
  220. * @access public
  221. * @param string $sName
  222. * @param integer $iWelcomeMessageId
  223. * @param bool [$bEmailOwnerOnChange]
  224. * @param bool [$bWelcomeOnManualAdd]
  225. * @param bool [$bWelcomeOnSignupAdd]
  226. * @param string [$sDescription]
  227. * @param string [$sPublicName]
  228. * @return object
  229. **/
  230. public function addList($sName, $iWelcomeMessageId, $bEmailOwnerOnChange = true, $bWelcomeOnManualAdd = false, $bWelcomeOnSignupAdd = false, $sDescription = null, $sPublicName = null) {
  231. // Setup the list
  232. $aList = array(
  233. 'name' => $sName,
  234. 'welcomeMessageId' => $iWelcomeMessageId,
  235. 'emailOwnerOnChange' => intval($bEmailOwnerOnChange),
  236. 'welcomeOnManualAdd' => intval($bWelcomeOnManualAdd),
  237. 'welcomeOnSignupAdd' => intval($bWelcomeOnSignupAdd),
  238. 'description' => $sDescription,
  239. 'publicname' => $sPublicName
  240. );
  241. // Make the call
  242. $aLists = $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/lists", 'POST', array($aList), 'lists');
  243. // Return the list
  244. return $aLists[0];
  245. }
  246. /**
  247. * This method adds a message to
  248. * your iContact API account
  249. * @access public
  250. * @param string $sSubject
  251. * @param integer $iCampaignId
  252. * @param string [$sHtmlBody]
  253. * @param string [$sTextBody]
  254. * @param string [$sMessageName]
  255. * @param integer [$iListId]
  256. * @param string [$sMessageType]
  257. * @return object
  258. **/
  259. public function addMessage($sSubject, $iCampaignId, $sHtmlBody = null, $sTextBody = null, $sMessageName = null, $iListId = null, $sMessageType = 'normal') {
  260. // Valid message types
  261. $aValidMessageTypes = array('normal', 'autoresponder', 'welcome', 'confirmation');
  262. // Setup the message data
  263. $aMessage = array(
  264. 'campaignId' => $iCampaignId,
  265. 'htmlBody' => $sHtmlBody,
  266. 'messageName' => $sMessageName,
  267. 'messageType' => (in_array($sMessageType, $aValidMessageTypes) ? $sMessageType : 'normal'),
  268. 'subject' => $sSubject,
  269. 'textBody' => $sTextBody
  270. );
  271. // Add the message
  272. $aNewMessage = $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/messages", 'POST', array($aMessage), 'messages');
  273. // Return the message data
  274. return $aNewMessage[0];
  275. }
  276. /**
  277. * This method adds a field to the order by
  278. * key in the search parameters array
  279. * @access public
  280. * @param string $sField
  281. * @param string [$sDirection]
  282. * @return iContactApi $this
  283. **/
  284. public function addOrderBy($sField, $sDirection = null) {
  285. // Check for existing order by parameters
  286. if (empty($this->aSearchParameters['orderby'])) {
  287. // Check for a direction
  288. if (empty($sDirection)) {
  289. // Add just the field
  290. $this->aSearchParameters['orderby'] = (string) $sField;
  291. } else {
  292. // Add the field and direction
  293. $this->aSearchParameters['orderby'] = (string) "{$sField}:{$sDirection}";
  294. }
  295. } else {
  296. // Check for a direction
  297. if (empty($sDirection)) {
  298. // Append just the field
  299. $this->aSearchParameters['orderby'] .= (string) ",{$sField}";
  300. } else {
  301. // Append the field and direction
  302. $this->aSearchParameters['orderby'] .= (string) ",{$sField}:{$sDirection}";
  303. }
  304. }
  305. // Return failure
  306. return false;
  307. }
  308. /**
  309. * This method handles the deleting of a single list
  310. * @access public
  311. * @param integer $iListId
  312. * @return bool
  313. **/
  314. public function deleteList($iListId) {
  315. // Delete the list
  316. return $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/lists/{$iListId}", 'delete');
  317. }
  318. /**
  319. * This method handles the handshaking between this app and the iContact API
  320. * @access public
  321. * @param string $sResource
  322. * @param string $sMethod
  323. * @param string $sReturnKey
  324. * @param mixed $mPostData Array, object, or string
  325. * @return array|object
  326. **/
  327. public function makeCall($sResource, $sMethod = 'GET', $mPostData = null, $sReturnKey = null) {
  328. // List of needed constants
  329. $aRequiredConfigs = array('apiPassword', 'apiUsername', 'appId');
  330. // First off check for definitions
  331. foreach ($aRequiredConfigs as $sKey) {
  332. // Is it defined
  333. if (empty($this->aConfig[$sKey])) {
  334. // Set an error
  335. $this->addError("{$sKey} is undefined.");
  336. }
  337. }
  338. // Set the URI that we will be calling
  339. $sApiUrl = (string) "{$this->getUrl()}{$sResource}";
  340. // Initialize the cURL handle
  341. $rHandle = curl_init();
  342. // Give our handle headers
  343. curl_setopt($rHandle, CURLOPT_HTTPHEADER, $this->getHeaders());
  344. // Tell our handle that we
  345. // want the data returned
  346. curl_setopt($rHandle, CURLOPT_RETURNTRANSFER, true);
  347. // Turn SSL verifcation off, so scripts do not get broken
  348. curl_setopt($rHandle, CURLOPT_SSL_VERIFYPEER, false);
  349. // Determine the request
  350. // method we are using
  351. switch (strtoupper($sMethod)) {
  352. // Deleting data
  353. case 'DELETE' :
  354. // Set the cURL custom header
  355. curl_setopt($rHandle, CURLOPT_CUSTOMREQUEST, 'DELETE');
  356. break;
  357. // Recieving data
  358. case 'GET' :
  359. // Check for a query string
  360. if (!empty($this->aSearchParameters)) {
  361. // Add the query string
  362. $sApiUrl .= (string) '?'.http_build_query($this->aSearchParameters);
  363. }
  364. break;
  365. // Sending data
  366. case 'POST' :
  367. // Check for POST data
  368. if (empty($mPostData)) {
  369. // Add an error, for there is no
  370. // POST data to send to the API
  371. $this->addError('No POST data was provided.');
  372. } else {
  373. // Tell our handle that
  374. // we want to send data
  375. curl_setopt($rHandle, CURLOPT_POST, true);
  376. // Give our handle the data
  377. curl_setopt($rHandle, CURLOPT_POSTFIELDS, json_encode($mPostData));
  378. // Set the request JSON
  379. $this->sLastRequest = (string) json_encode($mPostData);
  380. }
  381. break;
  382. // Uploading data
  383. case 'PUT' :
  384. if (empty($mPostData)) {
  385. // Is there data?
  386. $this->addError('No file or data specified for PUT request');
  387. } elseif (!is_string($mPostData) || !file_exists($mPostData)) {
  388. // Not a file, so we assume this is just data
  389. curl_setopt($rHandle, CURLOPT_CUSTOMREQUEST, "PUT");
  390. curl_setopt($rHandle, CURLOPT_POSTFIELDS, $mPostData);
  391. } else {
  392. $rFileContentHandle = fopen($mPostData, 'r');
  393. if ($rFileContentHandle === false) {
  394. $this->addError('A non-existant file was specified for POST data, or the file could not be opened.');
  395. } else {
  396. // Found a file, so upload its contents
  397. curl_setopt($rHandle, CURLOPT_PUT, true);
  398. curl_setopt($rHandle, CURLOPT_INFILE, $rFileContentHandle);
  399. }
  400. }
  401. break;
  402. }
  403. // Store the URL into the instance
  404. $this->sRequestUri = (string) $sApiUrl;
  405. // Give our handle a URL
  406. curl_setopt($rHandle, CURLOPT_URL, $sApiUrl);
  407. // Try to execute the handle
  408. if (!$sResponse = curl_exec($rHandle)) {
  409. // Add an error, for we could
  410. // not even execute the handle
  411. $this->addError('We were unable to execute the cURL handle.');
  412. }
  413. // Set the response JSON
  414. $this->sLastResponse = (string) $sResponse;
  415. // Try to decode the response
  416. if ((!$aResponse = json_decode($sResponse)) && (strtoupper($sMethod) != 'DELETE')) {
  417. // Add an error, for the API
  418. // did not return valid JSON
  419. $this->addError('The iContact API did not return valid JSON.');
  420. }
  421. // Close the cURL handle
  422. curl_close($rHandle);
  423. // Check for errors from the API
  424. if (!empty($aResponse->errors)) {
  425. // Loop through the errors
  426. foreach ($aResponse->errors as $sError) {
  427. // Add the error
  428. $this->addError($sError, 1);
  429. }
  430. }
  431. // Check for warnings from the API
  432. if (!empty($aResponse->warnings)) {
  433. // Loop through the warnings
  434. foreach ($aResponse->warnings as $sWarning) {
  435. // Add the warning
  436. $this->addWarning($sWarning);
  437. }
  438. }
  439. // Check for set errors
  440. if (!empty($this->aErrors)) {
  441. // Throw a new exception
  442. throw new Exception('Errors have occurred and the system cannot continue. Use getErrors() for details.');
  443. }
  444. // Check for a total
  445. if (!empty($aResponse->total)) {
  446. // Store the total records
  447. // into the current instsnce
  448. $this->iTotal = (integer) $aResponse->total;
  449. }
  450. // Return the response
  451. if (strtoupper($sMethod) == 'DELETE') {
  452. // Return success
  453. return true;
  454. } elseif (empty($sReturnKey)) {
  455. // Return the entire
  456. // base response
  457. return $aResponse;
  458. } else {
  459. // Return the narrowed resposne
  460. return $aResponse->$sReturnKey;
  461. }
  462. }
  463. /**
  464. * This method sends a message
  465. * @access public
  466. * @param string $sIncludeListId
  467. * @param integer $iMessageId
  468. * @param string [$sExcludeListIds]
  469. * @param string [$sExcludeSegmentIds]
  470. * @param string [$sIncludeSegmentIds]
  471. * @param string [$sScheduledTime]
  472. * @return object
  473. **/
  474. public function sendMessage($sIncludeListIds, $iMessageId, $sExcludeListIds = null, $sExcludeSegmentIds = null, $sIncludeSegmentIds = null, $sScheduledTime = null) {
  475. // Send the message
  476. $aSends = $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/sends", 'POST', array(
  477. array(
  478. 'excludeListIds' => $sExcludeListIds,
  479. 'excludeSegmentIds' => $sExcludeSegmentIds,
  480. 'includeListIds' => $sIncludeListIds,
  481. 'includeSegmentIds' => $sIncludeSegmentIds,
  482. 'scheduledTime' => (empty($sScheduledTime) ? null : date('c', strtotime($sScheduledTime)))
  483. )
  484. ), 'sends');
  485. // Return the send
  486. return $aSends;
  487. }
  488. /**
  489. * This method subscribes a contact to a list
  490. * @access public
  491. * @param integer $iContactId
  492. * @param integer $iListId
  493. * @param string $sStatus
  494. * @return object
  495. **/
  496. public function subscribeContactToList($iContactId, $iListId, $sStatus = 'normal') {
  497. // Valid statuses
  498. $aValidStatuses = array('normal', 'pending', 'unsubscribed');
  499. // Setup the subscription and make the call
  500. $aSubscriptions = $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/subscriptions", 'POST', array(
  501. array(
  502. 'contactId' => $iContactId,
  503. 'listId' => $iListId,
  504. 'status' => $sStatus
  505. )
  506. ), 'subscriptions');
  507. // Return the subscription
  508. return $aSubscriptions;
  509. }
  510. /**
  511. * This method updates a contact in your iContact account
  512. * @access public
  513. * @param integer $iContactId
  514. * @param string $sEmail
  515. * @param string $sPrefix
  516. * @param string $sFirstName
  517. * @param string $sLastName
  518. * @param string $sSuffix
  519. * @param string $sStreet
  520. * @param string $sStreet2
  521. * @param string $sCity
  522. * @param string $sState
  523. * @param string $sPostalCode
  524. * @param string $sPhone
  525. * @param string $sFax
  526. * @param string $sBusiness
  527. * @param string $sStatus
  528. * @return bool|object
  529. **/
  530. public function updateContact($iContactId, $sEmail = null, $sPrefix = null, $sFirstName = null, $sLastName = null, $sSuffix = null, $sStreet = null, $sStreet2 = null, $sCity = null, $sState = null, $sPostalCode = null, $sPhone = null, $sFax = null, $sBusiness = null, $sStatus = null) {
  531. // Valid statuses
  532. $aValidStatuses = array('normal', 'bounced', 'donotcontact', 'pending', 'invitable', 'deleted');
  533. // Contact placeholder
  534. $aContact = array();
  535. // Check for an email address
  536. if (!empty($sEmail)) {
  537. // Add the new email
  538. $aContact['email'] = (string) $sEmail;
  539. }
  540. // Check for a prefix
  541. if (!empty($sPrefix)) {
  542. // Add the new prefix
  543. $aContact['prefix'] = (string) $sPrefix;
  544. }
  545. // Check for a first name
  546. if (!empty($sFirstName)) {
  547. // Add the new first name
  548. $aContact['firstName'] = (string) $sFirstName;
  549. }
  550. // Check for a last name
  551. if (!empty($sLastName)) {
  552. // Add the new last name
  553. $aContact['lastName'] = (string) $sLastName;
  554. }
  555. // Check for a suffix
  556. if (!empty($sSuffix)) {
  557. // Add the new suffix
  558. $aContact['suffix'] = (string) $sSuffix;
  559. }
  560. // Check for a street
  561. if (!empty($sStreet)) {
  562. // Add the new street
  563. $aContact['street'] = (string) $sStreet;
  564. }
  565. // Check for a street2
  566. if (!empty($sStreet2)) {
  567. // Add the new street 2
  568. $aContact['street2'] = (string) $sStreet2;
  569. }
  570. // Check for a city
  571. if (!empty($sCity)) {
  572. // Add the new city
  573. $aContact['city'] = (string) $sCity;
  574. }
  575. // Check for a state
  576. if (!empty($sState)) {
  577. // Add the new state
  578. $aContact['state'] = (string) $sState;
  579. }
  580. // Check for a postal code
  581. if (!empty($sPostalCode)) {
  582. // Add the new postal code
  583. $aContact['postalCode'] = (string) $sPostalCode;
  584. }
  585. // Check for a phone number
  586. if (!empty($sPhone)) {
  587. // Add the new phone number
  588. $aContact['phone'] = (string) $sPhone;
  589. }
  590. // Check for a fax number
  591. if (!empty($sFax)) {
  592. // Add the new fax number
  593. $aContact['fax'] = (string) $sFax;
  594. }
  595. // Check for a business name
  596. if (!empty($sBusiness)) {
  597. // Add the new business
  598. $aContact['business'] = (string) $sBusiness;
  599. }
  600. // Check for a valid status
  601. if (!empty($sStatus) && in_array($sStatus, $aValidStatuses)) {
  602. // Add the new status
  603. $aContact['status'] = $sStatus;
  604. }
  605. // Make sure the contact isn't empty
  606. if (!empty($aContact)) {
  607. // Make the call
  608. $oContact = $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/contacts/{$iContactId}", 'POST', array($aContact), 'contact');
  609. // Return the contact
  610. return $oContact;
  611. }
  612. // Inevitably return failure
  613. return false;
  614. }
  615. /**
  616. * This method uploads a CSV file to the iContact API
  617. * @access public
  618. * @param string $sFile
  619. * @param integer [$iListId]
  620. * @param integer [$iUploadId]
  621. * @return string|bool
  622. **/
  623. public function uploadData($sFile, $iListId = null, $iUploadId = null) {
  624. // Check for an upload ID
  625. if (empty($iUploadId)) {
  626. // Make the call
  627. $aUploads = $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/uploads", 'POST', array(
  628. array(
  629. 'action' => 'add',
  630. 'listIds' => $iListId
  631. )
  632. ), 'uploads');
  633. // Store the uploadID
  634. $iUploadId = $aUploads[0]->uploadId;
  635. }
  636. // Upload the data
  637. if ($this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/uploads/{$iUploadId}/data", 'PUT', $sFile, 'uploadId')) {
  638. // Loop until the upload is complete
  639. while (true) {
  640. // Grab the upload
  641. $aUpload = $this->getUpload($iUploadId);
  642. // Check to see if the upload
  643. // has finished uploading
  644. if ($aUpload->status != 'receiving') {
  645. // Return the upload
  646. return $this->makeCall("/a/{$this->setAccountId()}/c{$this->setClientFolderId()}/uploads/{$iUploadId}/data", 'GET');
  647. }
  648. }
  649. }
  650. // Return failure
  651. return false;
  652. }
  653. /**
  654. * This message updates a list on your iContact account
  655. * @access public
  656. * @param string $sName
  657. * @param integer $iListId
  658. * @param string $sName
  659. * @param integer $iWelcomeMessageId
  660. * @param bool [$bEmailOwnerOnChange]
  661. * @param bool [$bWelcomeOnManualAdd]
  662. * @param bool [$bWelcomeOnSignupAdd]
  663. * @param string [$sDescription]
  664. * @param string [$sPublicName]
  665. * @return object
  666. **/
  667. public function updateList($iListId, $sName, $iWelcomeMessageId, $bEmailOwnerOnChange = true, $bWelcomeOnManualAdd = false, $bWelcomeOnSignupAdd = false, $sDescription = null, $sPublicName = null) {
  668. // Setup the list
  669. $aList = array(
  670. 'name' => $sName,
  671. 'welcomeMessageId' => $iWelcomeMessageId,
  672. 'emailOwnerOnChange' => intval($bEmailOwnerOnChange),
  673. 'welcomeOnManualAdd' => intval($bWelcomeOnManualAdd),
  674. 'welcomeOnSignupAdd' => intval($bWelcomeOnSignupAdd),
  675. 'description' => $sDescription,
  676. 'publicname' => $sPublicName
  677. );
  678. // Return the list
  679. return $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/lists/{$iListId}", 'POST', $aList, 'list');;
  680. }
  681. /**
  682. * This method tells the system whether
  683. * or not to use the sandbox or not, the
  684. * sandbox is turned off by defualt and
  685. * by default this method turns it on
  686. * @access public
  687. * @param bool [$bUse]
  688. * @return iContactApi $this
  689. **/
  690. public function useSandbox($bUse = true) {
  691. // Set the sandbox status
  692. $this->bSandbox = (bool) $bUse;
  693. // Return instance
  694. return $this;
  695. }
  696. //////////////////////////////////////////////////////////////////////////////
  697. /// PROTECTED ///////////////////////////////////////////////////////////////
  698. ////////////////////////////////////////////////////////////////////////////
  699. /**
  700. * This method appends an error to the list
  701. * of errors encountered with the iContact API
  702. * @access protected
  703. * @param string $sText
  704. * @param integer [$iCode]
  705. * @return iContactApi $this
  706. **/
  707. protected function addError($sText) {
  708. // Append the error
  709. array_push($this->aErrors, $sText);
  710. // Return instance
  711. return $this;
  712. }
  713. /**
  714. * This method appends a warning to the list
  715. * of warnings encountered with the iContact API
  716. * @access protected
  717. * @param string $sText
  718. * @return iContactApi $this
  719. **/
  720. public function addWarning($sText) {
  721. // Append the warning
  722. array_push($this->aWarnings, $sText);
  723. // Return instance
  724. return $this;
  725. }
  726. //////////////////////////////////////////////////////////////////////////////
  727. /// Getters /////////////////////////////////////////////////////////////////
  728. ////////////////////////////////////////////////////////////////////////////
  729. /**
  730. * This method grabs the campaigns associated
  731. * your iContact account
  732. * @access public
  733. * @return object
  734. **/
  735. public function getCampaigns() {
  736. // Make the call and return the data
  737. return $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/campaigns", 'GET');
  738. }
  739. /**
  740. * This method grabs a single contact
  741. * from your iContact Account
  742. * @access public
  743. * @param integer $iContactId
  744. * @return object
  745. **/
  746. public function getContact($iContactId) {
  747. // Make the call and return the data
  748. return $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/contacts/{$iContactId}", 'GET', null, 'contact');
  749. }
  750. /**
  751. * This method grabs the contacts associated
  752. * with you iContact API account
  753. * @access public
  754. * @return array
  755. **/
  756. public function getContacts() {
  757. // Make the call and return the data
  758. return $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/contacts", 'GET');
  759. }
  760. /**
  761. * This method returns any set
  762. * errors in the current instance
  763. * @access public
  764. * @return array|bool
  765. **/
  766. public function getErrors() {
  767. // Check for errors
  768. if (empty($this->aErrors)) {
  769. // Return false, for
  770. // there are no errors
  771. return false;
  772. } else {
  773. // Return the errors
  774. return $this->aErrors;
  775. }
  776. }
  777. /**
  778. * This method builds the header array
  779. * for making calls to the API
  780. * @access public
  781. * @return array
  782. **/
  783. public function getHeaders() {
  784. // Return the headers
  785. return array(
  786. 'Except:',
  787. 'Accept: application/json',
  788. 'Content-type: application/json',
  789. 'Api-Version: ' . (defined('ICONTACT_APIVERSION') ? constant('ICONTACT_APIVERSION') : '2.2'),
  790. 'Api-AppId: ' . (!empty($this->aConfig['appId']) ? $this->aConfig['appId'] : constant('ICONTACT_APPID')),
  791. 'Api-Username: '. (!empty($this->aConfig['apiUsername']) ? $this->aConfig['apiUsername'] : constant('ICONTACT_APIUSERNAME')),
  792. 'Api-Password: '. (!empty($this->aConfig['apiPassword']) ? $this->aConfig['apiPassword'] : constant('ICONTACT_APIPASSWORD'))
  793. );
  794. }
  795. /**
  796. * This method returns the last
  797. * API POST request JSON
  798. * @access public
  799. * @param bool [$bDecode]
  800. * @return string|object
  801. **/
  802. public function getLastRequest($bDecode = false) {
  803. // Check to see if we need
  804. // to decode the raw JSON
  805. if ($bDecode === true) {
  806. // Return the decoded JSON
  807. return json_decode($this->sLastRequest);
  808. }
  809. // Return the raw JSON
  810. return $this->sLastRequest;
  811. }
  812. /**
  813. * This method returns the last
  814. * API response JSON
  815. * @access public
  816. * @param bool [$bDecode]
  817. * @return string|object
  818. **/
  819. public function getLastResponse($bDecode = false) {
  820. // Check to see if we need
  821. // to decode the raw JSON
  822. if ($bDecode === true) {
  823. // Return the decoded JSON
  824. return json_decode($this->sLastResponse);
  825. }
  826. // Return the raw JSON
  827. return $this->sLastResponse;
  828. }
  829. /**
  830. * This method grabs a list of lists
  831. * that are associated with you iContact
  832. * API account
  833. * @access public
  834. * @return array
  835. **/
  836. public function getLists() {
  837. // Make the call and return the lists
  838. return $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/lists", 'GET', null, 'lists');
  839. }
  840. /**
  841. * This method lists the opens of a
  842. * single message based on the messageID
  843. * @access public
  844. * @param integer iMessageId
  845. * @return integer
  846. **/
  847. public function getMessageOpens($iMessageId) {
  848. // Make the call and return the data
  849. return $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/messages/{$iMessageId}/opens", 'GET', null, 'total');
  850. }
  851. public function getMessages($sType = null) {
  852. // Check for a message type
  853. if (!empty($sType)) {
  854. $this->addCustomQueryField('messageType', $sType);
  855. }
  856. // Return the messages
  857. return $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/messages", 'GET', null, 'messages');
  858. }
  859. /**
  860. * This method returns the URL
  861. * that the last API request
  862. * called
  863. * @access public
  864. * @return string
  865. **/
  866. public function getRequestUri() {
  867. // Return the URL
  868. return $this->sRequestUri;
  869. }
  870. /**
  871. * This method returns the count of the
  872. * total number of records from the most
  873. * recent API call, if there is one
  874. * @access public
  875. * @return integer
  876. **/
  877. public function getTotal() {
  878. // Return the total records
  879. return $this->iTotal;
  880. }
  881. /**
  882. * This method simply returns the base URL for
  883. * your API/Sandbox account
  884. * @access public
  885. * @param bool [$bFull]
  886. * @return string
  887. **/
  888. public function getUrl($bFull = false) {
  889. // Set the sandbox URL
  890. $sSandboxUrl = defined('ICONTACT_APISANDBOXURL') ? constant('ICONTACT_APISANDBOXURL') : 'https://app.sandbox.icontact.com/icp';
  891. // Set the production URL
  892. $sApiUrl = defined('ICONTACT_APIURL') ? constant('ICONTACT_APIURL') : 'https://app.icontact.com/icp';
  893. // Determine which one needs to be returned with the URL
  894. $sBaseUrl = ($this->bSandbox === true) ? $sSandboxUrl : $sApiUrl;
  895. // Do we need to return the entire url or just
  896. // the base url of the API service
  897. if ($bFull === false) {
  898. // Return the base url
  899. return $sBaseUrl;
  900. } else {
  901. // Return the base url and account details
  902. return $sBaseUrl . "/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}";
  903. }
  904. }
  905. /**
  906. * This method grabs a specific upload
  907. * @access public
  908. * @param integer $iUploadId
  909. * @return object
  910. **/
  911. public function getUpload($iUploadId) {
  912. // Return the upload data
  913. return $this->makeCall("/a/{$this->setAccountId()}/c{$this->setClientFolderId()}/uploads/{$iUploadId}/data");
  914. }
  915. /**
  916. * This method grabs the uploads associated
  917. * with your iContact Account
  918. * @access public
  919. * @return array
  920. **/
  921. public function getUploads() {
  922. // Return the uploads
  923. return $this->makeCall("/a/{$this->setAccountId()}/c{$this->setClientFolderId()}/uploads");
  924. }
  925. /**
  926. * This method returns the warnings encountered
  927. * while communicating with the iContact API
  928. * @access public
  929. * @return array
  930. **/
  931. public function getWarnings() {
  932. // Return the current system warnings
  933. return $this->aWarnings;
  934. }
  935. //////////////////////////////////////////////////////////////////////////////
  936. /// Setters /////////////////////////////////////////////////////////////////
  937. ////////////////////////////////////////////////////////////////////////////
  938. /**
  939. * This method fetches the Account ID
  940. * from the iContact API if it has not
  941. * already been stored in the instance
  942. * @access public
  943. * @param integer [$iAccountId]
  944. * @return integer
  945. **/
  946. public function setAccountId($iAccountId = null) {
  947. // Check for an overriding
  948. // Account ID
  949. if (!empty($iAccountId)) {
  950. // Override the Account ID
  951. $this->iAccountId = (integer) $iAccountId;
  952. } else {
  953. // Check to see if the
  954. // Account ID has already
  955. // been stored in the
  956. // instance
  957. if (empty($this->iAccountId)) {
  958. // Load the Account ID
  959. if ($aAccounts = $this->makeCall('/a/', 'get', null, 'accounts')) {
  960. // Set the account
  961. $aAccount = $aAccounts[0];
  962. // Make sure the account is active
  963. if (intval($aAccount->enabled) === 1) {
  964. // The account is active
  965. // set the Account ID
  966. $this->iAccountId = (integer) $aAccount->accountId;
  967. } else {
  968. // Set an error, for this account
  969. // has been disabled
  970. $this->addError('Your account has been disabled.');
  971. }
  972. }
  973. }
  974. }
  975. // Inevitably return instance
  976. return $this->iAccountId;
  977. }
  978. /**
  979. * This method fetches the Client
  980. * Folder ID from the iContact API
  981. * if it has not already been stored
  982. * in the instance and the Account ID
  983. * has also been stored in the instance
  984. * @access public
  985. * @param integer [$iClientFolderId]
  986. * @return integer
  987. **/
  988. public function setClientFolderId($iClientFolderId = null) {
  989. // Check for an overriding
  990. // Client Folder ID
  991. if (!empty($iClientFolderId)) {
  992. // Set the Client Folder ID
  993. $this->iClientFolderId = (integer) $iClientFolderId;
  994. } elseif (empty($this->iClientFolderId)) {
  995. // Check for an Account ID
  996. if (empty($this->iAccountId)) {
  997. // Set the Account ID
  998. $this->setAccountId();
  999. }
  1000. // Set the resource
  1001. $sResource = (string) "/a/{$this->iAccountId}/c/";
  1002. // Find the Client Folder ID
  1003. if ($aClients = $this->makeCall($sResource, 'get', null, 'clientfolders')) {
  1004. if (empty($aClients)) {
  1005. // Add an error, for there
  1006. // are no client folders
  1007. $this->addError('No client folders were found for this account.');
  1008. } else {
  1009. // Grab the default client folder
  1010. $aClient = $aClients[0];
  1011. // Set the Client Folder ID
  1012. $this->iClientFolderId = (integer) $aClient->clientFolderId;
  1013. }
  1014. }
  1015. }
  1016. // Inevitably return instance
  1017. return $this->iClientFolderId;
  1018. }
  1019. /**
  1020. * This method sets configuration into the
  1021. * plugin to pragmatically override constants
  1022. * @access public
  1023. * @param array $aConfig
  1024. * @return iContactApi $this
  1025. **/
  1026. public function setConfig($aConfig) {
  1027. // Combine the arrays
  1028. $this->aConfig = (array) array_merge($this->aConfig, $aConfig);
  1029. // Return instance
  1030. return $this;
  1031. }
  1032. /**
  1033. * This method sets the result limit
  1034. * for GET requests to the iContact API
  1035. * @access public
  1036. * @param integer $iLimit
  1037. * @return iContactApi $this
  1038. **/
  1039. public function setLimit($iLimit) {
  1040. // Set the limit in the search parameters
  1041. $this->aSearchParameters['limit'] = (integer) $iLimit;
  1042. // Return instance
  1043. return $this;
  1044. }
  1045. /**
  1046. * This method sets the result index
  1047. * offset for paginating results from
  1048. * GET requests to the iContact API
  1049. * @access public
  1050. * @param integer $iOffset
  1051. * @return iContactApi $this
  1052. **/
  1053. public function setOffset($iOffset) {
  1054. // Set the offset in the search parameters
  1055. $this->aSearchParameters['offset'] = (integer) $iOffset;
  1056. // Return instance
  1057. return $this;
  1058. }
  1059. }