CtCt
2 years ago
images
7 years ago
constantcontact.php
3 years ago
hustle-constantcontact-api.php
2 years ago
hustle-constantcontact-form-hooks.php
3 years ago
hustle-constantcontact-form-settings.php
3 years ago
hustle-constantcontact.php
3 years ago
hustle-constantcontact-api.php
422 lines
| 1 | <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName |
| 2 | /** |
| 3 | * Hustle_ConstantContact_Api class |
| 4 | * |
| 5 | * @package Hustle |
| 6 | */ |
| 7 | |
| 8 | if ( version_compare( PHP_VERSION, '5.3', '>=' ) ) { |
| 9 | |
| 10 | if ( ! class_exists( 'Ctct\CTCTOfficialSplClassLoader' ) ) { |
| 11 | require_once dirname( __FILE__ ) . '/CtCt/autoload.php'; |
| 12 | } |
| 13 | |
| 14 | if ( ! class_exists( 'Hustle_ConstantContact_Api' ) ) : |
| 15 | |
| 16 | /** |
| 17 | * Class Hustle_ConstantContact_Api |
| 18 | */ |
| 19 | class Hustle_ConstantContact_Api extends Opt_In_WPMUDEV_API { |
| 20 | |
| 21 | const API_URL = 'https://api.constantcontact.com/v2/'; |
| 22 | const AUTH_API_URL = 'https://oauth2.constantcontact.com/'; |
| 23 | |
| 24 | const APIKEY = 'wn8r98wcxnegkgy976xeuegt'; |
| 25 | const CONSUMER_SECRET = 'QZytJQReSTM3K9bH4NG9Dd2A'; |
| 26 | |
| 27 | // Random client ID we use to verify our calls. |
| 28 | const CLIENT_ID = '9253e5C3-28d6-48fd-c102-b92b8f250G1b'; |
| 29 | |
| 30 | const REFERER = 'hustle_constantcontact_referer'; |
| 31 | const CURRENTPAGE = 'hustle_constantcontact_current_page'; |
| 32 | |
| 33 | /** |
| 34 | * Auth token |
| 35 | * |
| 36 | * @var string |
| 37 | */ |
| 38 | private $option_token_name = 'hustle_opt-in-constant_contact-token'; |
| 39 | |
| 40 | /** |
| 41 | * Is error |
| 42 | * |
| 43 | * @var bool |
| 44 | */ |
| 45 | public $is_error = false; |
| 46 | |
| 47 | /** |
| 48 | * Error message |
| 49 | * |
| 50 | * @var string |
| 51 | */ |
| 52 | public $error_message; |
| 53 | |
| 54 | /** |
| 55 | * Sending |
| 56 | * |
| 57 | * @var boolean |
| 58 | */ |
| 59 | public $sending = false; |
| 60 | |
| 61 | |
| 62 | /** |
| 63 | * Hustle_ConstantContact_Api constructor. |
| 64 | */ |
| 65 | public function __construct() { |
| 66 | // Init request callback listener. |
| 67 | add_action( 'init', array( $this, 'process_callback_request' ) ); |
| 68 | } |
| 69 | |
| 70 | /** |
| 71 | * Helper function to listen to request callback sent from WPMUDEV |
| 72 | */ |
| 73 | public function process_callback_request() { |
| 74 | if ( $this->validate_callback_request( 'constantcontact' ) ) { |
| 75 | $code = filter_input( INPUT_GET, 'code', FILTER_SANITIZE_SPECIAL_CHARS ); |
| 76 | $status = 'error'; |
| 77 | |
| 78 | // Get the referer page that sent the request. |
| 79 | $referer = get_option( self::REFERER ); |
| 80 | $current_page = get_option( self::CURRENTPAGE ); |
| 81 | if ( $code ) { |
| 82 | if ( $this->get_access_token( $code ) ) { |
| 83 | if ( ! empty( $referer ) ) { |
| 84 | $status = 'success'; |
| 85 | } |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | if ( ! empty( $referer ) ) { |
| 90 | $referer = add_query_arg( 'status', $status, $referer ); |
| 91 | wp_safe_redirect( $referer ); |
| 92 | exit; |
| 93 | } |
| 94 | |
| 95 | // Allow retry but don't log referrer. |
| 96 | $authorization_uri = $this->get_authorization_uri( false, false, $current_page ); |
| 97 | |
| 98 | $this->api_die( __( 'Constant Contact integration failed!', 'hustle' ), $authorization_uri, $referer ); |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | |
| 103 | /** |
| 104 | * Generates authorization URL |
| 105 | * |
| 106 | * @param int $module_id Module ID. |
| 107 | * @param bool $log_referrer Log referrer. |
| 108 | * @param string $page Page. |
| 109 | * |
| 110 | * @return string |
| 111 | */ |
| 112 | public function get_authorization_uri( $module_id = 0, $log_referrer = true, $page = 'hustle_embedded' ) { |
| 113 | $oauth = new Ctct\Auth\CtctOAuth2( self::APIKEY, self::CONSUMER_SECRET, $this->get_redirect_uri() ); |
| 114 | if ( $log_referrer ) { |
| 115 | /** |
| 116 | * Store $referer to use after retrieving the access token |
| 117 | */ |
| 118 | $params = array( |
| 119 | 'page' => $page, |
| 120 | 'action' => 'external-redirect', |
| 121 | 'slug' => 'constantcontact', |
| 122 | 'nonce' => wp_create_nonce( 'hustle_provider_external_redirect' ), |
| 123 | ); |
| 124 | if ( ! empty( $module_id ) ) { |
| 125 | $params['id'] = $module_id; |
| 126 | $params['section'] = 'integrations'; |
| 127 | } |
| 128 | $referer = add_query_arg( $params, admin_url( 'admin.php' ) ); |
| 129 | update_option( self::REFERER, $referer ); |
| 130 | update_option( self::CURRENTPAGE, $page ); |
| 131 | } |
| 132 | return $oauth->getAuthorizationUrl(); |
| 133 | } |
| 134 | |
| 135 | /** |
| 136 | * Get token |
| 137 | * |
| 138 | * @param string $key Key. |
| 139 | * |
| 140 | * @return bool|mixed |
| 141 | */ |
| 142 | public function get_token( $key ) { |
| 143 | $auth = $this->get_auth_token(); |
| 144 | |
| 145 | if ( ! empty( $auth ) && ! empty( $auth[ $key ] ) ) { |
| 146 | return $auth[ $key ]; } |
| 147 | |
| 148 | return false; |
| 149 | } |
| 150 | |
| 151 | |
| 152 | /** |
| 153 | * Compose redirect_uri to use on request argument. |
| 154 | * The redirect uri must be constant and should not be change per request. |
| 155 | * |
| 156 | * @return string |
| 157 | */ |
| 158 | public function get_redirect_uri() { |
| 159 | return $this->redirect_uri( |
| 160 | 'constantcontact', |
| 161 | 'authorize', |
| 162 | array( |
| 163 | 'client_id' => self::CLIENT_ID, |
| 164 | 'state' => rawurlencode( $this->get_nonce_value() . '|' . site_url( '/' ) ), |
| 165 | ) |
| 166 | ); |
| 167 | } |
| 168 | |
| 169 | /** |
| 170 | * Get Access token |
| 171 | * |
| 172 | * @param string $code Code. |
| 173 | */ |
| 174 | public function get_access_token( $code ) { |
| 175 | $oauth = new Ctct\Auth\CtctOAuth2( self::APIKEY, self::CONSUMER_SECRET, $this->get_redirect_uri() ); |
| 176 | $access_token = $oauth->getAccessToken( $code ); |
| 177 | |
| 178 | $this->update_auth_token( $access_token ); |
| 179 | |
| 180 | return true; |
| 181 | } |
| 182 | |
| 183 | |
| 184 | /** |
| 185 | * Get stored token data. |
| 186 | * |
| 187 | * @return array|null |
| 188 | */ |
| 189 | public function get_auth_token() { |
| 190 | return get_option( $this->option_token_name ); |
| 191 | } |
| 192 | |
| 193 | |
| 194 | /** |
| 195 | * Update token data. |
| 196 | * |
| 197 | * @param array $token Token. |
| 198 | * @return void |
| 199 | */ |
| 200 | public function update_auth_token( array $token ) { |
| 201 | update_option( $this->option_token_name, $token ); |
| 202 | } |
| 203 | |
| 204 | /** |
| 205 | * Get current account information. |
| 206 | * |
| 207 | * @since 4.0.2 |
| 208 | * @throws Exception When there's a conflict with another CTCT plugin. |
| 209 | * @return object |
| 210 | */ |
| 211 | public function get_account_info() { |
| 212 | $cc_api = new Ctct\ConstantContact( self::APIKEY ); |
| 213 | if ( ! method_exists( $cc_api, 'getAccountInfo' ) ) { |
| 214 | throw new Exception( "There's a conflict with another plugin using the CTCT's library." ); |
| 215 | } |
| 216 | return $cc_api->getAccountInfo( $this->get_token( 'access_token' ) ); |
| 217 | } |
| 218 | |
| 219 | /** |
| 220 | * Retrieve contact lists from ConstantContact |
| 221 | * |
| 222 | * @return array |
| 223 | */ |
| 224 | public function get_contact_lists() { |
| 225 | |
| 226 | $cc_api = new Ctct\ConstantContact( self::APIKEY ); |
| 227 | |
| 228 | $access_token = $this->get_token( 'access_token' ); |
| 229 | |
| 230 | $lists_data = $cc_api->listService->getLists( $access_token );// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase |
| 231 | |
| 232 | return ( ! empty( $lists_data ) && is_array( $lists_data ) ) ? $lists_data : array(); |
| 233 | } |
| 234 | |
| 235 | |
| 236 | /** |
| 237 | * Retrieve contact from ConstantContact |
| 238 | * |
| 239 | * @param string $email Email. |
| 240 | * @return false|Object |
| 241 | */ |
| 242 | public function get_contact( $email ) { |
| 243 | $contact = false; |
| 244 | $cc_api = new Ctct\ConstantContact( self::APIKEY ); |
| 245 | $access_token = $this->get_token( 'access_token' ); |
| 246 | $res = $cc_api->contactService->getContacts( $access_token, array( 'email' => $email ) );// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase |
| 247 | if ( is_object( $res ) && ! empty( $res->results ) ) { |
| 248 | $contact = $res->results[0]; |
| 249 | } |
| 250 | return $contact; |
| 251 | |
| 252 | } |
| 253 | |
| 254 | |
| 255 | /** |
| 256 | * Check if contact exists in certain list |
| 257 | * |
| 258 | * @param object $contact \Ctct\Components\Contacts\Contact. |
| 259 | * @param string $list_id List ID. |
| 260 | * @return bool |
| 261 | */ |
| 262 | public function contact_exist( $contact, $list_id ) { |
| 263 | $exists = false; |
| 264 | if ( $contact instanceof Ctct\Components\Contacts\Contact ) { |
| 265 | $lists = $contact->lists; |
| 266 | foreach ( $lists as $list ) { |
| 267 | $list = (array) $list; |
| 268 | if ( (string) $list_id === (string) $list['id'] ) { |
| 269 | $exists = true; |
| 270 | break; |
| 271 | } |
| 272 | } |
| 273 | } |
| 274 | |
| 275 | return $exists; |
| 276 | } |
| 277 | |
| 278 | |
| 279 | /** |
| 280 | * Subscribe contact |
| 281 | * |
| 282 | * @param String $email Email. |
| 283 | * @param String $first_name First name. |
| 284 | * @param String $last_name Last name. |
| 285 | * @param String $list List. |
| 286 | * @param Array $custom_fields Custom fields. |
| 287 | */ |
| 288 | public function subscribe( $email, $first_name, $last_name, $list, $custom_fields = array() ) { |
| 289 | $access_token = $this->get_token( 'access_token' ); |
| 290 | $cc_api = new Ctct\ConstantContact( self::APIKEY ); |
| 291 | $contact = new Ctct\Components\Contacts\Contact(); |
| 292 | $contact->addEmail( $email ); |
| 293 | if ( ! empty( $first_name ) ) { |
| 294 | $contact->first_name = $first_name; |
| 295 | } |
| 296 | if ( ! empty( $last_name ) ) { |
| 297 | $contact->last_name = $last_name; |
| 298 | } |
| 299 | $contact->addList( $list ); |
| 300 | |
| 301 | if ( ! empty( $custom_fields ) ) { |
| 302 | $allowed = array( |
| 303 | 'prefix_name', |
| 304 | 'job_title', |
| 305 | 'company_name', |
| 306 | 'home_phone', |
| 307 | 'work_phone', |
| 308 | 'cell_phone', |
| 309 | 'fax', |
| 310 | ); |
| 311 | |
| 312 | // Add extra fields. |
| 313 | $x = 1; |
| 314 | foreach ( $custom_fields as $key => $value ) { |
| 315 | if ( in_array( $key, $allowed, true ) ) { |
| 316 | $contact->$key = $value; |
| 317 | } else { |
| 318 | if ( ! empty( $value ) ) { |
| 319 | $custom_field = array( |
| 320 | 'name' => 'CustomField' . $x, |
| 321 | 'value' => $value, |
| 322 | ); |
| 323 | $contact->custom_fields[] = $custom_field; |
| 324 | $x++; |
| 325 | } |
| 326 | } |
| 327 | } |
| 328 | } |
| 329 | |
| 330 | $response = $cc_api->contactService->addContact( $access_token, $contact, array( 'action_by' => 'ACTION_BY_VISITOR' ) );// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase |
| 331 | |
| 332 | return $response; |
| 333 | } |
| 334 | |
| 335 | /** |
| 336 | * Remove wp_options rows |
| 337 | */ |
| 338 | public function remove_wp_options() { |
| 339 | delete_option( $this->option_token_name ); |
| 340 | delete_option( self::REFERER ); |
| 341 | delete_option( self::CURRENTPAGE ); |
| 342 | } |
| 343 | |
| 344 | /** |
| 345 | * Update Subscription |
| 346 | * |
| 347 | * @param object $contact Contact. |
| 348 | * @param string $first_name First name. |
| 349 | * @param string $last_name Last name. |
| 350 | * @param string $list List. |
| 351 | * @param array $custom_fields Custom fields. |
| 352 | * @return type |
| 353 | */ |
| 354 | public function updateSubscription( $contact, $first_name, $last_name, $list, $custom_fields = array() ) { |
| 355 | $access_token = $this->get_token( 'access_token' ); |
| 356 | $cc_api = new Ctct\ConstantContact( self::APIKEY ); |
| 357 | $contact->addList( $list ); |
| 358 | if ( ! empty( $first_name ) ) { |
| 359 | $contact->first_name = $first_name; |
| 360 | } |
| 361 | if ( ! empty( $last_name ) ) { |
| 362 | $contact->last_name = $last_name; |
| 363 | } |
| 364 | |
| 365 | if ( ! empty( $custom_fields ) ) { |
| 366 | $allowed = array( |
| 367 | 'prefix_name', |
| 368 | 'job_title', |
| 369 | 'company_name', |
| 370 | 'home_phone', |
| 371 | 'work_phone', |
| 372 | 'cell_phone', |
| 373 | 'fax', |
| 374 | ); |
| 375 | |
| 376 | // Add extra fields. |
| 377 | $x = 1; |
| 378 | foreach ( $custom_fields as $key => $value ) { |
| 379 | if ( in_array( $key, $allowed, true ) ) { |
| 380 | $contact->$key = $value; |
| 381 | } else { |
| 382 | if ( ! empty( $value ) ) { |
| 383 | $custom_field = array( |
| 384 | 'name' => 'CustomField' . $x, |
| 385 | 'value' => $value, |
| 386 | ); |
| 387 | $contact->custom_fields[] = $custom_field; |
| 388 | $x++; |
| 389 | } |
| 390 | } |
| 391 | } |
| 392 | } |
| 393 | |
| 394 | $response = $cc_api->contactService->updateContact( $access_token, $contact, array( 'action_by' => 'ACTION_BY_VISITOR' ) );// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase |
| 395 | |
| 396 | return $response; |
| 397 | } |
| 398 | |
| 399 | /** |
| 400 | * Delete subscriber from the list |
| 401 | * |
| 402 | * @param string $list_id List ID. |
| 403 | * @param string $email Email. |
| 404 | * |
| 405 | * @return bool |
| 406 | */ |
| 407 | public function delete_email( $list_id, $email ) { |
| 408 | $contact = $this->get_contact( $email ); |
| 409 | if ( empty( $contact->id ) ) { |
| 410 | return false; |
| 411 | } |
| 412 | |
| 413 | $cc_api = new Ctct\ConstantContact( self::APIKEY ); |
| 414 | $access_token = $this->get_token( 'access_token' ); |
| 415 | $res = $cc_api->contactService->deleteContactFromList( $access_token, $contact->id, $list_id ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase |
| 416 | |
| 417 | return ! is_wp_error( $res ); |
| 418 | } |
| 419 | } |
| 420 | endif; |
| 421 | } |
| 422 |