File: /var/www/kevin-demo/wp-content/plugins/wpforms-sendinblue/src/Provider/Actions/SubscribeAction.php
<?php
namespace WPFormsSendinblue\Provider\Actions;
use WPFormsSendinblue\Api\Http\Response;
use WPFormsSendinblue\Api\Exceptions\ResponseException;
use WPFormsSendinblue\Api\Exceptions\RequiredArgumentMissingException;
/**
* Class SubscribeAction.
*
* @since 1.0.0
*/
class SubscribeAction extends Action {
/**
* Run action.
*
* @since 1.0.0
* @since 1.1.0 Added an opt-in subscribe.
*
* @throws ResponseException Invalid response.
* @throws RequiredArgumentMissingException Required argument is missing.
*/
public function run() {
if ( ! empty( $this->connection_data['fields_required']['opt_in']['value'] ) ) {
$this->opt_in_subscribe();
return;
}
$this->subscribe();
}
/**
* Process default subscription process.
*
* @since 1.1.0
*
* @throws ResponseException Invalid response.
* @throws RequiredArgumentMissingException Required argument is missing.
*/
private function subscribe() {
$this->update_contact_information();
$this->update_contact_email();
}
/**
* Process opt-in subscription process.
*
* @since 1.1.0
*
* @throws ResponseException Invalid response.
* @throws RequiredArgumentMissingException Required argument is missing.
* phpcs:ignore Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
*/
private function opt_in_subscribe() {
$email = sanitize_email( $this->field_mapper->get_field_value_by_id( $this->field_mapper->get_required_field_value( 'email', 'field_id' ) ) );
$list_id = absint( $this->field_mapper->get_required_field_value( 'list', 'list_id' ) );
$redirect_url = ! empty( $this->connection_data['fields_required']['redirect_url']['value'] ) ? $this->connection_data['fields_required']['redirect_url']['value'] : '';
$template_id = ! empty( $this->connection_data['fields_required']['template_id']['list_id'] ) ? $this->connection_data['fields_required']['template_id']['list_id'] : 0;
$attributes = $this->map_custom_fields();
$response = $this->create_opt_in_contact( $email, $list_id, $template_id, $redirect_url, $attributes );
if ( $this->is_invalid_phone( $response ) ) {
unset( $attributes['SMS'] );
$response = $this->create_opt_in_contact( $email, $list_id, $template_id, $redirect_url, $attributes );
}
if ( $response->has_errors() ) {
throw new ResponseException( esc_html( $response->get_response_message() ) );
}
}
/**
* Update contact information.
*
* @since 1.0.0
*
* @throws ResponseException Invalid response.
* @throws RequiredArgumentMissingException Required argument is missing.
*/
private function update_contact_information() {
$email = sanitize_email( $this->field_mapper->get_field_value_by_id( $this->field_mapper->get_required_field_value( 'email', 'field_id' ) ) );
if ( ! $email ) {
throw new RequiredArgumentMissingException( 'email' );
}
$list_id = absint( $this->field_mapper->get_required_field_value( 'list', 'list_id' ) );
$attributes = $this->map_custom_fields();
$response = $this->create_contact( $email, $list_id, $attributes );
if ( $this->is_invalid_phone( $response ) ) {
unset( $attributes['SMS'] );
$response = $this->create_contact( $email, $list_id, $attributes );
}
if ( $response->has_errors() ) {
throw new ResponseException( esc_html( $response->get_response_message() ) );
}
}
/**
* Is invalid phone response.
*
* @since 1.0.0
*
* @param Response $response Response from API.
*
* @return bool
*/
private function is_invalid_phone( $response ) {
$body = $response->get_body();
return ! empty( $body['code'] ) && ! empty( $body['message'] ) && $body['code'] === 'invalid_parameter' && $body['message'] === 'Invalid phone number';
}
/**
* Create a contact.
*
* @since 1.0.0
*
* @param string $email Contact's email.
* @param int $list_id List ID for contact.
* @param array $attributes List of attributes.
*
* @return Response
*/
private function create_contact( $email, $list_id, $attributes ) {
return $this->connection->create_contact(
$email,
$list_id,
$attributes
);
}
/**
* Create DOI contact.
*
* @since 1.0.0
*
* @param string $email Contact's email.
* @param int $list_id List ID for contact.
* @param int $template_id Email template ID.
* @param string $redirect_url Redirect URL for an opt-in button.
* @param array $attributes List of attributes.
*
* @return Response
*/
private function create_opt_in_contact( $email, $list_id, $template_id, $redirect_url, $attributes ) {
return $this->connection->create_opt_in_contact(
$email,
$list_id,
$template_id,
$redirect_url,
$attributes
);
}
/**
* Update contact email.
*
* @since 1.0.0
*
* @throws ResponseException Invalid response.
* @throws RequiredArgumentMissingException Required argument is missing.
* phpcs:ignore Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
*/
private function update_contact_email() {
$new_email_id = $this->field_mapper->get_not_required_field_value( 'new_email', 'field_id' );
if ( wpforms_is_empty_string( $new_email_id ) ) {
return;
}
$new_email = sanitize_email( $this->field_mapper->get_field_value_by_id( $new_email_id ) );
$email = sanitize_email( $this->field_mapper->get_field_value_by_id( $this->field_mapper->get_required_field_value( 'email', 'field_id' ) ) );
if ( empty( $new_email ) || empty( $email ) || $new_email === $email ) {
return;
}
$response = $this->connection->rename_contact(
$email,
$new_email
);
if ( $response->has_errors() ) {
// This exception will be thrown if the contact with a new email already exists.
// So rename will be skipped and logged.
throw new ResponseException( esc_html( $response->get_response_message() ) );
}
}
/**
* Get list of registered attributes in Sendinblue service.
*
* @since 1.0.0
*
* @return array
*/
private function get_attributes() {
$attributes = $this->connection->get_attributes();
if ( ! array_key_exists( 'attributes', $attributes->get_body() ) ) {
return [];
}
$attributes = $attributes->get_body()['attributes'];
foreach ( $attributes as $key => $attribute ) {
$attributes[ $attribute['name'] ] = $attribute;
unset( $attributes[ $key ] );
}
return $attributes;
}
/**
* Map Sendinblue attributes and form fields.
*
* @since 1.0.0
*
* @return array
*/
private function map_custom_fields() {
if ( empty( $this->connection_data['fields_meta'] ) ) {
return [];
}
$custom_fields = [];
$attributes = $this->get_attributes();
foreach ( $this->connection_data['fields_meta'] as $field ) {
if ( ! isset( $field['name'] ) ) {
continue;
}
$field_id = $this->field_mapper->get_custom_field_value( $field['name'] );
if ( wpforms_is_empty_string( $field_id ) ) {
continue;
}
$value = $this->field_mapper->get_formatted_field_value_by_id( $field_id, $attributes[ $field['name'] ] );
if ( $value === null || wpforms_is_empty_string( $value ) ) {
continue;
}
$custom_fields[ $field['name'] ] = $value;
}
return $custom_fields;
}
}