From 3151fa33659dfc9c18ad6cd39768db1d1cbcbbad Mon Sep 17 00:00:00 2001 From: George Gecewicz Date: Wed, 13 Nov 2019 20:50:43 -0500 Subject: [PATCH 01/15] add DS_Store to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 134a1c98..56c3ea39 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +**/.DS_Store /vendor/* /node_modules/* .nvimrc From e947d477f7c13ad176e7058d7215525e94119155 Mon Sep 17 00:00:00 2001 From: George Gecewicz Date: Wed, 13 Nov 2019 20:51:02 -0500 Subject: [PATCH 02/15] remove V1 namespace strucutre and token-generation code --- src/Ajax/GenerateSecretKey.php | 61 ------- src/Plugin.php | 6 +- .../{V1 => }/Endpoints/AbandonedCarts.php | 0 src/Rest/Registrar.php | 44 +++++ src/Rest/V1/AuthHandler.php | 154 ------------------ src/Rest/V1/Endpoints/GetToken.php | 126 -------------- src/Rest/V1/Registrar.php | 54 ------ 7 files changed, 45 insertions(+), 400 deletions(-) delete mode 100644 src/Ajax/GenerateSecretKey.php rename src/Rest/{V1 => }/Endpoints/AbandonedCarts.php (100%) create mode 100644 src/Rest/Registrar.php delete mode 100644 src/Rest/V1/AuthHandler.php delete mode 100644 src/Rest/V1/Endpoints/GetToken.php delete mode 100644 src/Rest/V1/Registrar.php diff --git a/src/Ajax/GenerateSecretKey.php b/src/Ajax/GenerateSecretKey.php deleted file mode 100644 index ed99b258..00000000 --- a/src/Ajax/GenerateSecretKey.php +++ /dev/null @@ -1,61 +0,0 @@ -> - * @since 2019-10-24 - */ - public function register_hooks() { - add_action( 'wp_ajax_cc_woo_abandoned_carts_generate_secret_key', [ $this, 'generate_secret_key' ] ); - } - - /** - * Generates a new secret key. - * - * @author George Gecewicz > - * @since 2019-10-24 - */ - public function generate_secret_key() { - $nonce = filter_input( INPUT_POST, 'nonce', FILTER_SANITIZE_STRING ); - - if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'cc-woo-abandoned-cart-generate-secret-key' ) ) { - wp_send_json_error( - [ - 'key' => null, - 'message' => esc_html__( 'Invalid nonce.', 'cc-woo' ), - ] - ); - } - - $secret_key = wp_generate_password( 64, true, true ); - - update_option( 'cc_woo_abandoned_carts_secret_key', $secret_key ); - - wp_send_json_success( - [ - 'key' => $secret_key, - 'message' => esc_html__( 'Success!', 'cc-woo' ), - ] - ); - } - -} diff --git a/src/Plugin.php b/src/Plugin.php index 4d339ea0..01e7229a 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -21,9 +21,7 @@ use WebDevStudios\CCForWoo\AbandonedCarts\CartHandler; use WebDevStudios\CCForWoo\AbandonedCarts\CartsTable; use WebDevStudios\CCForWoo\AbandonedCarts\CartRecovery; -use WebDevStudios\CCForWoo\Ajax\GenerateSecretKey; -use WebDevStudios\CCForWoo\Rest\V1\Registrar as RestRegistrar; -use WebDevStudios\CCForWoo\Rest\V1\AuthHandler as RestAuthHandler; +use WebDevStudios\CCForWoo\Rest\Registrar as RestRegistrar; /** * "Core" plugin class. @@ -79,8 +77,6 @@ final class Plugin extends ServiceRegistrar { CartsTable::class, CartRecovery::class, RestRegistrar::class, - RestAuthHandler::class, - GenerateSecretKey::class, ]; /** diff --git a/src/Rest/V1/Endpoints/AbandonedCarts.php b/src/Rest/Endpoints/AbandonedCarts.php similarity index 100% rename from src/Rest/V1/Endpoints/AbandonedCarts.php rename to src/Rest/Endpoints/AbandonedCarts.php diff --git a/src/Rest/Registrar.php b/src/Rest/Registrar.php new file mode 100644 index 00000000..b0ee032f --- /dev/null +++ b/src/Rest/Registrar.php @@ -0,0 +1,44 @@ + + * @package WebDevStudios\CCForWoo\Rest + * @since 2019-11-13 + */ + +namespace WebDevStudios\CCForWoo\Rest; + +use WebDevStudios\OopsWP\Structure\Service; + +/** + * Class Registrar + * + * @author George Gecewicz + * @package WebDevStudios\CCForWoo\Rest + * @since 2019-11-13 + */ +class Registrar extends Service { + + /** + * Register hooks. + * + * @author George Gecewicz + * @since 2019-11-13 + */ + public function register_hooks() { + add_action( 'rest_api_init', [ $this, 'init_rest_endpoints' ] ); + } + + /** + * Initialize REST endpoints. + * + * @author George Gecewicz + * @since 2019-11-13 + */ + public function init_rest_endpoints() { + ( new Endpoints\AbandonedCarts() )->register_routes(); + } + +} + diff --git a/src/Rest/V1/AuthHandler.php b/src/Rest/V1/AuthHandler.php deleted file mode 100644 index 574027ae..00000000 --- a/src/Rest/V1/AuthHandler.php +++ /dev/null @@ -1,154 +0,0 @@ - - * @package WebDevStudios\CCForWoo\Rest\V1 - * @since 2019-10-25 - */ - -namespace WebDevStudios\CCForWoo\Rest\V1; - -use WebDevStudios\OopsWP\Structure\Service; -use Firebase\JWT\JWT; -use Firebase\JWT\SignatureInvalidException; -use Firebase\JWT\ExpiredException; - -use WP_Error; -use WP_REST_Request; - -/** - * Class AuthHandler - * - * @author George Gecewicz - * @package WebDevStudios\CCForWoo\Rest\V1 - * @since 2019-10-25 - */ -class AuthHandler extends Service { - - /** - * Stores the fact of failed token validation. - * - * @since 2019-10-25 - * - * @var null|WP_Error - */ - private $auth_error = null; - - /** - * Register hooks. - * - * @author George Gecewicz - * @since 2019-10-25 - */ - public function register_hooks() { - add_filter( 'rest_pre_dispatch', [ $this, 'rest_pre_dispatch' ], 10, 2 ); - add_filter( 'determine_current_user', [ $this, 'determine_current_user' ], 10 ); - } - - /** - * Attempts to authenticate user based on the provided token. - * - * @author George Gecewicz - * @since 2019-10-25 - * - * @param WP_User $user A WP User. - * @return WP_User|int WP_User of the user by default, otherwise the int of token's User ID if verified. - */ - public function determine_current_user( $user ) { - // Only require tokens on cc-woo/v1 API requests that aren't the actual token-retrieval endpoint. - $is_cc_woo_endpoint = strpos( $_SERVER['REQUEST_URI'], 'cc-woo/v1' ); - $is_cc_woo_token_endpoint = strpos( $_SERVER['REQUEST_URI'], 'cc-woo/v1/get-token' ); - - if ( ! $is_cc_woo_endpoint || $is_cc_woo_token_endpoint ) { - return $user; - } - - $token = $this->validate_token(); - - if ( is_wp_error( $token ) ) { - $this->auth_error = $token; - return $user; - } - - return $token->data->user->id; - } - - /** - * Validates requests by validating existience of auth headers, token, and that token is valid. - * - * Much of this taken from the JWT for WP REST API plugin by Enrique Chavez. - * - * @author George Gecewicz - * @since 2019-10-25 - * - * @return WP_User|object|array - */ - public function validate_token() { - $auth = isset( $_SERVER['HTTP_AUTHORIZATION'] ) ? $_SERVER['HTTP_AUTHORIZATION'] : false; - - if ( ! $auth ) { - $auth = isset( $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ) ? $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] : false; - } - - if ( ! $auth ) { - return new WP_Error( 'cc-woo-rest-no-auth-header', esc_html__( 'Authorization header not found.', 'cc-woo' ), [ 'status' => 403 ] ); - } - - // The HTTP_AUTHORIZATION is present; now verify the format and presence of actual token. - list( $token ) = sscanf( $auth, 'Bearer %s' ); - - if ( ! $token ) { - return new WP_Error( 'cc-woo-rest-malformed-auth-header', esc_html__( 'Authorization header malformed.', 'cc-woo' ), [ 'status' => 403 ] ); - } - - $secret_key = get_option( 'cc_woo_abandoned_carts_secret_key', false ); - - if ( ! $secret_key ) { - return new WP_Error( 'cc-woo-rest-auth-config-error', esc_html__( 'Could not authenticate: Not configured properly.', 'cc-woo' ), [ 'status' => 403 ] ); - } - - try { - - $token = JWT::decode( $token, $secret_key, [ 'HS256' ] ); - - if ( get_bloginfo( 'url' ) !== $token->iss ) { - return new WP_Error( 'cc-woo-rest-auth-bad-request', esc_html__( 'Could not validate token iss.', 'cc-woo' ), [ 'status' => 403 ] ); - } - - if ( ! isset( $token->data->user->id ) ) { - return new WP_Error( 'cc-woo-rest-auth-bad-request', esc_html__( 'Could not validate token user ID.', 'cc-woo' ), [ 'status' => 403 ] ); - } - - return $token; - - } catch ( ExpiredException $e ) { - // Handles if the token has expired. - return new WP_Error( 'cc-woo-rest-auth-expired-token', $e->getMessage(), [ 'status' => 403 ] ); - } catch ( SignatureInvalidException $e ) { - // Handles if the signing key changed since time token was issued. - return new WP_Error( 'cc-woo-rest-auth-invalid-key', $e->getMessage(), [ 'status' => 403 ] ); - } catch ( Exception $e ) { - return new WP_Error( 'cc-woo-rest-auth-invalid-token', $e->getMessage(), [ 'status' => 403 ] ); - } - } - - /** - * Before request is rendered, verify auth. Invalid auth will be a WP_Error of some kind. - * - * @author George Gecewicz - * @since 2019-10-25 - * - * @param WP_REST_Request $request The REST request. - * @return WP_REST_Request|WP_Error - */ - public function rest_pre_dispatch( $request ) { - if ( is_wp_error( $this->auth_error ) ) { - return $this->auth_error; - } - - return $request; - } - -} - diff --git a/src/Rest/V1/Endpoints/GetToken.php b/src/Rest/V1/Endpoints/GetToken.php deleted file mode 100644 index 935a96fe..00000000 --- a/src/Rest/V1/Endpoints/GetToken.php +++ /dev/null @@ -1,126 +0,0 @@ - - * @package WebDevStudios\CCForWoo\Rest\V1 - * @since 2019-10-24 - */ - -namespace WebDevStudios\CCForWoo\Rest\V1\Endpoints; - -use WP_REST_Server; -use WP_REST_Request; -use WP_REST_Controller; -use WP_REST_Response; -use WP_Error; - -use Firebase\JWT\JWT; -use WebDevStudios\CCForWoo\Rest\V1\Registrar; - -/** - * Class GetToken - * - * @author George Gecewicz - * @package WebDevStudios\CCForWoo\Rest\V1 - * @since 2019-10-24 - */ -class GetToken extends WP_REST_Controller { - - /** - * This endpoint's rest base. - * - * @since 2019-10-24 - * - * @var string - */ - protected $rest_base; - - /** - * Constructor. - * - * @author George Gecewicz - * @since 2019-10-24 - */ - public function __construct() { - $this->rest_base = 'get-token'; - } - - /** - * Register the GetToken REST route. - * - * @author George Gecewicz - * @since 2019-10-24 - */ - public function register_routes() { - register_rest_route( - Registrar::$namespace, '/' . $this->rest_base, - [ - [ - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => [ $this, 'get_token' ], - ], - 'schema' => null, - ] - ); - } - - /** - * Register the Abandoned Carts endpoint. - * - * @author George Gecewicz - * @since 2019-10-24 - * - * @param WP_REST_Request $request The REST request. - * @return WP_REST_Response - */ - public function get_token( $request ) { - if ( ! $this->get_secret_key() ) { - return new WP_Error( 'cc-woo-rest-auth-config-error', esc_html__( 'Could not authenticate: Not configured properly.', 'cc-woo' ), [ 'status' => 403 ] ); - } - - $params = $request->get_json_params(); - $user = wp_authenticate( $params['username'], $params['password'] ); - - if ( is_wp_error( $user ) ) { - return new WP_Error( 'cc-woo-rest-invalid-user-error', $user->get_error_message( $user->get_error_code() ), [ 'status' => 403 ] ); - } - - if ( ! user_can( $user->ID, 'administrator' ) ) { - return new WP_Error( 'cc-woo-rest-unauthorized-user-error', esc_html__( 'Could not authenticate: Insufficient permissions.', 'cc-woo' ), [ 'status' => 403 ] ); - } - - $current_time = time(); - $expiration = time() + ( 15 * MINUTE_IN_SECONDS ); - - $token_body = [ - 'iss' => get_bloginfo( 'url' ), - 'iat' => $current_time, - 'nbf' => $current_time, - 'exp' => $expiration, - 'data' => [ - 'user' => [ - 'id' => $user->data->ID, - ], - ], - ]; - - $token = JWT::encode( $token_body, $this->get_secret_key() ); - - return new WP_REST_Response( [ 'token' => $token ], 200 ); - } - - /** - * Gets the secret key. - * - * @author George Gecewicz - * @since 2019-10-24 - * - * @return mixed String of the secret key if exists AND valid; bool false if not either. - */ - private function get_secret_key() { - return get_option( 'cc_woo_abandoned_carts_secret_key', false ); - } - -} - diff --git a/src/Rest/V1/Registrar.php b/src/Rest/V1/Registrar.php deleted file mode 100644 index e17b4ace..00000000 --- a/src/Rest/V1/Registrar.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @package WebDevStudios\CCForWoo\Rest\V1 - * @since 2019-10-16 - */ - -namespace WebDevStudios\CCForWoo\Rest\V1; - -use WebDevStudios\OopsWP\Structure\Service; - -/** - * Class Registrar - * - * @author George Gecewicz - * @package WebDevStudios\CCForWoo\Rest\V1 - * @since 2019-10-16 - */ -class Registrar extends Service { - - /** - * Namespace for the endpoints this registrar registers. - * - * @since 2019-10-16 - * - * @var string - */ - public static $namespace = 'cc-woo/v1'; - - /** - * Register hooks. - * - * @author George Gecewicz - * @since 2019-10-16 - */ - public function register_hooks() { - add_action( 'rest_api_init', [ $this, 'init_rest_endpoints' ] ); - } - - /** - * Initialize REST endpoints. - * - * @author George Gecewicz - * @since 2019-10-16 - */ - public function init_rest_endpoints() { - ( new Endpoints\GetToken() )->register_routes(); - ( new Endpoints\AbandonedCarts() )->register_routes(); - } - -} - From d0784181bd411cc5234d960ba5cbf4496e87ae54 Mon Sep 17 00:00:00 2001 From: George Gecewicz Date: Wed, 13 Nov 2019 20:55:28 -0500 Subject: [PATCH 03/15] removing remaining admin-facing classes related to old auth methods --- composer.lock | 266 +++++++++--------- src/Rest/Endpoints/AbandonedCarts.php | 6 +- .../Field/AbandonedCarts/ApiSecretKey.php | 77 ----- .../Admin/Field/AbandonedCarts/ServerInfo.php | 98 ------- src/View/Admin/WooTab.php | 11 - 5 files changed, 138 insertions(+), 320 deletions(-) delete mode 100644 src/View/Admin/Field/AbandonedCarts/ApiSecretKey.php delete mode 100644 src/View/Admin/Field/AbandonedCarts/ServerInfo.php diff --git a/composer.lock b/composer.lock index 5f2140a7..44317ca9 100644 --- a/composer.lock +++ b/composer.lock @@ -8,16 +8,16 @@ "packages": [ { "name": "composer/installers", - "version": "v1.6.0", + "version": "v1.7.0", "source": { "type": "git", "url": "https://github.com/composer/installers.git", - "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b" + "reference": "141b272484481432cda342727a427dc1e206bfa0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/installers/zipball/cfcca6b1b60bc4974324efb5783c13dca6932b5b", - "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b", + "url": "https://api.github.com/repos/composer/installers/zipball/141b272484481432cda342727a427dc1e206bfa0", + "reference": "141b272484481432cda342727a427dc1e206bfa0", "shasum": "" }, "require": { @@ -73,6 +73,7 @@ "RadPHP", "SMF", "Thelia", + "Whmcs", "WolfCMS", "agl", "aimeos", @@ -95,6 +96,7 @@ "installer", "itop", "joomla", + "known", "kohana", "laravel", "lavalite", @@ -124,7 +126,7 @@ "zend", "zikula" ], - "time": "2018-08-27T06:10:37+00:00" + "time": "2019-08-12T15:00:31+00:00" }, { "name": "firebase/php-jwt", @@ -217,12 +219,12 @@ "source": { "type": "git", "url": "https://github.com/10up/wp_mock.git", - "reference": "9019226eb50df275aa86bb15bfc98a619601ee49" + "reference": "9927f0c2600d2537e53ac7b17856891ab61dfb36" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/10up/wp_mock/zipball/9019226eb50df275aa86bb15bfc98a619601ee49", - "reference": "9019226eb50df275aa86bb15bfc98a619601ee49", + "url": "https://api.github.com/repos/10up/wp_mock/zipball/9927f0c2600d2537e53ac7b17856891ab61dfb36", + "reference": "9927f0c2600d2537e53ac7b17856891ab61dfb36", "shasum": "" }, "require": { @@ -250,25 +252,28 @@ "GPL-2.0-or-later" ], "description": "A mocking library to take the pain out of unit testing for WordPress", - "time": "2019-03-16T03:44:39+00:00" + "time": "2019-09-16T18:03:59+00:00" }, { "name": "antecedent/patchwork", - "version": "2.1.8", + "version": "2.1.11", "source": { "type": "git", "url": "https://github.com/antecedent/patchwork.git", - "reference": "3bb81ace3914c220aa273d1c0603d5e1b454c0d7" + "reference": "ff7aae02f1c5492716fe13d59de4cfc389b8c4b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/antecedent/patchwork/zipball/3bb81ace3914c220aa273d1c0603d5e1b454c0d7", - "reference": "3bb81ace3914c220aa273d1c0603d5e1b454c0d7", + "url": "https://api.github.com/repos/antecedent/patchwork/zipball/ff7aae02f1c5492716fe13d59de4cfc389b8c4b0", + "reference": "ff7aae02f1c5492716fe13d59de4cfc389b8c4b0", "shasum": "" }, "require": { "php": ">=5.4.0" }, + "require-dev": { + "phpunit/phpunit": ">=4" + }, "type": "library", "notification-url": "https://packagist.org/downloads/", "license": [ @@ -291,31 +296,33 @@ "runkit", "testing" ], - "time": "2018-02-19T18:52:50+00:00" + "time": "2019-10-26T07:10:56+00:00" }, { "name": "doctrine/instantiator", - "version": "1.1.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + "reference": "ae466f726242e637cebdd526a7d991b9433bacf1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1", + "reference": "ae466f726242e637cebdd526a7d991b9433bacf1", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { - "athletic/athletic": "~0.1.8", + "doctrine/coding-standard": "^6.0", "ext-pdo": "*", "ext-phar": "*", - "phpunit/phpunit": "^6.2.3", - "squizlabs/php_codesniffer": "^3.0.2" + "phpbench/phpbench": "^0.13", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-shim": "^0.11", + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { @@ -340,12 +347,12 @@ } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", "keywords": [ "constructor", "instantiate" ], - "time": "2017-07-22T11:58:36+00:00" + "time": "2019-10-21T16:45:58+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -397,16 +404,16 @@ }, { "name": "mockery/mockery", - "version": "1.2.2", + "version": "1.2.4", "source": { "type": "git", "url": "https://github.com/mockery/mockery.git", - "reference": "0eb0b48c3f07b3b89f5169ce005b7d05b18cf1d2" + "reference": "b3453f75fd23d9fd41685f2148f4abeacabc6405" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mockery/mockery/zipball/0eb0b48c3f07b3b89f5169ce005b7d05b18cf1d2", - "reference": "0eb0b48c3f07b3b89f5169ce005b7d05b18cf1d2", + "url": "https://api.github.com/repos/mockery/mockery/zipball/b3453f75fd23d9fd41685f2148f4abeacabc6405", + "reference": "b3453f75fd23d9fd41685f2148f4abeacabc6405", "shasum": "" }, "require": { @@ -420,7 +427,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -458,20 +465,20 @@ "test double", "testing" ], - "time": "2019-02-13T09:37:52+00:00" + "time": "2019-09-30T08:30:27+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.8.1", + "version": "1.9.3", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8" + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", - "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea", + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea", "shasum": "" }, "require": { @@ -506,7 +513,7 @@ "object", "object graph" ], - "time": "2018-06-11T23:09:50+00:00" + "time": "2019-08-09T12:45:53+00:00" }, { "name": "phar-io/manifest", @@ -612,35 +619,33 @@ }, { "name": "phpdocumentor/reflection-common", - "version": "1.0.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", + "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", "shasum": "" }, "require": { - "php": ">=5.5" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^4.6" + "phpunit/phpunit": "~6" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] + "phpDocumentor\\Reflection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -662,30 +667,30 @@ "reflection", "static analysis" ], - "time": "2017-09-11T18:02:19+00:00" + "time": "2018-08-07T13:53:10+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.3.0", + "version": "4.3.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e", + "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e", "shasum": "" }, "require": { "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", + "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", + "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", "webmozart/assert": "^1.0" }, "require-dev": { - "doctrine/instantiator": "~1.0.5", + "doctrine/instantiator": "^1.0.5", "mockery/mockery": "^1.0", "phpunit/phpunit": "^6.4" }, @@ -713,41 +718,40 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-11-30T07:14:17+00:00" + "time": "2019-09-12T14:27:41+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "0.4.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", + "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" + "php": "^7.1", + "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" + "ext-tokenizer": "^7.1", + "mockery/mockery": "~1", + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -760,26 +764,27 @@ "email": "me@mikevanriel.com" } ], - "time": "2017-07-14T14:27:02+00:00" + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "time": "2019-08-22T18:11:29+00:00" }, { "name": "phpspec/prophecy", - "version": "1.8.0", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" + "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", - "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/f6811d96d97bdf400077a0cc100ae56aa32b9203", + "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", "sebastian/comparator": "^1.1|^2.0|^3.0", "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, @@ -794,8 +799,8 @@ } }, "autoload": { - "psr-0": { - "Prophecy\\": "src/" + "psr-4": { + "Prophecy\\": "src/Prophecy" } }, "notification-url": "https://packagist.org/downloads/", @@ -823,7 +828,7 @@ "spy", "stub" ], - "time": "2018-08-05T17:53:17+00:00" + "time": "2019-10-03T11:07:50+00:00" }, { "name": "phpunit/php-code-coverage", @@ -981,16 +986,16 @@ }, { "name": "phpunit/php-timer", - "version": "2.1.1", + "version": "2.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "8b389aebe1b8b0578430bda0c7c95a829608e059" + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b389aebe1b8b0578430bda0c7c95a829608e059", - "reference": "8b389aebe1b8b0578430bda0c7c95a829608e059", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", "shasum": "" }, "require": { @@ -1026,20 +1031,20 @@ "keywords": [ "timer" ], - "time": "2019-02-20T10:12:59+00:00" + "time": "2019-06-07T04:22:29+00:00" }, { "name": "phpunit/php-token-stream", - "version": "3.0.1", + "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18" + "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/c99e3be9d3e85f60646f152f9002d46ed7770d18", - "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff", + "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff", "shasum": "" }, "require": { @@ -1052,7 +1057,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -1075,20 +1080,20 @@ "keywords": [ "tokenizer" ], - "time": "2018-10-30T05:52:18+00:00" + "time": "2019-09-17T06:23:10+00:00" }, { "name": "phpunit/phpunit", - "version": "7.5.7", + "version": "7.5.17", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "eb343b86753d26de07ecba7868fa983104361948" + "reference": "4c92a15296e58191a4cd74cff3b34fc8e374174a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/eb343b86753d26de07ecba7868fa983104361948", - "reference": "eb343b86753d26de07ecba7868fa983104361948", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4c92a15296e58191a4cd74cff3b34fc8e374174a", + "reference": "4c92a15296e58191a4cd74cff3b34fc8e374174a", "shasum": "" }, "require": { @@ -1159,7 +1164,7 @@ "testing", "xunit" ], - "time": "2019-03-16T07:31:17+00:00" + "time": "2019-10-28T10:37:36+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -1328,16 +1333,16 @@ }, { "name": "sebastian/environment", - "version": "4.1.0", + "version": "4.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "6fda8ce1974b62b14935adc02a9ed38252eca656" + "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6fda8ce1974b62b14935adc02a9ed38252eca656", - "reference": "6fda8ce1974b62b14935adc02a9ed38252eca656", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/f2a2c8e1c97c11ace607a7a667d73d47c19fe404", + "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404", "shasum": "" }, "require": { @@ -1352,7 +1357,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -1377,20 +1382,20 @@ "environment", "hhvm" ], - "time": "2019-02-01T05:27:49+00:00" + "time": "2019-05-05T09:05:15+00:00" }, { "name": "sebastian/exporter", - "version": "3.1.0", + "version": "3.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", "shasum": "" }, "require": { @@ -1417,6 +1422,10 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -1425,17 +1434,13 @@ "name": "Volker Dusch", "email": "github@wallbash.com" }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, { "name": "Adam Harvey", "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], "description": "Provides the functionality to export PHP variables for visualization", @@ -1444,7 +1449,7 @@ "export", "exporter" ], - "time": "2017-04-03T13:19:02+00:00" + "time": "2019-09-14T09:02:43+00:00" }, { "name": "sebastian/global-state", @@ -1729,16 +1734,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.10.0", + "version": "v1.12.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "e3d826245268269cd66f8326bd8bc066687b4a19" + "reference": "550ebaac289296ce228a706d0867afc34687e3f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19", - "reference": "e3d826245268269cd66f8326bd8bc066687b4a19", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4", + "reference": "550ebaac289296ce228a706d0867afc34687e3f4", "shasum": "" }, "require": { @@ -1750,7 +1755,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.9-dev" + "dev-master": "1.12-dev" } }, "autoload": { @@ -1767,12 +1772,12 @@ ], "authors": [ { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" }, { - "name": "Gert de Pagter", - "email": "backendtea@gmail.com" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for ctype functions", @@ -1783,20 +1788,20 @@ "polyfill", "portable" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2019-08-06T08:03:45+00:00" }, { "name": "theseer/tokenizer", - "version": "1.1.0", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", + "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", "shasum": "" }, "require": { @@ -1823,20 +1828,20 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2017-04-07T12:08:54+00:00" + "time": "2019-06-13T22:48:21+00:00" }, { "name": "webmozart/assert", - "version": "1.4.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9" + "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9", - "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9", + "url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4", + "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4", "shasum": "" }, "require": { @@ -1844,8 +1849,7 @@ "symfony/polyfill-ctype": "^1.8" }, "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" + "phpunit/phpunit": "^4.8.36 || ^7.5.13" }, "type": "library", "extra": { @@ -1874,7 +1878,7 @@ "check", "validate" ], - "time": "2018-12-25T11:19:39+00:00" + "time": "2019-08-24T08:43:50+00:00" } ], "aliases": [], diff --git a/src/Rest/Endpoints/AbandonedCarts.php b/src/Rest/Endpoints/AbandonedCarts.php index 6526f009..9a1767a3 100644 --- a/src/Rest/Endpoints/AbandonedCarts.php +++ b/src/Rest/Endpoints/AbandonedCarts.php @@ -7,7 +7,7 @@ * @since 2019-10-16 */ -namespace WebDevStudios\CCForWoo\Rest\V1\Endpoints; +namespace WebDevStudios\CCForWoo\Rest\Endpoints; use WP_REST_Server; use WP_REST_Request; @@ -17,7 +17,7 @@ use WebDevStudios\CCForWoo\AbandonedCarts\CartsTable; use WebDevStudios\CCForWoo\AbandonedCarts\Cart; -use WebDevStudios\CCForWoo\Rest\V1\Registrar; +use WebDevStudios\CCForWoo\Rest\Registrar; /** * Class AbandonedCarts @@ -55,7 +55,7 @@ public function __construct() { */ public function register_routes() { register_rest_route( - Registrar::$namespace, '/' . $this->rest_base, + 'wc-' . $this->rest_base, [ [ 'methods' => WP_REST_Server::READABLE, diff --git a/src/View/Admin/Field/AbandonedCarts/ApiSecretKey.php b/src/View/Admin/Field/AbandonedCarts/ApiSecretKey.php deleted file mode 100644 index 9624cae4..00000000 --- a/src/View/Admin/Field/AbandonedCarts/ApiSecretKey.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @package cc-woo-view-admin-field - */ - -namespace WebDevStudios\CCForWoo\View\Admin\Field\AbandonedCarts; - -/** - * ApiSecretKey field class - * - * @since 2019-10-24 - * @author George Gecewicz - * @package cc-woo-view-admin-field - */ -class ApiSecretKey { - - /** - * Secret Key field. - * - * @since 2019-10-24 - * - * @var string - */ - const OPTION_FIELD_NAME = 'cc_woo_abandoned_carts_secret_key'; - - /** - * Returns the form field configuration. - * - * @since 2019-10-24 - * @author George Gecewicz - * - * @return array. - */ - public function get_form_field() : array { - return [ - 'title' => esc_html__( 'Secret Key', 'cc-woo' ), - 'desc' => $this->get_description(), - 'type' => 'text', - 'id' => self::OPTION_FIELD_NAME, - 'default' => '', - 'custom_attributes' => [ - 'readonly' => 'true', - ], - ]; - } - - /** - * Field description, where we actually just show the Generate Key button. - * - * @since 2019-10-24 - * @author George Gecewicz - * - * @return string - */ - private function get_description() : string { - ob_start(); - ?> -
- -

- -

-
- - * @package cc-woo-view-admin-field - */ - -namespace WebDevStudios\CCForWoo\View\Admin\Field\AbandonedCarts; - -/** - * AbandonedCarts\ServerInfo field class - * - * @since 2019-10-28 - * @author George Gecewicz - * @package cc-woo-view-admin-field - */ -class ServerInfo { - - /** - * Server Info field. - * - * @since 2019-10-28 - * - * @var string - */ - const OPTION_FIELD_NAME = 'cc_woo_abandoned_carts_server_info'; - - /** - * Returns the form field configuration. - * - * @since 2019-10-28 - * @author George Gecewicz - * - * @return array. - */ - public function get_form_field() : array { - return [ - 'title' => esc_html__( 'Server Information', 'cc-woo' ), - 'desc' => $this->get_description(), - 'type' => 'text', - 'id' => self::OPTION_FIELD_NAME, - 'default' => '', - 'custom_attributes' => [ - 'readonly' => 'true', - ], - ]; - } - - /** - * Field description. - * - * @since 2019-10-28 - * @author George Gecewicz - * - * @return string - */ - private function get_description() : string { - ob_start(); - ?> -
-

-

-

.htaccess

-

- .htaccess' - ); - ?> -

- - RewriteEngine on - RewriteCond %{HTTP:Authorization} ^(.*) - RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1] - -

apache.conf

-

- apache.conf', - 'apache2.conf' - ); - ?> -

- - SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 - -
- get_form_field() ); - $settings[] = array_merge( $settings, - $secret_key_field->get_form_field() - ); - - $settings[] = array_merge( - $settings, - $server_info_field->get_form_field() - ); - return $settings; } From 82ddd9ab18e26b73ca4b4b40d82a0d1bb2a9e7f4 Mon Sep 17 00:00:00 2001 From: George Gecewicz Date: Wed, 13 Nov 2019 22:08:06 -0500 Subject: [PATCH 04/15] add permissions check that inherits WC auth processes --- src/Rest/Endpoints/AbandonedCarts.php | 27 ++++- src/Rest/Registrar.php | 36 ++++++- .../Field/AbandonedCarts/RestEndpoints.php | 100 ------------------ src/View/Admin/WooTab.php | 47 +------- 4 files changed, 56 insertions(+), 154 deletions(-) delete mode 100644 src/View/Admin/Field/AbandonedCarts/RestEndpoints.php diff --git a/src/Rest/Endpoints/AbandonedCarts.php b/src/Rest/Endpoints/AbandonedCarts.php index 9a1767a3..1d925501 100644 --- a/src/Rest/Endpoints/AbandonedCarts.php +++ b/src/Rest/Endpoints/AbandonedCarts.php @@ -13,6 +13,7 @@ use WP_REST_Request; use WP_REST_Controller; use WP_REST_Response; +use WP_Error; use WC_Product; use WebDevStudios\CCForWoo\AbandonedCarts\CartsTable; @@ -55,17 +56,33 @@ public function __construct() { */ public function register_routes() { register_rest_route( - 'wc-' . $this->rest_base, + Registrar::$namespace, + '/' . $this->rest_base, [ [ - 'methods' => WP_REST_Server::READABLE, - 'callback' => [ $this, 'get_items' ], + 'methods' => WP_REST_Server::READABLE, + 'callback' => [ $this, 'get_items' ], + 'permission_callback' => [ $this, 'get_items_permissions_check' ], ], 'schema' => null, ] ); } + /** + * Check whether a given request has permission to show abandoned carts. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'cc-woo-rest-not-allowed', esc_html__( 'Sorry, you cannot list resources.', 'cc-woo' ), [ 'status' => rest_authorization_required_code() ] ); + } + + return true; + } + /** * Register the Abandoned Carts endpoint. * @@ -188,7 +205,7 @@ private function get_cart_data( int $per_page, int $offset, string $date_min, st ); // phpcs:enable WordPress.DB.PreparedSQL - return $this->prepare_cart_data_for_api( $data ); + return $this->prepare_cart_data_for_api_response( $data ); } /** @@ -230,7 +247,7 @@ private function get_dates_where( string $date_min, string $date_max ) : string * @param array $data The carts whose fields need preparation. * @return array */ - private function prepare_cart_data_for_api( array $data ) { + private function prepare_cart_data_for_api_response( array $data ) { foreach ( $data as $cart ) { $cart->cart_contents = maybe_unserialize( $cart->cart_contents ); $cart->cart_contents = $this->get_additional_product_fields( $cart->cart_contents ); diff --git a/src/Rest/Registrar.php b/src/Rest/Registrar.php index b0ee032f..9cab3318 100644 --- a/src/Rest/Registrar.php +++ b/src/Rest/Registrar.php @@ -20,6 +20,15 @@ */ class Registrar extends Service { + /** + * Namespace for the endpoints this registrar registers. + * + * @since 2019-10-16 + * + * @var string + */ + public static $namespace = 'wc/cc-woo'; + /** * Register hooks. * @@ -27,8 +36,9 @@ class Registrar extends Service { * @since 2019-11-13 */ public function register_hooks() { - add_action( 'rest_api_init', [ $this, 'init_rest_endpoints' ] ); - } + add_action( 'rest_api_init', [ $this, 'init_rest_endpoints' ] ); + add_filter( 'woocommerce_rest_is_request_to_rest_api', [ $this, 'register_endpoints_with_woo_auth_handler' ] ); + } /** * Initialize REST endpoints. @@ -38,7 +48,27 @@ public function register_hooks() { */ public function init_rest_endpoints() { ( new Endpoints\AbandonedCarts() )->register_routes(); - } + } + + /** + * Register REST endpoints with WooCommerce's REST auth handler. + * + * @author George Gecewicz + * @since 2019-11-13 + * + * @return bool + */ + public function register_endpoints_with_woo_auth_handler() { + $request_uri = esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ); + + if ( empty( $request_uri ) ) { + return false; + } + + $rest_prefix = trailingslashit( rest_get_url_prefix() ); + + return false !== strpos( $request_uri, $rest_prefix . self::$namespace ); + } } diff --git a/src/View/Admin/Field/AbandonedCarts/RestEndpoints.php b/src/View/Admin/Field/AbandonedCarts/RestEndpoints.php deleted file mode 100644 index 13cd2616..00000000 --- a/src/View/Admin/Field/AbandonedCarts/RestEndpoints.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @package cc-woo-view-admin-field - */ - -namespace WebDevStudios\CCForWoo\View\Admin\Field\AbandonedCarts; - -/** - * RestEndpoints field class - * - * @since 2019-10-28 - * @author George Gecewicz - * @package cc-woo-view-admin-field - */ -class RestEndpoints { - - /** - * Rest Endpoints field. - * - * @since 2019-10-28 - * - * @var string - */ - const OPTION_FIELD_NAME = 'cc_woo_abandoned_carts_rest_endpoints'; - - /** - * Returns the form field configuration. - * - * @since 2019-10-28 - * @author George Gecewicz - * - * @return array. - */ - public function get_form_field() : array { - return [ - 'title' => esc_html__( 'REST Endpoints', 'cc-woo' ), - 'desc' => $this->get_description(), - 'type' => 'text', - 'id' => self::OPTION_FIELD_NAME, - 'default' => '', - 'custom_attributes' => [ - 'readonly' => 'true', - ], - ]; - } - - /** - * Field description, where we actually just show the Generate Key button. - * - * @since 2019-10-24 - * @author George Gecewicz - * - * @return string - */ - private function get_description() : string { - ob_start(); - ?> -
-

-
- get_abandoned_carts_endpoint_url() ); ?> -

-

-
- get_get_token_endpoint_url() ); ?> -

-
- - * - * @return string - */ - private function get_abandoned_carts_endpoint_url() : string { - return sprintf( '%1$s/wp-json/cc-woo/v1/abandoned-carts', get_home_url() ); - } - - /** - * Get URL to getToken endpoint. - * - * @since 2019-10-28 - * @author George Gecewicz - * - * @return string - */ - private function get_get_token_endpoint_url() : string { - return sprintf( '%1$s/wp-json/cc-woo/v1/get-token', get_home_url() ); - } - -} diff --git a/src/View/Admin/WooTab.php b/src/View/Admin/WooTab.php index 0b78554d..f31f7b89 100644 --- a/src/View/Admin/WooTab.php +++ b/src/View/Admin/WooTab.php @@ -124,14 +124,6 @@ class WooTab extends WC_Settings_Page implements Hookable { */ private $import_existing_customer_section = 'customer_data_import'; - /** - * The identifier for the Abandoned Carts section. - * - * @since 2019-10-24 - * @var string - */ - private $abandoned_carts_section = 'abandoned_carts'; - /** * WooTab constructor. * @@ -207,7 +199,6 @@ public function get_sections() { $sections = [ '' => esc_html__( 'Store Information', 'cc-woo' ), $this->import_existing_customer_section => esc_html__( 'Import your contacts', 'cc-woo' ), - $this->abandoned_carts_section => esc_html__( 'Abandoned Carts', 'cc-woo' ), ]; return apply_filters( 'woocommerce_get_sections_' . $this->id, $sections ); @@ -280,10 +271,6 @@ private function get_default_settings_options() { case $this->import_existing_customer_section: $settings = $this->get_customer_data_settings(); break; - - case $this->abandoned_carts_section: - $settings = $this->get_abandoned_carts_settings(); - break; } $settings = $this->process_errors( $settings ); @@ -306,8 +293,7 @@ public function add_rest_group( $groups ) { $groups[] = [ 'id' => 'cc_woo', 'label' => esc_html__( 'Constant Contact WooCommerce', 'cc-woo' ), - 'description' => esc_html__( 'This endpoint provides information for the Constant Contact for WooCommerce plugin.', - 'cc-woo' ), + 'description' => esc_html__( 'This endpoint provides information for the Constant Contact for WooCommerce plugin.', 'cc-woo' ), ]; return $groups; @@ -546,37 +532,6 @@ private function get_customer_data_settings() { return $settings; } - /** - * Get the Abandoned Carts settings. - * - * @since 2019-10-24 - * @author George Gecewicz - * - * @return array - */ - private function get_abandoned_carts_settings() { - $settings = [ - [ - 'title' => esc_html__( 'Abandoned Cart Settings', 'cc-woo' ), - 'id' => 'cc_woo_abandoned_cart_settings', - 'type' => 'title', - ], - [ - 'title' => '', - 'type' => 'title', - 'desc' => esc_html__( 'Settings for the Abandoned Carts functionality, namely its REST API endpoint.', 'cc-woo' ), - ], - ]; - - $rest_endpoints_field = new \WebDevStudios\CCForWoo\View\Admin\Field\AbandonedCarts\RestEndpoints(); - - $settings[] = array_merge( $settings, - $rest_endpoints_field->get_form_field() - ); - - return $settings; - } - /** * Displays the Constant Contact connection button when the form is validated and a connection is not already established. * From 0b876f7d0d5ffdb6e08da0aa1d51de68366b7c84 Mon Sep 17 00:00:00 2001 From: George Gecewicz Date: Thu, 14 Nov 2019 10:36:20 -0500 Subject: [PATCH 05/15] fleshing out the AbandonedCarts endpoint schema --- src/Rest/Endpoints/AbandonedCarts.php | 246 +++++++++++++++++++++++++- src/Rest/Registrar.php | 2 +- 2 files changed, 246 insertions(+), 2 deletions(-) diff --git a/src/Rest/Endpoints/AbandonedCarts.php b/src/Rest/Endpoints/AbandonedCarts.php index 1d925501..951cad22 100644 --- a/src/Rest/Endpoints/AbandonedCarts.php +++ b/src/Rest/Endpoints/AbandonedCarts.php @@ -63,8 +63,9 @@ public function register_routes() { 'methods' => WP_REST_Server::READABLE, 'callback' => [ $this, 'get_items' ], 'permission_callback' => [ $this, 'get_items_permissions_check' ], + 'args' => $this->get_collection_params(), ], - 'schema' => null, + 'schema' => [ $this, 'get_public_item_schema' ], ] ); } @@ -341,5 +342,248 @@ private function get_product_image_url( WC_Product $wc_product ) : string { return wp_get_attachment_url( $wc_product->get_image_id() ); } + /** + * Get the Abandoned Cart's schema for public consumption. + * + * @return array + */ + public function get_item_schema() { + return [ + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'cc_woo_abandoned_cart', + 'type' => 'object', + 'properties' => [ + 'cart_id' => [ + 'description' => esc_html__( 'Database ID for the abandoned cart.', 'cc-woo' ), + 'type' => 'integer', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'user_id' => [ + 'description' => esc_html__( 'WordPress user ID of the user the cart belongs to; defaults to 0 if a guest or non-logged-in user.', 'cc-woo' ), + 'type' => 'integer', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'user_email' => [ + 'description' => esc_html__( 'The billing email the user entered at checkout before abandoning it. Note that this may be different than the email address the user has in their WordPress user profile.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_contents' => [ + 'description' => esc_html__( 'Object representation of the cart that was abandoned, and its contents, coupon codes, and billing data.', 'cc-woo' ), + 'type' => 'object', + 'context' => [ 'view' ], + 'readonly' => true, + 'properties' => [ + 'products' => [ + 'description' => esc_html__( 'Key-value listing of products in the cart. Keys are unique WooCommerce-generated keys identifying the cart in the database; values are objects representing the items in the cart.', 'cc-woo' ), + 'type' => 'array', + 'context' => [ 'view' ], + 'readonly' => true, + 'properties' => [ + [ + 'key' => [ + 'description' => esc_html__( 'Unique WooCommerce-generated key identifying the cart in the database. This differs from the parent-level cart_hash property.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'product_id' => [ + 'description' => esc_html__( 'The WooCommerce product ID.', 'cc-woo' ), + 'type' => 'integer', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'variation_id' => [ + 'description' => esc_html__( 'The WooCommerce product variation ID, if applicable.', 'cc-woo' ), + 'type' => 'integer', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'variation' => [ + 'description' => esc_html__( 'Object representation of any applicable variations, where keys are variation names and values are the actual variation selection.', 'cc-woo' ), + 'type' => 'object', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'quantity' => [ + 'description' => esc_html__( 'Item quantity.', 'cc-woo' ), + 'type' => 'integer', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'data_hash' => [ + 'description' => esc_html__( 'MD5 hash of cart items to determine if contents are modified.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'line_tax_data' => [ + 'description' => esc_html__( 'Line subtotal tax and total tax data.', 'cc-woo' ), + 'type' => 'object', + 'context' => [ 'view' ], + 'readonly' => true, + 'properties' => [ + 'subtotal' => [ + 'description' => esc_html__( 'Line subtotal tax data.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'total' => [ + 'description' => esc_html__( 'Line total tax data.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + ] + ], + 'line_subtotal' => [ + 'description' => esc_html__( 'Line subtotal.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'line_subtotal_tax' => [ + 'description' => esc_html__( 'Line subtotal tax.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'line_total' => [ + 'description' => esc_html__( 'Line total.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'line_tax' => [ + 'description' => esc_html__( 'Line total tax.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'data' => [ + 'description' => esc_html__( 'Misc. product data in key-value pairs.', 'cc-woo' ), + 'type' => 'object', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'product_title' => [ + 'description' => esc_html__( 'The product title.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'product_sku' => [ + 'description' => esc_html__( 'The product SKU.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'product_permalink' => [ + 'description' => esc_html__( 'Permalink to the product page.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'product_image_url' => [ + 'description' => esc_html__( 'URL to the full-size featured image for the product if one exists.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ] + ] + ] + ], + 'coupons' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + ], + ], + 'cart_updated' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_updated_ts' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_created' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_created_ts' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_hash' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_subtotal' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_total' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_subtotal_tax' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_total_tax' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_recovery_url' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + ] + ]; + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for Abandoned Carts. + * + * @return array + */ + public function get_collection_params() { + return [ + 'page' => [], + 'per_page' => [], + 'date_min' => [], + 'date_max' => [], + ]; + } + } diff --git a/src/Rest/Registrar.php b/src/Rest/Registrar.php index 9cab3318..b2d61f06 100644 --- a/src/Rest/Registrar.php +++ b/src/Rest/Registrar.php @@ -51,7 +51,7 @@ public function init_rest_endpoints() { } /** - * Register REST endpoints with WooCommerce's REST auth handler. + * Register REST endpoints with wc/cc-woo namespace with WooCommerce's REST auth handler. * * @author George Gecewicz * @since 2019-11-13 From 6444e1fdc1c857867bb4f1968faa126d425a6ff7 Mon Sep 17 00:00:00 2001 From: George Gecewicz Date: Thu, 14 Nov 2019 10:42:33 -0500 Subject: [PATCH 06/15] restructure Rest classes directory --- .../Controller.php} | 10 +++++----- src/Rest/AbandonedCarts/Schema.php | 0 src/Rest/Registrar.php | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) rename src/Rest/{Endpoints/AbandonedCarts.php => AbandonedCarts/Controller.php} (98%) create mode 100644 src/Rest/AbandonedCarts/Schema.php diff --git a/src/Rest/Endpoints/AbandonedCarts.php b/src/Rest/AbandonedCarts/Controller.php similarity index 98% rename from src/Rest/Endpoints/AbandonedCarts.php rename to src/Rest/AbandonedCarts/Controller.php index 951cad22..447f4d01 100644 --- a/src/Rest/Endpoints/AbandonedCarts.php +++ b/src/Rest/AbandonedCarts/Controller.php @@ -3,11 +3,11 @@ * REST API endpoint for collection of Abandoned Carts. * * @author George Gecewicz - * @package WebDevStudios\CCForWoo\Rest\V1 + * @package WebDevStudios\CCForWoo\Rest\AbandonedCarts * @since 2019-10-16 */ -namespace WebDevStudios\CCForWoo\Rest\Endpoints; +namespace WebDevStudios\CCForWoo\Rest\AbandonedCarts; use WP_REST_Server; use WP_REST_Request; @@ -21,13 +21,13 @@ use WebDevStudios\CCForWoo\Rest\Registrar; /** - * Class AbandonedCarts + * Class AbandonedCarts\Controller * * @author George Gecewicz - * @package WebDevStudios\CCForWoo\Rest\V1 + * @package WebDevStudios\CCForWoo\Rest\AbandonedCarts * @since 2019-10-16 */ -class AbandonedCarts extends WP_REST_Controller { +class Controller extends WP_REST_Controller { /** * This endpoint's rest base. diff --git a/src/Rest/AbandonedCarts/Schema.php b/src/Rest/AbandonedCarts/Schema.php new file mode 100644 index 00000000..e69de29b diff --git a/src/Rest/Registrar.php b/src/Rest/Registrar.php index b2d61f06..02a54247 100644 --- a/src/Rest/Registrar.php +++ b/src/Rest/Registrar.php @@ -9,6 +9,7 @@ namespace WebDevStudios\CCForWoo\Rest; +use WebDevStudios\CCForWoo\Rest\AbandonedCarts\Controller as AbandonedCartsController; use WebDevStudios\OopsWP\Structure\Service; /** @@ -47,7 +48,7 @@ public function register_hooks() { * @since 2019-11-13 */ public function init_rest_endpoints() { - ( new Endpoints\AbandonedCarts() )->register_routes(); + ( new AbandonedCartsController() )->register_routes(); } /** From a20e349c5c1bdb2e6aa88ad029bba15b59ddcf5a Mon Sep 17 00:00:00 2001 From: George Gecewicz Date: Thu, 14 Nov 2019 10:49:33 -0500 Subject: [PATCH 07/15] move schema into separate class for readability --- src/Rest/AbandonedCarts/Controller.php | 251 +---------------------- src/Rest/AbandonedCarts/Schema.php | 266 +++++++++++++++++++++++++ 2 files changed, 269 insertions(+), 248 deletions(-) diff --git a/src/Rest/AbandonedCarts/Controller.php b/src/Rest/AbandonedCarts/Controller.php index 447f4d01..9c892af8 100644 --- a/src/Rest/AbandonedCarts/Controller.php +++ b/src/Rest/AbandonedCarts/Controller.php @@ -1,8 +1,7 @@ * @package WebDevStudios\CCForWoo\Rest\AbandonedCarts * @since 2019-10-16 */ @@ -23,7 +22,6 @@ /** * Class AbandonedCarts\Controller * - * @author George Gecewicz * @package WebDevStudios\CCForWoo\Rest\AbandonedCarts * @since 2019-10-16 */ @@ -63,9 +61,9 @@ public function register_routes() { 'methods' => WP_REST_Server::READABLE, 'callback' => [ $this, 'get_items' ], 'permission_callback' => [ $this, 'get_items_permissions_check' ], - 'args' => $this->get_collection_params(), + 'args' => Schema::get_collection_params(), ], - 'schema' => [ $this, 'get_public_item_schema' ], + 'schema' => [ '\WebDevStudios\CCForWoo\Rest\AbandonedCarts\Schema', 'get_public_item_schema' ], ] ); } @@ -342,248 +340,5 @@ private function get_product_image_url( WC_Product $wc_product ) : string { return wp_get_attachment_url( $wc_product->get_image_id() ); } - /** - * Get the Abandoned Cart's schema for public consumption. - * - * @return array - */ - public function get_item_schema() { - return [ - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'cc_woo_abandoned_cart', - 'type' => 'object', - 'properties' => [ - 'cart_id' => [ - 'description' => esc_html__( 'Database ID for the abandoned cart.', 'cc-woo' ), - 'type' => 'integer', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'user_id' => [ - 'description' => esc_html__( 'WordPress user ID of the user the cart belongs to; defaults to 0 if a guest or non-logged-in user.', 'cc-woo' ), - 'type' => 'integer', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'user_email' => [ - 'description' => esc_html__( 'The billing email the user entered at checkout before abandoning it. Note that this may be different than the email address the user has in their WordPress user profile.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'cart_contents' => [ - 'description' => esc_html__( 'Object representation of the cart that was abandoned, and its contents, coupon codes, and billing data.', 'cc-woo' ), - 'type' => 'object', - 'context' => [ 'view' ], - 'readonly' => true, - 'properties' => [ - 'products' => [ - 'description' => esc_html__( 'Key-value listing of products in the cart. Keys are unique WooCommerce-generated keys identifying the cart in the database; values are objects representing the items in the cart.', 'cc-woo' ), - 'type' => 'array', - 'context' => [ 'view' ], - 'readonly' => true, - 'properties' => [ - [ - 'key' => [ - 'description' => esc_html__( 'Unique WooCommerce-generated key identifying the cart in the database. This differs from the parent-level cart_hash property.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'product_id' => [ - 'description' => esc_html__( 'The WooCommerce product ID.', 'cc-woo' ), - 'type' => 'integer', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'variation_id' => [ - 'description' => esc_html__( 'The WooCommerce product variation ID, if applicable.', 'cc-woo' ), - 'type' => 'integer', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'variation' => [ - 'description' => esc_html__( 'Object representation of any applicable variations, where keys are variation names and values are the actual variation selection.', 'cc-woo' ), - 'type' => 'object', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'quantity' => [ - 'description' => esc_html__( 'Item quantity.', 'cc-woo' ), - 'type' => 'integer', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'data_hash' => [ - 'description' => esc_html__( 'MD5 hash of cart items to determine if contents are modified.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'line_tax_data' => [ - 'description' => esc_html__( 'Line subtotal tax and total tax data.', 'cc-woo' ), - 'type' => 'object', - 'context' => [ 'view' ], - 'readonly' => true, - 'properties' => [ - 'subtotal' => [ - 'description' => esc_html__( 'Line subtotal tax data.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'total' => [ - 'description' => esc_html__( 'Line total tax data.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - ] - ], - 'line_subtotal' => [ - 'description' => esc_html__( 'Line subtotal.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'line_subtotal_tax' => [ - 'description' => esc_html__( 'Line subtotal tax.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'line_total' => [ - 'description' => esc_html__( 'Line total.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'line_tax' => [ - 'description' => esc_html__( 'Line total tax.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'data' => [ - 'description' => esc_html__( 'Misc. product data in key-value pairs.', 'cc-woo' ), - 'type' => 'object', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'product_title' => [ - 'description' => esc_html__( 'The product title.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'product_sku' => [ - 'description' => esc_html__( 'The product SKU.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'product_permalink' => [ - 'description' => esc_html__( 'Permalink to the product page.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'product_image_url' => [ - 'description' => esc_html__( 'URL to the full-size featured image for the product if one exists.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ] - ] - ] - ], - 'coupons' => [ - 'description' => esc_html__( '', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - ], - ], - 'cart_updated' => [ - 'description' => esc_html__( '', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'cart_updated_ts' => [ - 'description' => esc_html__( '', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'cart_created' => [ - 'description' => esc_html__( '', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'cart_created_ts' => [ - 'description' => esc_html__( '', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'cart_hash' => [ - 'description' => esc_html__( '', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'cart_subtotal' => [ - 'description' => esc_html__( '', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'cart_total' => [ - 'description' => esc_html__( '', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'cart_subtotal_tax' => [ - 'description' => esc_html__( '', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'cart_total_tax' => [ - 'description' => esc_html__( '', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'cart_recovery_url' => [ - 'description' => esc_html__( '', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - ] - ]; - - return $this->add_additional_fields_schema( $schema ); - } - - /** - * Get the query params for Abandoned Carts. - * - * @return array - */ - public function get_collection_params() { - return [ - 'page' => [], - 'per_page' => [], - 'date_min' => [], - 'date_max' => [], - ]; - } - } diff --git a/src/Rest/AbandonedCarts/Schema.php b/src/Rest/AbandonedCarts/Schema.php index e69de29b..0027ff09 100644 --- a/src/Rest/AbandonedCarts/Schema.php +++ b/src/Rest/AbandonedCarts/Schema.php @@ -0,0 +1,266 @@ + + * @since 2019-11-13 + * + * @return array + * */ + public static function get_collection_params() { + return [ + 'page' => [], + 'per_page' => [], + 'date_min' => [], + 'date_max' => [], + ]; + } + + /** + * Get the Abandoned Cart's schema for public consumption. + * + * @author George Gecewicz + * @since 2019-11-13 + * + * @return array + */ + public static function get_public_item_schema() { + return [ + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'cc_woo_abandoned_cart', + 'type' => 'object', + 'properties' => [ + 'cart_id' => [ + 'description' => esc_html__( 'Database ID for the abandoned cart.', 'cc-woo' ), + 'type' => 'integer', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'user_id' => [ + 'description' => esc_html__( 'WordPress user ID of the user the cart belongs to; defaults to 0 if a guest or non-logged-in user.', 'cc-woo' ), + 'type' => 'integer', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'user_email' => [ + 'description' => esc_html__( 'The billing email the user entered at checkout before abandoning it. Note that this may be different than the email address the user has in their WordPress user profile.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_contents' => [ + 'description' => esc_html__( 'Object representation of the cart that was abandoned, and its contents, coupon codes, and billing data.', 'cc-woo' ), + 'type' => 'object', + 'context' => [ 'view' ], + 'readonly' => true, + 'properties' => [ + 'products' => [ + 'description' => esc_html__( 'Key-value listing of products in the cart. Keys are unique WooCommerce-generated keys identifying the cart in the database; values are objects representing the items in the cart.', 'cc-woo' ), + 'type' => 'array', + 'context' => [ 'view' ], + 'readonly' => true, + 'properties' => [ + [ + 'key' => [ + 'description' => esc_html__( 'Unique WooCommerce-generated key identifying the cart in the database. This differs from the parent-level cart_hash property.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'product_id' => [ + 'description' => esc_html__( 'The WooCommerce product ID.', 'cc-woo' ), + 'type' => 'integer', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'variation_id' => [ + 'description' => esc_html__( 'The WooCommerce product variation ID, if applicable.', 'cc-woo' ), + 'type' => 'integer', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'variation' => [ + 'description' => esc_html__( 'Object representation of any applicable variations, where keys are variation names and values are the actual variation selection.', 'cc-woo' ), + 'type' => 'object', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'quantity' => [ + 'description' => esc_html__( 'Item quantity.', 'cc-woo' ), + 'type' => 'integer', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'data_hash' => [ + 'description' => esc_html__( 'MD5 hash of cart items to determine if contents are modified.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'line_tax_data' => [ + 'description' => esc_html__( 'Line subtotal tax and total tax data.', 'cc-woo' ), + 'type' => 'object', + 'context' => [ 'view' ], + 'readonly' => true, + 'properties' => [ + 'subtotal' => [ + 'description' => esc_html__( 'Line subtotal tax data.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'total' => [ + 'description' => esc_html__( 'Line total tax data.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + ] + ], + 'line_subtotal' => [ + 'description' => esc_html__( 'Line subtotal.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'line_subtotal_tax' => [ + 'description' => esc_html__( 'Line subtotal tax.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'line_total' => [ + 'description' => esc_html__( 'Line total.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'line_tax' => [ + 'description' => esc_html__( 'Line total tax.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'data' => [ + 'description' => esc_html__( 'Misc. product data in key-value pairs.', 'cc-woo' ), + 'type' => 'object', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'product_title' => [ + 'description' => esc_html__( 'The product title.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'product_sku' => [ + 'description' => esc_html__( 'The product SKU.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'product_permalink' => [ + 'description' => esc_html__( 'Permalink to the product page.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'product_image_url' => [ + 'description' => esc_html__( 'URL to the full-size featured image for the product if one exists.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ] + ] + ] + ], + 'coupons' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + ], + ], + 'cart_updated' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_updated_ts' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_created' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_created_ts' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_hash' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_subtotal' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_total' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_subtotal_tax' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_total_tax' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'cart_recovery_url' => [ + 'description' => esc_html__( '', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + ] + ]; + } + +} From faf86c6493a22cadd5caf4c24441a5ead7dcf7d7 Mon Sep 17 00:00:00 2001 From: George Gecewicz Date: Thu, 14 Nov 2019 10:51:31 -0500 Subject: [PATCH 08/15] fix some spacing issues in Registrar and Schema classes --- src/Rest/AbandonedCarts/Schema.php | 34 +++++++++++++++--------------- src/Rest/Registrar.php | 32 ++++++++++++++-------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/Rest/AbandonedCarts/Schema.php b/src/Rest/AbandonedCarts/Schema.php index 0027ff09..d4bb93a7 100644 --- a/src/Rest/AbandonedCarts/Schema.php +++ b/src/Rest/AbandonedCarts/Schema.php @@ -16,29 +16,29 @@ */ class Schema { - /** - * Get the query params for Abandoned Carts. - * - * @author George Gecewicz - * @since 2019-11-13 - * + /** + * Get the query params for Abandoned Carts. + * + * @author George Gecewicz + * @since 2019-11-13 + * * @return array - * */ - public static function get_collection_params() { - return [ - 'page' => [], - 'per_page' => [], - 'date_min' => [], - 'date_max' => [], - ]; + * */ + public static function get_collection_params() { + return [ + 'page' => [], + 'per_page' => [], + 'date_min' => [], + 'date_max' => [], + ]; } /** * Get the Abandoned Cart's schema for public consumption. - * + * * @author George Gecewicz - * @since 2019-11-13 - * + * @since 2019-11-13 + * * @return array */ public static function get_public_item_schema() { diff --git a/src/Rest/Registrar.php b/src/Rest/Registrar.php index 02a54247..52a13d50 100644 --- a/src/Rest/Registrar.php +++ b/src/Rest/Registrar.php @@ -21,14 +21,14 @@ */ class Registrar extends Service { - /** + /** * Namespace for the endpoints this registrar registers. * * @since 2019-10-16 * * @var string */ - public static $namespace = 'wc/cc-woo'; + public static $namespace = 'wc/cc-woo'; /** * Register hooks. @@ -37,9 +37,9 @@ class Registrar extends Service { * @since 2019-11-13 */ public function register_hooks() { - add_action( 'rest_api_init', [ $this, 'init_rest_endpoints' ] ); - add_filter( 'woocommerce_rest_is_request_to_rest_api', [ $this, 'register_endpoints_with_woo_auth_handler' ] ); - } + add_action( 'rest_api_init', [ $this, 'init_rest_endpoints' ] ); + add_filter( 'woocommerce_rest_is_request_to_rest_api', [ $this, 'register_endpoints_with_woo_auth_handler' ] ); + } /** * Initialize REST endpoints. @@ -49,27 +49,27 @@ public function register_hooks() { */ public function init_rest_endpoints() { ( new AbandonedCartsController() )->register_routes(); - } + } - /** + /** * Register REST endpoints with wc/cc-woo namespace with WooCommerce's REST auth handler. * * @author George Gecewicz * @since 2019-11-13 - * - * @return bool + * + * @return bool */ - public function register_endpoints_with_woo_auth_handler() { - $request_uri = esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ); + public function register_endpoints_with_woo_auth_handler() { + $request_uri = esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ); - if ( empty( $request_uri ) ) { - return false; - } + if ( empty( $request_uri ) ) { + return false; + } $rest_prefix = trailingslashit( rest_get_url_prefix() ); - return false !== strpos( $request_uri, $rest_prefix . self::$namespace ); - } + return false !== strpos( $request_uri, $rest_prefix . self::$namespace ); + } } From f80c0eab48e99a5e06f4ce3641fda7755f2e92a1 Mon Sep 17 00:00:00 2001 From: George Gecewicz Date: Thu, 14 Nov 2019 15:09:18 -0500 Subject: [PATCH 09/15] merge latest develop branch and flesh out the Schema class --- src/Rest/AbandonedCarts/Schema.php | 230 +++++++++++++++-------------- 1 file changed, 116 insertions(+), 114 deletions(-) diff --git a/src/Rest/AbandonedCarts/Schema.php b/src/Rest/AbandonedCarts/Schema.php index d4bb93a7..2d20baff 100644 --- a/src/Rest/AbandonedCarts/Schema.php +++ b/src/Rest/AbandonedCarts/Schema.php @@ -76,120 +76,7 @@ public static function get_public_item_schema() { 'type' => 'array', 'context' => [ 'view' ], 'readonly' => true, - 'properties' => [ - [ - 'key' => [ - 'description' => esc_html__( 'Unique WooCommerce-generated key identifying the cart in the database. This differs from the parent-level cart_hash property.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'product_id' => [ - 'description' => esc_html__( 'The WooCommerce product ID.', 'cc-woo' ), - 'type' => 'integer', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'variation_id' => [ - 'description' => esc_html__( 'The WooCommerce product variation ID, if applicable.', 'cc-woo' ), - 'type' => 'integer', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'variation' => [ - 'description' => esc_html__( 'Object representation of any applicable variations, where keys are variation names and values are the actual variation selection.', 'cc-woo' ), - 'type' => 'object', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'quantity' => [ - 'description' => esc_html__( 'Item quantity.', 'cc-woo' ), - 'type' => 'integer', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'data_hash' => [ - 'description' => esc_html__( 'MD5 hash of cart items to determine if contents are modified.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'line_tax_data' => [ - 'description' => esc_html__( 'Line subtotal tax and total tax data.', 'cc-woo' ), - 'type' => 'object', - 'context' => [ 'view' ], - 'readonly' => true, - 'properties' => [ - 'subtotal' => [ - 'description' => esc_html__( 'Line subtotal tax data.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'total' => [ - 'description' => esc_html__( 'Line total tax data.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - ] - ], - 'line_subtotal' => [ - 'description' => esc_html__( 'Line subtotal.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'line_subtotal_tax' => [ - 'description' => esc_html__( 'Line subtotal tax.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'line_total' => [ - 'description' => esc_html__( 'Line total.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'line_tax' => [ - 'description' => esc_html__( 'Line total tax.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'data' => [ - 'description' => esc_html__( 'Misc. product data in key-value pairs.', 'cc-woo' ), - 'type' => 'object', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'product_title' => [ - 'description' => esc_html__( 'The product title.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'product_sku' => [ - 'description' => esc_html__( 'The product SKU.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'product_permalink' => [ - 'description' => esc_html__( 'Permalink to the product page.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ], - 'product_image_url' => [ - 'description' => esc_html__( 'URL to the full-size featured image for the product if one exists.', 'cc-woo' ), - 'type' => 'string', - 'context' => [ 'view' ], - 'readonly' => true, - ] - ] - ] + 'properties' => self::get_products_properties(), ], 'coupons' => [ 'description' => esc_html__( '', 'cc-woo' ), @@ -263,4 +150,119 @@ public static function get_public_item_schema() { ]; } + public static function get_products_properties() { + return [ + 'key' => [ + 'description' => esc_html__( 'Unique WooCommerce-generated key identifying the cart in the database. This differs from the parent-level cart_hash property.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'product_id' => [ + 'description' => esc_html__( 'The WooCommerce product ID.', 'cc-woo' ), + 'type' => 'integer', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'variation_id' => [ + 'description' => esc_html__( 'The WooCommerce product variation ID, if applicable.', 'cc-woo' ), + 'type' => 'integer', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'variation' => [ + 'description' => esc_html__( 'Object representation of any applicable variations, where keys are variation names and values are the actual variation selection.', 'cc-woo' ), + 'type' => 'object', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'quantity' => [ + 'description' => esc_html__( 'Item quantity.', 'cc-woo' ), + 'type' => 'integer', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'data_hash' => [ + 'description' => esc_html__( 'MD5 hash of cart items to determine if contents are modified.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'line_tax_data' => [ + 'description' => esc_html__( 'Line subtotal tax and total tax data.', 'cc-woo' ), + 'type' => 'object', + 'context' => [ 'view' ], + 'readonly' => true, + 'properties' => [ + 'subtotal' => [ + 'description' => esc_html__( 'Line subtotal tax data.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'total' => [ + 'description' => esc_html__( 'Line total tax data.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + ] + ], + 'line_subtotal' => [ + 'description' => esc_html__( 'Line subtotal.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'line_subtotal_tax' => [ + 'description' => esc_html__( 'Line subtotal tax.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'line_total' => [ + 'description' => esc_html__( 'Line total.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'line_tax' => [ + 'description' => esc_html__( 'Line total tax.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'data' => [ + 'description' => esc_html__( 'Misc. product data in key-value pairs.', 'cc-woo' ), + 'type' => 'object', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'product_title' => [ + 'description' => esc_html__( 'The product title.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'product_sku' => [ + 'description' => esc_html__( 'The product SKU.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'product_permalink' => [ + 'description' => esc_html__( 'Permalink to the product page.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ], + 'product_image_url' => [ + 'description' => esc_html__( 'URL to the full-size featured image for the product if one exists.', 'cc-woo' ), + 'type' => 'string', + 'context' => [ 'view' ], + 'readonly' => true, + ] + ]; + } + } From 79cb03203bf1f4eb981f13e3d60805c7419c1249 Mon Sep 17 00:00:00 2001 From: George Gecewicz Date: Thu, 14 Nov 2019 15:11:43 -0500 Subject: [PATCH 10/15] some phpdoc cleanup --- src/Rest/AbandonedCarts/Controller.php | 3 +++ src/Rest/AbandonedCarts/Schema.php | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/src/Rest/AbandonedCarts/Controller.php b/src/Rest/AbandonedCarts/Controller.php index 9c892af8..86fb1928 100644 --- a/src/Rest/AbandonedCarts/Controller.php +++ b/src/Rest/AbandonedCarts/Controller.php @@ -71,6 +71,9 @@ public function register_routes() { /** * Check whether a given request has permission to show abandoned carts. * + * @author George Gecewicz + * @since 2019-11-12 + * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean */ diff --git a/src/Rest/AbandonedCarts/Schema.php b/src/Rest/AbandonedCarts/Schema.php index 2d20baff..34cb6e5a 100644 --- a/src/Rest/AbandonedCarts/Schema.php +++ b/src/Rest/AbandonedCarts/Schema.php @@ -150,6 +150,14 @@ public static function get_public_item_schema() { ]; } + /** + * Get properties for individual Products definition in Schema. + * + * @author George Gecewicz + * @since 2019-11-13 + * + * @return array + */ public static function get_products_properties() { return [ 'key' => [ From f5fffdef9850459a6bd8bc61d6da7d40e5c37fc3 Mon Sep 17 00:00:00 2001 From: George Gecewicz Date: Thu, 14 Nov 2019 15:26:46 -0500 Subject: [PATCH 11/15] remove unnecessary auth filter; make products array in REST response simpler --- src/AbandonedCarts/CartHandler.php | 2 +- src/Rest/Registrar.php | 22 ---------------------- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/src/AbandonedCarts/CartHandler.php b/src/AbandonedCarts/CartHandler.php index 046351c5..ff4c9a37 100644 --- a/src/AbandonedCarts/CartHandler.php +++ b/src/AbandonedCarts/CartHandler.php @@ -242,7 +242,7 @@ protected function save_cart_data( $user_id, $customer_data ) { $user_id, $customer_data['billing']['email'], maybe_serialize( [ - 'products' => WC()->cart->get_cart(), + 'products' => array_values( WC()->cart->get_cart() ), 'coupons' => WC()->cart->get_applied_coupons(), 'customer' => $customer_data, 'shipping_method' => WC()->checkout()->get_posted_data()['shipping_method'], diff --git a/src/Rest/Registrar.php b/src/Rest/Registrar.php index 52a13d50..7c3d102c 100644 --- a/src/Rest/Registrar.php +++ b/src/Rest/Registrar.php @@ -38,7 +38,6 @@ class Registrar extends Service { */ public function register_hooks() { add_action( 'rest_api_init', [ $this, 'init_rest_endpoints' ] ); - add_filter( 'woocommerce_rest_is_request_to_rest_api', [ $this, 'register_endpoints_with_woo_auth_handler' ] ); } /** @@ -50,26 +49,5 @@ public function register_hooks() { public function init_rest_endpoints() { ( new AbandonedCartsController() )->register_routes(); } - - /** - * Register REST endpoints with wc/cc-woo namespace with WooCommerce's REST auth handler. - * - * @author George Gecewicz - * @since 2019-11-13 - * - * @return bool - */ - public function register_endpoints_with_woo_auth_handler() { - $request_uri = esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ); - - if ( empty( $request_uri ) ) { - return false; - } - - $rest_prefix = trailingslashit( rest_get_url_prefix() ); - - return false !== strpos( $request_uri, $rest_prefix . self::$namespace ); - } - } From 8800f0e395a349c30524e7760ee202c900e8d92d Mon Sep 17 00:00:00 2001 From: George Gecewicz Date: Thu, 14 Nov 2019 15:31:34 -0500 Subject: [PATCH 12/15] finish carts public item schema --- src/Rest/AbandonedCarts/Schema.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Rest/AbandonedCarts/Schema.php b/src/Rest/AbandonedCarts/Schema.php index 34cb6e5a..09a8f585 100644 --- a/src/Rest/AbandonedCarts/Schema.php +++ b/src/Rest/AbandonedCarts/Schema.php @@ -79,69 +79,69 @@ public static function get_public_item_schema() { 'properties' => self::get_products_properties(), ], 'coupons' => [ - 'description' => esc_html__( '', 'cc-woo' ), - 'type' => 'string', + 'description' => esc_html__( 'Array of coupon code strings used in the checkout.', 'cc-woo' ), + 'type' => 'array', 'context' => [ 'view' ], 'readonly' => true, ], ], ], 'cart_updated' => [ - 'description' => esc_html__( '', 'cc-woo' ), + 'description' => esc_html__( 'The MySQL-format datetime of when the cart was last updated, in GMT+0 time zone.', 'cc-woo' ), 'type' => 'string', 'context' => [ 'view' ], 'readonly' => true, ], 'cart_updated_ts' => [ - 'description' => esc_html__( '', 'cc-woo' ), + 'description' => esc_html__( 'Unix timestamp of when the cart was last updated, in GMT+0 time zone.', 'cc-woo' ), 'type' => 'string', 'context' => [ 'view' ], 'readonly' => true, ], 'cart_created' => [ - 'description' => esc_html__( '', 'cc-woo' ), + 'description' => esc_html__( 'The MySQL-format datetime of when the cart was first created, in GMT+0 time zone.', 'cc-woo' ), 'type' => 'string', 'context' => [ 'view' ], 'readonly' => true, ], 'cart_created_ts' => [ - 'description' => esc_html__( '', 'cc-woo' ), + 'description' => esc_html__( 'Unix timestamp of when the cart was first created, in GMT+0 time zone.', 'cc-woo' ), 'type' => 'string', 'context' => [ 'view' ], 'readonly' => true, ], 'cart_hash' => [ - 'description' => esc_html__( '', 'cc-woo' ), + 'description' => esc_html__( 'MD5 hash of cart\'s user ID and email address.', 'cc-woo' ), 'type' => 'string', 'context' => [ 'view' ], 'readonly' => true, ], 'cart_subtotal' => [ - 'description' => esc_html__( '', 'cc-woo' ), + 'description' => esc_html__( 'Cart subtotal.', 'cc-woo' ), 'type' => 'string', 'context' => [ 'view' ], 'readonly' => true, ], 'cart_total' => [ - 'description' => esc_html__( '', 'cc-woo' ), + 'description' => esc_html__( 'Cart total.', 'cc-woo' ), 'type' => 'string', 'context' => [ 'view' ], 'readonly' => true, ], 'cart_subtotal_tax' => [ - 'description' => esc_html__( '', 'cc-woo' ), + 'description' => esc_html__( 'Cart subtotal tax.', 'cc-woo' ), 'type' => 'string', 'context' => [ 'view' ], 'readonly' => true, ], 'cart_total_tax' => [ - 'description' => esc_html__( '', 'cc-woo' ), + 'description' => esc_html__( 'Cart total tax.', 'cc-woo' ), 'type' => 'string', 'context' => [ 'view' ], 'readonly' => true, ], 'cart_recovery_url' => [ - 'description' => esc_html__( '', 'cc-woo' ), + 'description' => esc_html__( 'Recovery URL that recreates cart the cart for checkout when visited.', 'cc-woo' ), 'type' => 'string', 'context' => [ 'view' ], 'readonly' => true, From 0e3d74b0b7f431762d7d519637716b7d61a8b66e Mon Sep 17 00:00:00 2001 From: George Gecewicz Date: Thu, 14 Nov 2019 15:36:47 -0500 Subject: [PATCH 13/15] finish describing query params --- src/Rest/AbandonedCarts/Schema.php | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/Rest/AbandonedCarts/Schema.php b/src/Rest/AbandonedCarts/Schema.php index 09a8f585..233d7534 100644 --- a/src/Rest/AbandonedCarts/Schema.php +++ b/src/Rest/AbandonedCarts/Schema.php @@ -26,10 +26,27 @@ class Schema { * */ public static function get_collection_params() { return [ - 'page' => [], - 'per_page' => [], - 'date_min' => [], - 'date_max' => [], + 'page' => [ + 'description' => esc_html__( 'Current page of paginated results.', 'woocommerce' ), + 'required' => false, + 'type' => 'integer', + ], + 'per_page' => [ + 'description' => esc_html__( 'How many abandoned carts to show per page.', 'woocommerce' ), + 'required' => false, + 'type' => 'integer', + 'default' => 10, + ], + 'date_min' => [ + 'description' => esc_html__( 'Filters results to only show abandoned carts created after this date. Accepts dates in any format acceptable for comparison of MySQL DATETIME column values.', 'woocommerce' ), + 'required' => false, + 'type' => 'string', + ], + 'date_max' => [ + 'description' => esc_html__( 'Filters results to only show abandoned carts created before this date. Accepts dates in any format acceptable for comparison of MySQL DATETIME column values.', 'woocommerce' ), + 'required' => false, + 'type' => 'string', + ], ]; } From 5592ffe944abb5a7422b6563d70e86924832a8ef Mon Sep 17 00:00:00 2001 From: George Gecewicz Date: Thu, 14 Nov 2019 15:43:22 -0500 Subject: [PATCH 14/15] fix some whitespace issues --- src/Rest/AbandonedCarts/Schema.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Rest/AbandonedCarts/Schema.php b/src/Rest/AbandonedCarts/Schema.php index 233d7534..f7dec96a 100644 --- a/src/Rest/AbandonedCarts/Schema.php +++ b/src/Rest/AbandonedCarts/Schema.php @@ -23,7 +23,7 @@ class Schema { * @since 2019-11-13 * * @return array - * */ + */ public static function get_collection_params() { return [ 'page' => [ @@ -48,7 +48,7 @@ public static function get_collection_params() { 'type' => 'string', ], ]; - } + } /** * Get the Abandoned Cart's schema for public consumption. From 4952ef3849d49365a91eda59e32e19fd9bc2300b Mon Sep 17 00:00:00 2001 From: George Gecewicz Date: Thu, 14 Nov 2019 16:09:52 -0500 Subject: [PATCH 15/15] remove firebase JWT token composer dependency --- composer.json | 3 +-- composer.lock | 48 +----------------------------------------------- 2 files changed, 2 insertions(+), 49 deletions(-) diff --git a/composer.json b/composer.json index 3b1b2a46..77726e44 100644 --- a/composer.json +++ b/composer.json @@ -28,8 +28,7 @@ }, "require": { "webdevstudios/oops-wp": "^0.1", - "composer/installers": "^1.6", - "firebase/php-jwt": "^5.0" + "composer/installers": "^1.6" }, "archive": { "exclude": [ diff --git a/composer.lock b/composer.lock index 44317ca9..d9dd9d42 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "cd9cf4554eb2711427811502c9e8624d", + "content-hash": "ceca78e5da697872f7b692cfe20570c5", "packages": [ { "name": "composer/installers", @@ -128,52 +128,6 @@ ], "time": "2019-08-12T15:00:31+00:00" }, - { - "name": "firebase/php-jwt", - "version": "v5.0.0", - "source": { - "type": "git", - "url": "https://github.com/firebase/php-jwt.git", - "reference": "9984a4d3a32ae7673d6971ea00bae9d0a1abba0e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/9984a4d3a32ae7673d6971ea00bae9d0a1abba0e", - "reference": "9984a4d3a32ae7673d6971ea00bae9d0a1abba0e", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": " 4.8.35" - }, - "type": "library", - "autoload": { - "psr-4": { - "Firebase\\JWT\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Neuman Vong", - "email": "neuman+pear@twilio.com", - "role": "Developer" - }, - { - "name": "Anant Narayanan", - "email": "anant@php.net", - "role": "Developer" - } - ], - "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", - "homepage": "https://github.com/firebase/php-jwt", - "time": "2017-06-27T22:17:23+00:00" - }, { "name": "webdevstudios/oops-wp", "version": "0.1.0",