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

Yoast / wordpress-seo / 9594812bf110d67afe78816058eb15ec830063d2

15 Jul 2025 10:16AM UTC coverage: 52.595% (-1.0%) from 53.638%
9594812bf110d67afe78816058eb15ec830063d2

Pull #22432

github

web-flow
Merge branch 'trunk' into feature/ai-generator-in-free
Pull Request #22432: Merge feature branch into trunk

8341 of 15027 branches covered (55.51%)

Branch coverage included in aggregate %.

382 of 1769 new or added lines in 122 files covered. (21.59%)

2 existing lines in 2 files now uncovered.

30934 of 59648 relevant lines covered (51.86%)

40029.26 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\WP_Request_Exception;
11
use Yoast\WP\SEO\AI_HTTP_Request\Domain\Request;
12
use Yoast\WP\SEO\Conditionals\AI_Conditional;
13
use Yoast\WP\SEO\Main;
14
use Yoast\WP\SEO\Routes\Route_Interface;
15

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

25
        use Route_Permission_Trait;
26

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

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

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

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

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

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

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

84
        /**
85
         * Registers routes with WordPress.
86
         *
87
         * @return void
88
         */
NEW
89
        public function register_routes() {
×
NEW
90
                \register_rest_route(
×
NEW
91
                        self::ROUTE_NAMESPACE,
×
NEW
92
                        self::ROUTE_PREFIX,
×
NEW
93
                        [
×
NEW
94
                                'methods'             => 'POST',
×
NEW
95
                                'callback'            => [ $this, 'get_usage' ],
×
NEW
96
                                'permission_callback' => [ $this, 'check_permissions' ],
×
NEW
97
                        ]
×
NEW
98
                );
×
99
        }
100

101
        /**
102
         * Runs the callback that gets the monthly usage of the user.
103
         *
104
         * @return WP_REST_Response The response of the callback action.
105
         */
NEW
106
        public function get_usage(): WP_REST_Response {
×
NEW
107
                $user = \wp_get_current_user();
×
108
                try {
NEW
109
                        $token           = $this->token_manager->get_or_request_access_token( $user );
×
NEW
110
                        $request_headers = [
×
NEW
111
                                'Authorization' => "Bearer $token",
×
NEW
112
                        ];
×
NEW
113
                        $action_path     = $this->get_action_path();
×
NEW
114
                        $response        = $this->request_handler->handle( new Request( $action_path, [], $request_headers, false ) );
×
NEW
115
                        $data            = \json_decode( $response->get_body() );
×
116

NEW
117
                }  catch ( Remote_Request_Exception | WP_Request_Exception $e ) {
×
NEW
118
                        $message = [
×
NEW
119
                                'errorMessage'    => $e->getMessage(),
×
NEW
120
                                'errorIdentifier' => $e->get_error_identifier(),
×
NEW
121
                                'errorCode'       => $e->getCode(),
×
NEW
122
                        ];
×
NEW
123
                        return new WP_REST_Response(
×
NEW
124
                                $message,
×
NEW
125
                                $e->getCode()
×
NEW
126
                        );
×
127
                }
128

NEW
129
                return new WP_REST_Response( $data );
×
130
        }
131

132
        /**
133
         * Get action path for the request.
134
         *
135
         * @return string The action path.
136
         */
NEW
137
        public function get_action_path() {
×
NEW
138
                $post_type = \get_post_type();
×
NEW
139
                $unlimited = '/usage/' . \gmdate( 'Y-m' );
×
NEW
140
                if ( $post_type === 'product' && $this->addon_manager->has_valid_subscription( WPSEO_Addon_Manager::WOOCOMMERCE_SLUG ) ) {
×
NEW
141
                        return $unlimited;
×
142
                }
NEW
143
                if ( $post_type !== 'product' && $this->addon_manager->has_valid_subscription( WPSEO_Addon_Manager::PREMIUM_SLUG ) ) {
×
NEW
144
                        return $unlimited;
×
145
                }
NEW
146
                return '/usage/free-usages';
×
147
        }
148
}
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