• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Yoast / wordpress-seo / 81d2b4dba47f1f36d53a30afb3079916e29c1e30

07 Aug 2025 02:44PM UTC coverage: 52.906% (-0.01%) from 52.919%
81d2b4dba47f1f36d53a30afb3079916e29c1e30

push

github

leonidasmi
Merge branch 'release/25.7' of github.com:Yoast/wordpress-seo into trunk

8340 of 15083 branches covered (55.29%)

Branch coverage included in aggregate %.

2 of 13 new or added lines in 6 files covered. (15.38%)

1 existing line in 1 file now uncovered.

31233 of 59716 relevant lines covered (52.3%)

39983.72 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/ai-generator/user-interface/get-usage-route.php
1
<?php
2
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
3
namespace Yoast\WP\SEO\AI_Generator\User_Interface;
4

5
use WP_REST_Response;
6
use WPSEO_Addon_Manager;
7
use Yoast\WP\SEO\AI_Authorization\Application\Token_Manager;
8
use Yoast\WP\SEO\AI_HTTP_Request\Application\Request_Handler;
9
use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\Remote_Request_Exception;
10
use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\Too_Many_Requests_Exception;
11
use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\WP_Request_Exception;
12
use Yoast\WP\SEO\AI_HTTP_Request\Domain\Request;
13
use Yoast\WP\SEO\Conditionals\AI_Conditional;
14
use Yoast\WP\SEO\Main;
15
use Yoast\WP\SEO\Routes\Route_Interface;
16

17
/**
18
 * Registers a route to get suggestions from the AI API
19
 *
20
 * @makePublic
21
 *
22
 * @phpcs:disable Yoast.NamingConventions.ObjectNameDepth.MaxExceeded
23
 */
24
class Get_Usage_Route implements Route_Interface {
25

26
        use Route_Permission_Trait;
27

28
                /**
29
                 *  The namespace for this route.
30
                 *
31
                 * @var string
32
                 */
33
        public const ROUTE_NAMESPACE = Main::API_V1_NAMESPACE;
34

35
        /**
36
         *  The prefix for this route.
37
         *
38
         * @var string
39
         */
40
        public const ROUTE_PREFIX = '/ai_generator/get_usage';
41

42
        /**
43
         * The token manager instance.
44
         *
45
         * @var Token_Manager
46
         */
47
        private $token_manager;
48

49
        /**
50
         * The request handler instance.
51
         *
52
         * @var Request_Handler
53
         */
54
        private $request_handler;
55

56
        /**
57
         * Represents the add-on manager.
58
         *
59
         * @var WPSEO_Addon_Manager
60
         */
61
        private $addon_manager;
62

63
        /**
64
         * Returns the conditionals based in which this loadable should be active.
65
         *
66
         * @return array<string> The conditionals.
67
         */
68
        public static function get_conditionals() {
×
69
                return [ AI_Conditional::class ];
×
70
        }
71

72
        /**
73
         * Class constructor.
74
         *
75
         * @param Token_Manager       $token_manager   The token manager instance.
76
         * @param Request_Handler     $request_handler The request handler instance.
77
         * @param WPSEO_Addon_Manager $addon_manager   The add-on manager instance.
78
         */
79
        public function __construct( Token_Manager $token_manager, Request_Handler $request_handler, WPSEO_Addon_Manager $addon_manager ) {
×
80
                $this->addon_manager   = $addon_manager;
×
81
                $this->token_manager   = $token_manager;
×
82
                $this->request_handler = $request_handler;
×
83
        }
84

85
        /**
86
         * Registers routes with WordPress.
87
         *
88
         * @return void
89
         */
90
        public function register_routes() {
×
91
                \register_rest_route(
×
92
                        self::ROUTE_NAMESPACE,
×
93
                        self::ROUTE_PREFIX,
×
94
                        [
×
95
                                'methods'             => 'POST',
×
96
                                'args'                => [
×
97
                                        'is_woo_product_entity' => [
×
98
                                                'type'        => 'boolean',
×
99
                                                'default'     => false,
×
100
                                        ],
×
101
                                ],
×
102
                                'callback'            => [ $this, 'get_usage' ],
×
103
                                'permission_callback' => [ $this, 'check_permissions' ],
×
104
                        ]
×
105
                );
×
106
        }
107

108
        /**
109
         * Runs the callback that gets the monthly usage of the user.
110
         *
111
         * @param WP_REST_Response $response The response object containing the parameters for the request.
112
         *
113
         * @return WP_REST_Response The response of the callback action.
114
         */
115
        public function get_usage( $response ): WP_REST_Response {
×
116
                $is_woo_product_entity = $response->get_param( 'is_woo_product_entity' );
×
117
                $user                  = \wp_get_current_user();
×
118
                try {
119
                        $token           = $this->token_manager->get_or_request_access_token( $user );
×
120
                        $request_headers = [
×
121
                                'Authorization' => "Bearer $token",
×
122
                        ];
×
123
                        $action_path     = $this->get_action_path( $is_woo_product_entity );
×
124
                        $response        = $this->request_handler->handle( new Request( $action_path, [], $request_headers, false ) );
×
125
                        $data            = \json_decode( $response->get_body() );
×
126

127
                }  catch ( Remote_Request_Exception | WP_Request_Exception $e ) {
×
128
                        $message = [
×
129
                                'errorMessage'    => $e->getMessage(),
×
130
                                'errorIdentifier' => $e->get_error_identifier(),
×
131
                                'errorCode'       => $e->getCode(),
×
132
                        ];
×
NEW
133
                        if ( $e instanceof Too_Many_Requests_Exception ) {
×
NEW
134
                                $message['missingLicenses'] = $e->get_missing_licenses();
×
135
                        }
136
                        return new WP_REST_Response(
×
137
                                $message,
×
138
                                $e->getCode()
×
139
                        );
×
140
                }
141

142
                return new WP_REST_Response( $data );
×
143
        }
144

145
        /**
146
         * Get action path for the request.
147
         *
148
         * @param bool $is_woo_product_entity Whether the request is for a WooCommerce product entity.
149
         *
150
         * @return string The action path.
151
         */
152
        public function get_action_path( $is_woo_product_entity = false ): string {
×
153
                $unlimited = '/usage/' . \gmdate( 'Y-m' );
×
154
                if ( $is_woo_product_entity && $this->addon_manager->has_valid_subscription( WPSEO_Addon_Manager::WOOCOMMERCE_SLUG ) ) {
×
155
                        return $unlimited;
×
156
                }
157
                if ( ! $is_woo_product_entity && $this->addon_manager->has_valid_subscription( WPSEO_Addon_Manager::PREMIUM_SLUG ) ) {
×
158
                        return $unlimited;
×
159
                }
160
                return '/usage/free-usages';
×
161
        }
162
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc