+ * @since 1.9.0
+ * @todo Update addList to use v3
*/
- private function set_authorization(): array {
+ private function add_to_list( $contact, $list ) {
+ if ( empty( $list ) ) {
+ return;
+ }
- // Set authorization header
- // Make string of "API_KEY:SECRET"
- $auth = $this->client_api_key;
- // Base64 encode it
- $credentials = base64_encode( $auth );
- // Create and set the Authorization header to use the encoded credentials
- $headers = [ 'Authorization: Basic ' . $credentials, 'cache-control: no-cache' ];
+ $list = is_array( $list ) ? $list : [ $list ];
- return $headers;
+ foreach ( $list as $list_id ) {
+ $contact->list_memberships[] = esc_attr( $list_id );
+ }
}
/**
- * Execute our API request for token acquisition.
+ * Helper method to output a link for our settings page tabs.
*
- * @since 2.0.0
+ * @since 2022-10-24
+ * @return string Settings tab URL.
+ */
+ public function get_settings_link( $settings_tab = 'ctct_options_settings_general' ) {
+
+ return add_query_arg(
+ [
+ 'post_type' => 'ctct_forms',
+ 'page' => sanitize_text_field( $settings_tab ),
+ ],
+ admin_url( 'edit.php' )
+ );
+ }
+
+ /**
+ * Maybe get the disclosure address from the API Organization Information.
*
- * @param string $url URL to make request to.
- * @param array $options Request options.
+ * @since 1.0.0
*
- * @return bool
- * @throws Exception
+ * @param bool $as_parts If true return an array.
+ * @return mixed
*/
- private function exec( $url, $options ): bool {
- $response = wp_safe_remote_post( $url, $options );
+ public function get_disclosure_info( $as_parts = false ) {
+ /*
+ * [
+ * [name] => Business Name
+ * [address] => 555 Business Place Ln., Beverly Hills, CA, 90210
+ * ]
+ */
- $this->last_error = '';
- $this->status_code = 0;
+ static $address_fields = [ 'address_line1', 'address_line2', 'address_line3', 'city', 'state_code', 'postal_code' ];
- if ( ! is_wp_error( $response ) ) {
- if ( empty( $response['body'] ) ) {
- constant_contact_maybe_log_it(
- 'Response error: ', implode( ":", $response['response'] )
- );
- return false;
- }
- $data = json_decode( $response['body'], true );
- $json_last_error = json_last_error();
- if ( JSON_ERROR_NONE !== $json_last_error ) {
- constant_contact_maybe_log_it( 'JSON error: ', json_last_error_msg() );
- }
+ // Grab disclosure info from the API.
+ $account_info = $this->get_account_info();
- // check if the body contains error
- if ( isset( $data['error'] ) ) {
- if ( 'invalid_grant' === $data['error'] ) {
- $this->api_errors_admin_email();
+ if ( empty( $account_info ) ) {
+ return $as_parts ? [] : '';
+ }
+
+ $disclosure = [
+ 'name' => empty( $account_info->organization_name ) ? constant_contact_get_option( '_ctct_disclose_name', '' ) : $account_info->organization_name,
+ 'address' => constant_contact_get_option( '_ctct_disclose_address', '' ),
+ ];
+
+ if ( empty( $disclosure['name'] ) ) {
+ return $as_parts ? [] : '';
+ }
+
+ // Determine the address to use for disclosure from the API.
+ if (
+ isset( $account_info['physical_address'] )
+ && count( $account_info['physical_address'] )
+ ) {
+ $organization_address = $account_info['physical_address'];
+ $disclosure_address = [];
+
+ if ( is_array( $address_fields ) ) {
+ foreach ( $address_fields as $field ) {
+ if ( isset( $organization_address[ $field ] ) && strlen( $organization_address[ $field ] ) ) {
+ $disclosure_address[] = $organization_address[ $field ];
+ }
}
- $this->last_error = $data['error'] . ': ' . ( $data['error_description'] ?? 'Undefined' );
- constant_contact_maybe_log_it( 'Error: ', $this->last_error );
- return false;
}
- if ( ! empty( $data['access_token'] ) ) {
+ $disclosure['address'] = implode( ', ', $disclosure_address );
+ } elseif ( empty( $disclosure['address'] ) ) {
+ unset( $disclosure['address'] );
+ }
- constant_contact_maybe_log_it( 'Refresh Token: ', 'Old Refresh Token: ' . $this->obfuscate_api_data_item( $this->refresh_token ) );
- constant_contact_maybe_log_it( 'Access Token: ', 'Old Access Token: ' . $this->obfuscate_api_data_item( $this->access_token ) );
+ if ( ! empty( $account_info['website'] ) ) {
+ $disclosure['website'] = $account_info['website'];
+ }
- constant_contact()->get_connect()->e_set( '_ctct_access_token', $data['access_token'] );
- constant_contact()->get_connect()->e_set( '_ctct_refresh_token', $data['refresh_token'] );
- constant_contact()->get_connect()->e_set( '_ctct_expires_in', (string) $data['expires_in'] );
+ return $as_parts ? $disclosure : implode( ', ', array_values( $disclosure ) );
+ }
- $this->access_token = $data['access_token'] ?? '';
- $this->refresh_token = $data['refresh_token'] ?? '';
- $this->expires_in = $data['expires_in'] ?? '';
+ /**
+ * Generate code_verifier and code_challenge for rfc7636 PKCE.
+ * https://datatracker.ietf.org/doc/html/rfc7636#appendix-B
+ *
+ * @return array [code_verifier, code_challenge].
+ */
+ private function code_challenge( ?string $code_verifier = null ): array {
+ $gen = static function () {
+ $strings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';
+ $length = random_int( 43, 128 );
- delete_option( 'ctct_auth_url' );
- $dateObj = current_datetime();
- $expDateObj = $dateObj->modify( '+' . $data['expires_in'] . ' seconds' );
+ for ( $i = 0; $i < $length; $i++ ) {
+ yield $strings[ random_int( 0, 65 ) ];
+ }
+ };
- constant_contact_maybe_log_it( 'Refresh Token: ', 'Refresh token successfully received' );
- constant_contact_maybe_log_it( 'Refresh Token: ', 'New Refresh Token: ' . $this->obfuscate_api_data_item( $this->refresh_token ) );
- constant_contact_maybe_log_it( 'Access Token: ', 'New Access Token: ' . $this->obfuscate_api_data_item( $this->access_token ) );
- constant_contact_maybe_log_it(
- 'Expiration time:',
- 'Current time: ' . $dateObj->format( 'Y-n-d, H:i' ) . ' Estimated expiration time: ' . $expDateObj->format( 'Y-n-d, H:i' )
- );
+ $code = $code_verifier ?? implode( '', iterator_to_array( $gen() ) );
- return isset( $data['access_token'], $data['refresh_token'] );
- }
- } else {
- $this->status_code = 0;
- $this->last_error = $response->get_error_message();
- constant_contact_maybe_log_it( 'Error: ', $this->last_error );
+ if ( ! \preg_match( '/[A-Za-z0-9-._~]{43,128}/', $code ) ) {
+ return [ '', '' ];
}
- return false;
+ return [ $code, constant_contact()->get_api_utility()->base64url_encode( pack( 'H*', hash( 'sha256', $code ) ) ) ];
}
/**
- * Obfuscate a value in our debug logs.
+ * Handle user session details.
*
- * Helps keep things private and not put into a potentially publicly accessed file.
+ * Not used.
*
- * @since 2.1.0
+ * @since 2.0.0
*
- * @param string $data_item Item to obfuscate.
+ * @param string $key
+ * @param string|null $value
*
- * @return string
+ * @return mixed|string
*/
- private function obfuscate_api_data_item( string $data_item ): string {
- $start = substr( $data_item, 0, 8 );
- return $start . '***';
+ public function session( string $key, ?string $value ) {
+ if ( $this->session_callback ) {
+ return call_user_func( $this->session_callback, $key, $value );
+ }
+ if ( null === $value ) {
+ $value = get_user_meta( $this->this_user_id, $key, true );
+ delete_user_meta( $this->this_user_id, $key, $value );
+
+ return $value;
+ }
+
+ update_user_meta( $this->this_user_id, $key, $value );
+
+ return $value;
}
/**
@@ -1734,31 +1622,6 @@ private function get_note_content( $submission_data ) {
return $note;
}
- /**
- * Check if our current access token is expired.
- *
- * Based on access token issued timestamp + expires in timestamp and current time.
- *
- * @since 2.2.0
- *
- * @return bool
- */
- private function access_token_maybe_expired() {
-
- $issued_time = get_option( 'ctct_access_token_timestamp', '' );
- if ( empty( $issued_time ) ) {
- // It's not expired because it doesn't exist.
- // This should be filled in by now though.
- return false;
- }
-
- $current_time = time();
- $expiration_time = (int) $issued_time + (int) $this->expires_in;
-
- // If we're currently above the expiration time, we're expired.
- return $current_time >= $expiration_time;
- }
-
/**
* Logs a missed API request to our overall log of missed requests.
*
@@ -1889,16 +1752,3 @@ public function set_email_type() {
return 'text/html';
}
}
-
-/**
- * Helper function to get/return the ConstantContact_API object.
- *
- * @since 1.0.0
- * @deprecated 2.11.0
- *
- * @return object ConstantContact_API
- */
-function constantcontact_api() {
- _deprecated_function( __FUNCTION__, '2.11.0', 'constant_contact()->get_api()' );
- return constant_contact()->get_api();
-}
diff --git a/includes/class-builder.php b/includes/class-builder.php
index 2788776e..c2324206 100644
--- a/includes/class-builder.php
+++ b/includes/class-builder.php
@@ -313,7 +313,7 @@ class="ctct-modal-flare"
-
+
diff --git a/includes/class-notification-content.php b/includes/class-notification-content.php
index 92cff866..28099e00 100644
--- a/includes/class-notification-content.php
+++ b/includes/class-notification-content.php
@@ -53,7 +53,7 @@ public static function activation(): string {
admin_url( 'edit.php' )
);
$auth_url = wp_nonce_url( $auth_url, 'ctct-user-is-dismissing', 'ctct-dismiss' );
- $try_url = constant_contact()->get_api()->get_signup_link();
+ $try_url = constant_contact()->get_api_utility()->get_signup_link();
if ( ! empty( $_GET['page'] ) && 'ctct_options_connect' === sanitize_text_field( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
return '';
diff --git a/includes/deprecated.php b/includes/deprecated.php
index fd3dec55..91e14c7c 100644
--- a/includes/deprecated.php
+++ b/includes/deprecated.php
@@ -58,3 +58,15 @@ function ctct_has_forms() {
return constant_contact_has_forms();
}
+
+/**
+ * Helper function to get/return the ConstantContact_API object.
+ * @return object ConstantContact_API
+ * @since 1.0.0
+ * @deprecated 2.11.0
+ */
+function constantcontact_api() {
+ _deprecated_function( __FUNCTION__, '2.11.0', 'constant_contact()->get_api()' );
+
+ return constant_contact()->get_api();
+}
diff --git a/includes/notification-logic.php b/includes/notification-logic.php
index b0c79f27..62289e97 100644
--- a/includes/notification-logic.php
+++ b/includes/notification-logic.php
@@ -16,7 +16,7 @@
* @return bool
* @since 1.2.2
*/
-function constant_contact_maybe_display_review_notification() : bool {
+function constant_contact_maybe_display_review_notification(): bool {
if ( ! current_user_can( 'manage_options' ) ) {
return false;
@@ -95,7 +95,7 @@ function constant_contact_maybe_display_review_notification() : bool {
* @return bool
* @since 1.6.0
*/
-function constant_contact_maybe_display_exceptions_notice() : bool {
+function constant_contact_maybe_display_exceptions_notice(): bool {
if ( ! current_user_can( 'manage_options' ) ) {
return false;
}
@@ -110,7 +110,7 @@ function constant_contact_maybe_display_exceptions_notice() : bool {
* @return bool Whether to display the deleted forms notice.
* @since 1.8.0
*/
-function constant_contact_maybe_display_deleted_forms_notice() : bool {
+function constant_contact_maybe_display_deleted_forms_notice(): bool {
if ( ! current_user_can( 'manage_options' ) ) {
return false;
}
@@ -153,7 +153,7 @@ function constant_contact_forms_maybe_set_exception_notice( $e = '' ) {
* @return bool
* @since 1.14.0
*/
-function constant_contact_maybe_display_api3_upgrade_notice() : bool {
+function constant_contact_maybe_display_api3_upgrade_notice(): bool {
if ( ! current_user_can( 'manage_options' ) ) {
return false;
}
@@ -168,7 +168,7 @@ function constant_contact_maybe_display_api3_upgrade_notice() : bool {
* @return bool|int
* @since 2.0.0
*/
-function constant_contact_maybe_display_api3_upgraded_notice() : bool {
+function constant_contact_maybe_display_api3_upgraded_notice(): bool {
if ( ! current_user_can( 'manage_options' ) ) {
return false;
}
@@ -190,7 +190,7 @@ function constant_contact_maybe_display_api3_upgraded_notice() : bool {
* @return bool
* @since 2.2.0
*/
-function constant_contact_maybe_display_disconnect_reconnect_notice() : bool {
+function constant_contact_maybe_display_disconnect_reconnect_notice(): bool {
if ( ! current_user_can( 'manage_options' ) ) {
return false;
}
@@ -203,7 +203,7 @@ function constant_contact_maybe_display_disconnect_reconnect_notice() : bool {
* @return bool
* @since 2.2.0
*/
-function constant_contact_maybe_show_cron_notification() : bool {
+function constant_contact_maybe_show_cron_notification(): bool {
if ( ! current_user_can( 'manage_options' ) ) {
return false;
}
@@ -219,7 +219,7 @@ function constant_contact_maybe_show_cron_notification() : bool {
return false;
}
-function constant_contact_maybe_show_update_available_notification() : bool {
+function constant_contact_maybe_show_update_available_notification(): bool {
if ( ! current_user_can( 'manage_options' ) ) {
return false;
}