whoami7 - Manager
:
/
home
/
dataiclx
/
vielorbe.com
/
wp-content
/
plugins
/
suremails
/
inc
/
api
/
Upload File:
files >> //home/dataiclx/vielorbe.com/wp-content/plugins/suremails/inc/api/save-test-connection.php
<?php /** * SaveTestConnection class * * Handles the REST API endpoint for testing and saving email connection settings. * * @package SureMails\Inc\API */ namespace SureMails\Inc\API; use SureMails\Inc\Emails\Handler\ConnectionHandlerFactory; use SureMails\Inc\Providers; use SureMails\Inc\Settings; use SureMails\Inc\Traits\Instance; use WP_REST_Request; use WP_REST_Response; use WP_REST_Server; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Class SaveTestConnection * * Handles the `/test-and-save-email-connection` REST API endpoint. */ class SaveTestConnection extends Api_Base { use Instance; /** * Indicates whether the current flow is for saving a connection. * When simulation mode is enabled, this flag ensures that the Connection Handler Factory returns the appropriate handler for performing the save operation. * * @since 1.5.0 * @var bool True if saving a connection, false otherwise. */ public $saving_connection = false; /** * Route base. * * @var string */ protected $rest_base = '/test-and-save-email-connection'; /** * Register API routes. * * @since 0.0.1 * @return void */ public function register_routes() { register_rest_route( $this->get_api_namespace(), $this->rest_base, [ [ 'methods' => WP_REST_Server::CREATABLE, 'callback' => [ $this, 'handle_test_save_email_connection' ], 'permission_callback' => [ $this, 'validate_permission' ], ], ] ); } /** * Handle testing and saving the email connection settings. * * This method will: * - Retrieve the provider-specific fields via Providers::get_provider_options(). * - Validate that all required fields are present. * - Prepare the connection data. * - Check for priority uniqueness. * - Authenticate the connection using the appropriate handler. * - Save the connection settings. * * @param WP_REST_Request<array<string, mixed>> $request The REST request object. * @return WP_REST_Response The REST API response. */ public function handle_test_save_email_connection( $request ) { try { $params = $request->get_json_params(); $settings = $params['settings'] ?? []; $provider = strtoupper( sanitize_text_field( $params['provider'] ?? '' ) ); $this->saving_connection = true; $options = Providers::instance()->get_provider_options( $provider ); if ( null === $options ) { return new WP_REST_Response( [ 'success' => false, 'message' => __( 'Unsupported connection type.', 'suremails' ), ], 400 ); } $fields = $options['fields'] ?? []; $validation = $this->validate_schema_fields( $fields, $settings ); if ( ! $validation['success'] ) { return new WP_REST_Response( [ 'success' => false, 'message' => $validation['message'], ], 400 ); } // Prepare connection data (only the fields defined in the providier options). $connection_data = $this->prepare_connection_data( $fields, $settings ); $connection_data['type'] = strtoupper( $provider ); // Check for priority uniqueness. if ( isset( $connection_data['priority'] ) && ! $this->is_priority_unique( intval( $connection_data['priority'] ), $connection_data['id'] ?? '' ) ) { return new WP_REST_Response( [ 'success' => false, 'message' => sprintf( /* translators: %s: Connection priority */ __( 'Connection Sequence %1$s is already assigned to another connection. Please choose a different sequence.', 'suremails' ), $connection_data['priority'] ), ], 400 ); } // Authenticate the connection before testing or saving it. $auth_result = $this->authenticate_connection( $connection_data ); if ( $auth_result['success'] !== true ) { $status_code = $auth_result['error_code'] ?? 401; return new WP_REST_Response( [ 'success' => false, 'message' => $auth_result['message'] ?? __( 'Failed to authenticate.', 'suremails' ), ], $status_code ); } // If the connection is authenticated, store the connection data. $add_extra_fields = $this->add_extra_fields( $connection_data, $auth_result ); $new_connection_data = $this->store_connection( $add_extra_fields ); return new WP_REST_Response( [ 'success' => true, 'message' => __( 'Connection authenticated and settings saved.', 'suremails' ), 'connection' => $new_connection_data, ], 200 ); } catch ( \Exception $e ) { return new WP_REST_Response( [ 'success' => false, 'message' => __( 'An error occurred: ', 'suremails' ) . $e->getMessage(), ], 500 ); } finally { // Reset the saving_connection flag. $this->saving_connection = false; } } /** * Authenticate the email connection to ensure it is valid. * * @param array $connection_data The connection data. * @return array The result of the authentication process. */ public function authenticate_connection( array $connection_data ) { $handler = ConnectionHandlerFactory::create( $connection_data ); if ( empty( $handler ) ) { return [ 'success' => false, 'message' => __( 'Invalid connection type.', 'suremails' ), 'error_code' => 400, ]; } $auth_result = $handler->authenticate(); // Include an error code based on the specific error, if provided. if ( isset( $auth_result['success'] ) && ! $auth_result['success'] ) { $auth_result['error_code'] = $auth_result['error_code'] ?? 401; } return $auth_result; } /** * Get all connection details. * * @return array The array of all connections. */ public function get_all_connections() { // Fetch the connections from the WordPress options. $connections = Settings::instance()->get_settings(); // Ensure the returned value is an array, even if the option does not exist. return is_array( $connections['connections'] ) ? $connections['connections'] : []; } /** * Store the email connection data in the database. * * @param array $connection_data The connection data. * @return array The stored connection data. */ public function store_connection( array $connection_data ) { $options = Settings::instance()->get_settings(); // Check if it's a new connection or an update. if ( isset( $connection_data['id'] ) && ! empty( $connection_data['id'] ) ) { // If it's an update, keep the existing `created_at` timestamp if it exists. if ( ! empty( $options['connections'][ $connection_data['id'] ]['created_at'] ) ) { $connection_data['created_at'] = $options['connections'][ $connection_data['id'] ]['created_at']; } if ( $options['default_connection']['id'] === $connection_data['id'] ) { $options['default_connection'] = [ 'type' => $connection_data['type'], 'email' => $connection_data['from_email'], 'id' => $connection_data['id'], 'connection_title' => $connection_data['connection_title'], ]; } $options['connections'][ $connection_data['id'] ] = $connection_data; } else { // For new connections, generate a unique ID and add a `created_at` timestamp. $connection_data['id'] = $this->generate_unique_id( $options['connections'] ); // Store the timestamp in MySQL datetime format. $connection_data['created_at'] = current_time( 'mysql' ); $options['connections'][ $connection_data['id'] ] = $connection_data; } // Set default connection if necessary. if ( count( $options['connections'] ) === 1 ) { $options['default_connection'] = [ 'type' => $connection_data['type'], 'email' => $connection_data['from_email'] ?? '', 'id' => $connection_data['id'], 'connection_title' => $connection_data['connection_title'] ?? '', ]; } // Update the options in the WordPress database. update_option( SUREMAILS_CONNECTIONS, Settings::instance()->encrypt_all( $options ) ); return $connection_data; } /** * Add extra fields to the connection data. * * @param array $connection_data The connection data. * @param array $new_fields The new fields to add. * @return array The updated connection data. */ protected function add_extra_fields( $connection_data, $new_fields ) { $providers = [ 'GMAIL', ]; if ( ! in_array( $connection_data['type'], $providers ) ) { return $connection_data; } if ( isset( $new_fields['refresh_token'] ) ) { $connection_data['refresh_token'] = $new_fields['refresh_token']; } if ( isset( $new_fields['access_token'] ) ) { $connection_data['access_token'] = $new_fields['access_token']; } if ( isset( $new_fields['expires_in'] ) ) { $connection_data['expires_in'] = $new_fields['expires_in']; } if ( isset( $new_fields['expire_stamp'] ) ) { $connection_data['expire_stamp'] = $new_fields['expire_stamp']; } unset( $connection_data['auth_code'] ); return $connection_data; } /** * Validate the provided settings against the provider's field schema. * * @param array $schema The field definitions from the provider's options. * @param array $settings The submitted settings. * @return array ['success' => bool, 'message' => string] */ private function validate_schema_fields( array $schema, array $settings ) { foreach ( $schema as $field => $rules ) { if ( ! empty( $rules['required'] ) ) { $value = trim( $settings[ $field ] ?? '' ); if ( '' === $value ) { return [ 'success' => false, 'message' => __( 'Missing required field.', 'suremails' ), ]; } } } return [ 'success' => true ]; } /** * Prepare the connection data array based on the provider schema and submitted settings. * * Only fields defined in the schema are stored. * * @param array $schema The provider's field definitions. * @param array $settings The settings array from the request. * @return array The prepared connection data. */ private function prepare_connection_data( array $schema, array $settings ) { $data = []; foreach ( $schema as $field => $rules ) { if ( isset( $settings[ $field ] ) ) { $value = $settings[ $field ]; switch ( $rules['datatype'] ) { case 'email': $data[ $field ] = sanitize_email( $value ); break; case 'int': $data[ $field ] = intval( $value ); break; case 'boolean': $data[ $field ] = filter_var( $value, FILTER_VALIDATE_BOOLEAN ); break; case 'string': default: $data[ $field ] = sanitize_text_field( $value ); break; } } else { $data[ $field ] = ''; } } if ( isset( $settings['force_from_name'] ) && $settings['force_from_name'] ) { $data['force_from_name'] = ! empty( $data['from_name'] ); } if ( isset( $settings['force_from_email'] ) && $settings['force_from_email'] ) { $data['force_from_email'] = ! empty( $data['from_email'] ); } // ID is set for updatesss. $data['id'] = $settings['id'] ?? ''; return $data; } /** * Check if the desired priority is unique among existing connections. * * @param int $desired_priority The desired priority. * @param string $current_id The current connection ID (if updating). * @return bool True if unique, false otherwise. */ private function is_priority_unique( int $desired_priority, string $current_id ) { $all_connections = $this->get_all_connections(); foreach ( $all_connections as $existing_connection ) { if ( ! empty( $existing_connection['id'] ) && $existing_connection['id'] === $current_id ) { // Skip the current connection if updating. continue; } if ( intval( $existing_connection['priority'] ) === $desired_priority ) { return false; } } return true; } /** * Generates a unique ID for a connection. * * @param array $existing_connections The list of existing connections. * @return string The generated unique ID. */ private function generate_unique_id( array $existing_connections ) { do { $id = bin2hex( random_bytes( 16 ) ); // Generate a 32-character unique ID. } while ( $this->id_exists( $id, $existing_connections ) ); return $id; } /** * Checks if a connection ID already exists. * * @param string $id The ID to check. * @param array $existing_connections The existing connections. * @return bool True if exists, false otherwise. */ private function id_exists( string $id, array $existing_connections ) { foreach ( $existing_connections as $connection ) { if ( isset( $connection['id'] ) && $connection['id'] === $id ) { return true; } } return false; } /** * Encrypt sensitive data. * * @param string $data The data to encrypt. * @return string The encrypted data. */ private function encrypt( string $data ) { // Implement your encryption logic here. return $data; } } // Initialize the SaveTestConnection singleton. SaveTestConnection::instance();
Copyright ©2021 || Defacer Indonesia