class-fl-builder-service-constant-contact.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <?php
  2. /**
  3. * Helper class for the Constant Contact API.
  4. *
  5. * @since 1.5.4
  6. */
  7. final class FLBuilderServiceConstantContact extends FLBuilderService {
  8. /**
  9. * The ID for this service.
  10. *
  11. * @since 1.5.4
  12. * @var string $id
  13. */
  14. public $id = 'constant-contact';
  15. /**
  16. * The api url for this service.
  17. *
  18. * @since 1.5.4
  19. * @var string $api_url
  20. */
  21. public $api_url = 'https://api.constantcontact.com/v2/';
  22. /**
  23. * Test the API connection.
  24. *
  25. * @since 1.5.4
  26. * @param array $fields {
  27. * @type string $api_key A valid API key.
  28. * @type string $access_token A valid access token.
  29. * }
  30. * @return array{
  31. * @type bool|string $error The error message or false if no error.
  32. * @type array $data An array of data used to make the connection.
  33. * }
  34. */
  35. public function connect( $fields = array() ) {
  36. $response = array(
  37. 'error' => false,
  38. 'data' => array(),
  39. );
  40. // Make sure we have an API key.
  41. if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
  42. $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
  43. } elseif ( ! isset( $fields['access_token'] ) || empty( $fields['access_token'] ) ) {
  44. $response['error'] = __( 'Error: You must provide an access token.', 'fl-builder' );
  45. } // Try to connect and store the connection data.
  46. else {
  47. $url = $this->api_url . 'lists?api_key=' . $fields['api_key'] . '&access_token=' . $fields['access_token'];
  48. $request = json_decode( wp_remote_retrieve_body( wp_remote_get( $url ) ) );
  49. if ( ! is_array( $request ) || ( isset( $request[0] ) && isset( $request[0]->error_message ) ) ) {
  50. $response['error'] = sprintf( __( 'Error: Could not connect to Constant Contact. %s', 'fl-builder' ), $request[0]->error_message );
  51. } else {
  52. $response['data'] = array(
  53. 'api_key' => $fields['api_key'],
  54. 'access_token' => $fields['access_token'],
  55. );
  56. }
  57. }
  58. return $response;
  59. }
  60. /**
  61. * Renders the markup for the connection settings.
  62. *
  63. * @since 1.5.4
  64. * @return string The connection settings markup.
  65. */
  66. public function render_connect_settings() {
  67. ob_start();
  68. FLBuilder::render_settings_field( 'api_key', array(
  69. 'row_class' => 'fl-builder-service-connect-row',
  70. 'class' => 'fl-builder-service-connect-input',
  71. 'type' => 'text',
  72. 'label' => __( 'API Key', 'fl-builder' ),
  73. 'help' => __( 'Your Constant Contact API key.', 'fl-builder' ),
  74. 'preview' => array(
  75. 'type' => 'none',
  76. ),
  77. ));
  78. FLBuilder::render_settings_field( 'access_token', array(
  79. 'row_class' => 'fl-builder-service-connect-row',
  80. 'class' => 'fl-builder-service-connect-input',
  81. 'type' => 'text',
  82. 'label' => __( 'Access Token', 'fl-builder' ),
  83. 'help' => __( 'Your Constant Contact access token.', 'fl-builder' ),
  84. 'description' => sprintf( __( 'You must register a <a%1$s>Developer Account</a> with Constant Contact to obtain an API key and access token. Please see <a%2$s>Getting an API key</a> for complete instructions.', 'fl-builder' ), ' href="https://constantcontact.mashery.com/member/register" target="_blank"', ' href="https://developer.constantcontact.com/home/api-keys.html" target="_blank"' ),
  85. 'preview' => array(
  86. 'type' => 'none',
  87. ),
  88. ));
  89. return ob_get_clean();
  90. }
  91. /**
  92. * Render the markup for service specific fields.
  93. *
  94. * @since 1.5.4
  95. * @param string $account The name of the saved account.
  96. * @param object $settings Saved module settings.
  97. * @return array {
  98. * @type bool|string $error The error message or false if no error.
  99. * @type string $html The field markup.
  100. * }
  101. */
  102. public function render_fields( $account, $settings ) {
  103. $account_data = $this->get_account_data( $account );
  104. $api_key = $account_data['api_key'];
  105. $access_token = $account_data['access_token'];
  106. $url = $this->api_url . 'lists?api_key=' . $api_key . '&access_token=' . $access_token;
  107. $request = json_decode( wp_remote_retrieve_body( wp_remote_get( $url ) ) );
  108. $response = array(
  109. 'error' => false,
  110. 'html' => '',
  111. );
  112. if ( ! is_array( $request ) || ( isset( $request[0] ) && isset( $request[0]->error_message ) ) ) {
  113. $response['error'] = sprintf( __( 'Error: Could not connect to Constant Contact. %s', 'fl-builder' ), $request[0]->error_message );
  114. } else {
  115. $response['html'] = $this->render_list_field( $request, $settings );
  116. }
  117. return $response;
  118. }
  119. /**
  120. * Render markup for the list field.
  121. *
  122. * @since 1.5.4
  123. * @param array $lists List data from the API.
  124. * @param object $settings Saved module settings.
  125. * @return string The markup for the list field.
  126. * @access private
  127. */
  128. private function render_list_field( $lists, $settings ) {
  129. ob_start();
  130. $options = array(
  131. '' => __( 'Choose...', 'fl-builder' ),
  132. );
  133. foreach ( $lists as $list ) {
  134. $options[ $list->id ] = $list->name;
  135. }
  136. FLBuilder::render_settings_field( 'list_id', array(
  137. 'row_class' => 'fl-builder-service-field-row',
  138. 'class' => 'fl-builder-service-list-select',
  139. 'type' => 'select',
  140. 'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
  141. 'options' => $options,
  142. 'preview' => array(
  143. 'type' => 'none',
  144. ),
  145. ), $settings);
  146. return ob_get_clean();
  147. }
  148. /**
  149. * Subscribe an email address to Constant Contact.
  150. *
  151. * @since 1.5.4
  152. * @param object $settings A module settings object.
  153. * @param string $email The email to subscribe.
  154. * @param string $name Optional. The full name of the person subscribing.
  155. * @return array {
  156. * @type bool|string $error The error message or false if no error.
  157. * }
  158. */
  159. public function subscribe( $settings, $email, $name = false ) {
  160. $account_data = $this->get_account_data( $settings->service_account );
  161. $response = array(
  162. 'error' => false,
  163. );
  164. if ( ! $account_data ) {
  165. $response['error'] = __( 'There was an error subscribing to Constant Contact. The account is no longer connected.', 'fl-builder' );
  166. } else {
  167. $api_key = $account_data['api_key'];
  168. $access_token = $account_data['access_token'];
  169. $url = $this->api_url . 'contacts?api_key=' . $api_key . '&access_token=' . $access_token . '&email=' . $email;
  170. $request = wp_remote_get( $url );
  171. $contact = json_decode( wp_remote_retrieve_body( $request ) );
  172. $list_id = $settings->list_id;
  173. // This contact exists.
  174. if ( ! empty( $contact->results ) ) {
  175. $args = array();
  176. $data = $contact->results[0];
  177. // Check if already subscribed to this list.
  178. if ( ! empty( $data->lists ) ) {
  179. // Return early if already added.
  180. foreach ( $data->lists as $key => $list ) {
  181. if ( isset( $list->id ) && $list_id == $list->id ) {
  182. return $response;
  183. }
  184. }
  185. // Add an existing contact to the list.
  186. $new_list = new stdClass;
  187. $new_list->id = $list_id;
  188. $new_list->status = 'ACTIVE';
  189. $data->lists[ count( $data->lists ) ] = $new_list;
  190. } else {
  191. // Add an existing contact that has no list.
  192. $data->lists = array();
  193. $new_list = new stdClass;
  194. $new_list->id = $list_id;
  195. $new_list->status = 'ACTIVE';
  196. $data->lists[0] = $new_list;
  197. }
  198. $args['body'] = json_encode( $data );
  199. $args['method'] = 'PUT';
  200. $args['headers']['Content-Type'] = 'application/json';
  201. $args['headers']['Content-Length'] = strlen( $args['body'] );
  202. $url = $this->api_url . 'contacts/' . $contact->results[0]->id . '?api_key=' . $api_key . '&access_token=' . $access_token . '&action_by=ACTION_BY_VISITOR';
  203. $update = wp_remote_request( $url, $args );
  204. $res = json_decode( wp_remote_retrieve_body( $update ) );
  205. if ( isset( $res->error_key ) ) {
  206. $response['error'] = sprintf( __( 'There was an error subscribing to Constant Contact. %s', 'fl-builder' ), $res->error_key );
  207. }
  208. } else {
  209. // @codingStandardsIgnoreLine
  210. $args = $data = array();
  211. $data['email_addresses'] = array();
  212. $data['email_addresses'][0]['id'] = $list_id;
  213. $data['email_addresses'][0]['status'] = 'ACTIVE';
  214. $data['email_addresses'][0]['confirm_status'] = 'CONFIRMED';
  215. $data['email_addresses'][0]['email_address'] = $email;
  216. $data['lists'] = array();
  217. $data['lists'][0]['id'] = $list_id;
  218. if ( $name ) {
  219. $names = explode( ' ', $name );
  220. if ( isset( $names[0] ) ) {
  221. $data['first_name'] = $names[0];
  222. }
  223. if ( isset( $names[1] ) ) {
  224. $data['last_name'] = $names[1];
  225. }
  226. }
  227. $args['body'] = json_encode( $data );
  228. $args['headers']['Content-Type'] = 'application/json';
  229. $args['headers']['Content-Length'] = strlen( json_encode( $data ) );
  230. $url = $this->api_url . 'contacts?api_key=' . $api_key . '&access_token=' . $access_token . '&action_by=ACTION_BY_VISITOR';
  231. $create = wp_remote_post( $url, $args );
  232. if ( isset( $create->error_key ) ) {
  233. $response['error'] = sprintf( __( 'There was an error subscribing to Constant Contact. %s', 'fl-builder' ), $create->error_key );
  234. }
  235. }
  236. }
  237. return $response;
  238. }
  239. }