get_error_message() : __( 'Your shop is connected to Eazign.', 'eazign' ) ); wp_safe_redirect( admin_url( 'admin.php?page=eazign' ) ); exit; } /** * Disconnect button. */ public static function handle_disconnect() { if ( ! current_user_can( 'manage_woocommerce' ) ) { wp_die( esc_html__( 'Sorry, you are not allowed to do this.', 'eazign' ) ); } check_admin_referer( 'eazign_disconnect' ); self::disconnect(); Eazign_Admin::notice( 'success', __( 'Eazign is disconnected. Your Eazign data will be deleted in 48 hours.', 'eazign' ) ); wp_safe_redirect( admin_url( 'admin.php?page=eazign' ) ); exit; } /** * Copy of a connected shop (staging): forgets the connection here only. */ public static function handle_forget() { if ( ! current_user_can( 'manage_woocommerce' ) ) { wp_die( esc_html__( 'Sorry, you are not allowed to do this.', 'eazign' ) ); } check_admin_referer( 'eazign_forget_site' ); self::delete_api_key(); delete_option( Eazign_Client::OPTION ); Eazign_Admin::notice( 'success', __( 'The connection was removed on this site. The shop at the connected address stays connected.', 'eazign' ) ); wp_safe_redirect( admin_url( 'admin.php?page=eazign' ) ); exit; } /** * Registers the site (once) and hands a fresh REST key to the service. * * @param bool $retry Register again if the service no longer knows the site. * @return true|WP_Error */ public static function connect( $retry = true ) { if ( ! Eazign_Client::is_registered() ) { $registered = Eazign_Client::post( 'register', array( 'url' => home_url(), 'name' => get_bloginfo( 'name' ), 'email' => get_option( 'admin_email' ), 'locale' => get_locale(), 'currency' => get_woocommerce_currency(), ), array( 'signed' => false ) ); if ( is_wp_error( $registered ) ) { return $registered; } update_option( Eazign_Client::OPTION, array( 'id' => sanitize_text_field( $registered['siteId'] ), 'secret' => sanitize_text_field( $registered['secret'] ), 'connected' => false, ), false ); } $key = self::create_api_key(); if ( is_wp_error( $key ) ) { return $key; } $result = Eazign_Client::post( 'keys', array( 'consumerKey' => $key['consumer_key'], 'consumerSecret' => $key['consumer_secret'], ), array( 'timeout' => 60 ) ); if ( is_wp_error( $result ) && $retry && 401 === ( $result->get_error_data()['status'] ?? 0 ) ) { // Registrations that never connected are removed after a day. self::delete_api_key(); delete_option( Eazign_Client::OPTION ); return self::connect( false ); } if ( is_wp_error( $result ) ) { return $result; } $site = Eazign_Client::site(); $site['connected'] = true; update_option( Eazign_Client::OPTION, $site, false ); return true; } /** * Tells the service to forget the site and removes the REST key. */ public static function disconnect() { if ( Eazign_Client::is_registered() ) { Eazign_Client::post( 'disconnect' ); } self::delete_api_key(); delete_option( Eazign_Client::OPTION ); } /** * Creates a read/write REST key for the current user, like WooCommerce's * own key authorization (WC_Auth::create_keys). It is listed and can be * revoked under WooCommerce → Settings → Advanced → REST API. * * @return array|WP_Error consumer_key and consumer_secret. */ private static function create_api_key() { global $wpdb; self::delete_api_key(); $consumer_key = 'ck_' . wc_rand_hash(); $consumer_secret = 'cs_' . wc_rand_hash(); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- WooCommerce keeps REST keys in its own table without an API for this. $inserted = $wpdb->insert( $wpdb->prefix . 'woocommerce_api_keys', array( 'user_id' => get_current_user_id(), 'description' => 'Eazign', 'permissions' => 'read_write', 'consumer_key' => wc_api_hash( $consumer_key ), 'consumer_secret' => $consumer_secret, 'truncated_key' => substr( $consumer_key, -7 ), ), array( '%d', '%s', '%s', '%s', '%s', '%s' ) ); if ( ! $inserted ) { return new WP_Error( 'eazign_key', __( 'Could not create the WooCommerce REST API key.', 'eazign' ) ); } update_option( self::KEY_OPTION, (int) $wpdb->insert_id, false ); return array( 'consumer_key' => $consumer_key, 'consumer_secret' => $consumer_secret, ); } /** * Removes the key created by create_api_key(). */ private static function delete_api_key() { global $wpdb; $key_id = (int) get_option( self::KEY_OPTION ); if ( $key_id ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- WooCommerce has no API to delete one REST key. $wpdb->delete( $wpdb->prefix . 'woocommerce_api_keys', array( 'key_id' => $key_id ), array( '%d' ) ); delete_option( self::KEY_OPTION ); } } }