PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 28.1
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v28.1
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / src / ai-generator / user-interface / get-usage-route.php

get-usage-route.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 28.1, at src/ai-generator/user-interface/get-usage-route.php

179 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
4 namespace Yoast\WP\SEO\AI_Generator\User_Interface;
5
6 use WP_REST_Response;
7 use WPSEO_Addon_Manager;
8 use Yoast\WP\SEO\AI_Authorization\Application\Token_Manager;
9 use Yoast\WP\SEO\AI_Consent\Application\Consent_Handler;
10 use Yoast\WP\SEO\AI_HTTP_Request\Application\Request_Handler;
11 use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\Forbidden_Exception;
12 use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\Remote_Request_Exception;
13 use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\Too_Many_Requests_Exception;
14 use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\WP_Request_Exception;
15 use Yoast\WP\SEO\AI_HTTP_Request\Domain\Request;
16 use Yoast\WP\SEO\Conditionals\AI_Conditional;
17 use Yoast\WP\SEO\Conditionals\Old_Premium_AI_Conditional;
18 use Yoast\WP\SEO\Main;
19 use Yoast\WP\SEO\Routes\Route_Interface;
20
21 /**
22 * Registers a route to get suggestions from the AI API
23 *
24 * @makePublic
25 *
26 * @phpcs:disable Yoast.NamingConventions.ObjectNameDepth.MaxExceeded
27 */
28 class Get_Usage_Route implements Route_Interface {
29
30 use Route_Permission_Trait;
31
32 /**
33 * The namespace for this route.
34 *
35 * @var string
36 */
37 public const ROUTE_NAMESPACE = Main::API_V1_NAMESPACE;
38
39 /**
40 * The prefix for this route.
41 *
42 * @var string
43 */
44 public const ROUTE_PREFIX = '/ai_generator/get_usage';
45
46 /**
47 * The token manager instance.
48 *
49 * @var Token_Manager
50 */
51 private $token_manager;
52
53 /**
54 * The request handler instance.
55 *
56 * @var Request_Handler
57 */
58 private $request_handler;
59
60 /**
61 * The consent handler instance.
62 *
63 * @var Consent_Handler
64 */
65 private $consent_handler;
66
67 /**
68 * Represents the add-on manager.
69 *
70 * @var WPSEO_Addon_Manager
71 */
72 private $addon_manager;
73
74 /**
75 * Returns the conditionals based in which this loadable should be active.
76 *
77 * @return array<string> The conditionals.
78 */
79 public static function get_conditionals() {
80 return [ AI_Conditional::class, Old_Premium_AI_Conditional::class ];
81 }
82
83 /**
84 * Class constructor.
85 *
86 * @param Token_Manager $token_manager The token manager instance.
87 * @param Request_Handler $request_handler The request handler instance.
88 * @param Consent_Handler $consent_handler The consent handler instance.
89 * @param WPSEO_Addon_Manager $addon_manager The add-on manager instance.
90 */
91 public function __construct( Token_Manager $token_manager, Request_Handler $request_handler, Consent_Handler $consent_handler, WPSEO_Addon_Manager $addon_manager ) {
92 $this->addon_manager = $addon_manager;
93 $this->token_manager = $token_manager;
94 $this->request_handler = $request_handler;
95 $this->consent_handler = $consent_handler;
96 }
97
98 /**
99 * Registers routes with WordPress.
100 *
101 * @return void
102 */
103 public function register_routes() {
104 \register_rest_route(
105 self::ROUTE_NAMESPACE,
106 self::ROUTE_PREFIX,
107 [
108 'methods' => 'POST',
109 'args' => [
110 'is_woo_product_entity' => [
111 'type' => 'boolean',
112 'default' => false,
113 ],
114 ],
115 'callback' => [ $this, 'get_usage' ],
116 'permission_callback' => [ $this, 'check_permissions' ],
117 ],
118 );
119 }
120
121 /**
122 * Runs the callback that gets the monthly usage of the user.
123 *
124 * @param WP_REST_Request $request The request object.
125 *
126 * @return WP_REST_Response The response of the callback action.
127 */
128 public function get_usage( $request ): WP_REST_Response {
129 $is_woo_product_entity = $request->get_param( 'is_woo_product_entity' );
130 $user = \wp_get_current_user();
131 try {
132 $token = $this->token_manager->get_or_request_access_token( $user );
133 $request_headers = [
134 'Authorization' => "Bearer $token",
135 ];
136 $action_path = $this->get_action_path( $is_woo_product_entity );
137 $response = $this->request_handler->handle( new Request( $action_path, [], $request_headers, Request::METHOD_GET ) );
138 $data = \json_decode( $response->get_body() );
139 } catch ( Remote_Request_Exception |WP_Request_Exception $e ) {
140 if ( $e instanceof Forbidden_Exception ) {
141 // The API signals that consent is revoked; sync local state.
142 $this->consent_handler->revoke_consent( $user->ID );
143 }
144 $message = [
145 'errorMessage' => $e->getMessage(),
146 'errorIdentifier' => $e->get_error_identifier(),
147 'errorCode' => $e->getCode(),
148 ];
149 if ( $e instanceof Too_Many_Requests_Exception ) {
150 $message['missingLicenses'] = $e->get_missing_licenses();
151 }
152 return new WP_REST_Response(
153 $message,
154 $e->getCode(),
155 );
156 }
157
158 return new WP_REST_Response( $data );
159 }
160
161 /**
162 * Get action path for the request.
163 *
164 * @param bool $is_woo_product_entity Whether the request is for a WooCommerce product entity.
165 *
166 * @return string The action path.
167 */
168 public function get_action_path( $is_woo_product_entity = false ): string {
169 $unlimited = '/usage/' . \gmdate( 'Y-m' );
170 if ( $is_woo_product_entity && $this->addon_manager->has_valid_subscription( WPSEO_Addon_Manager::WOOCOMMERCE_SLUG ) ) {
171 return $unlimited;
172 }
173 if ( ! $is_woo_product_entity && $this->addon_manager->has_valid_subscription( WPSEO_Addon_Manager::PREMIUM_SLUG ) ) {
174 return $unlimited;
175 }
176 return '/usage/free-usages';
177 }
178 }
179