PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 1.1.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v1.1.0
2.7.0 2.6.0 2.5.0 2.4.0 2.3.0 2.2.0 2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.32.0 1.31.0 1.30.0 1.29.0 1.28.0 1.27.0 1.26.0 1.25.0 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.10.0 All 48 releases
thinkrank / includes / api / class-seo-analytics-endpoint.php

class-seo-analytics-endpoint.php in ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO 1.1.0, at includes/api/class-seo-analytics-endpoint.php

583 lines 18.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * SEO Analytics API Endpoints Class
4 *
5 * REST API endpoints for SEO analytics data collection, Google API integration,
6 * and AI-powered insights generation. Provides comprehensive API access to
7 * Analytics Manager functionality with proper authentication, validation,
8 * and error handling.
9 *
10 * @package ThinkRank
11 * @subpackage API
12 * @since 1.0.0
13 */
14
15 declare(strict_types=1);
16
17 namespace ThinkRank\API;
18
19 use ThinkRank\SEO\Analytics_Manager;
20 use WP_REST_Controller;
21 use WP_REST_Request;
22 use WP_REST_Response;
23 use WP_Error;
24
25 // Prevent direct access
26 if (!defined('ABSPATH')) {
27 exit;
28 }
29
30 /**
31 * SEO Analytics API Endpoints Class
32 *
33 * Provides REST API endpoints for SEO analytics operations including
34 * Google API integration, dashboard data retrieval, SEO opportunities
35 * analysis, and connection management with proper authentication and validation.
36 *
37 * @since 1.0.0
38 */
39 class SEO_Analytics_Endpoint extends WP_REST_Controller {
40
41 /**
42 * Analytics Manager instance
43 *
44 * @since 1.0.0
45 * @var Analytics_Manager
46 */
47 private Analytics_Manager $analytics_manager;
48
49 /**
50 * API namespace
51 *
52 * @since 1.0.0
53 * @var string
54 */
55 protected $namespace = 'thinkrank/v1';
56
57 /**
58 * API resource base
59 *
60 * @since 1.0.0
61 * @var string
62 */
63 protected $rest_base = 'seo-analytics';
64
65 /**
66 * Constructor
67 *
68 * @since 1.0.0
69 * @param Analytics_Manager|null $analytics_manager Analytics manager instance
70 */
71 public function __construct(?Analytics_Manager $analytics_manager = null) {
72 $this->analytics_manager = $analytics_manager ?? new Analytics_Manager();
73 }
74
75 /**
76 * Register API routes
77 * Following ThinkRank endpoint registration patterns
78 *
79 * @since 1.0.0
80 */
81 public function register_routes(): void {
82 // Test Google API connections
83 register_rest_route(
84 $this->namespace,
85 '/' . $this->rest_base . '/test-connections',
86 [
87 [
88 'methods' => 'GET',
89 'callback' => [$this, 'test_connections'],
90 'permission_callback' => [$this, 'check_permissions'],
91 ]
92 ]
93 );
94
95 // Get dashboard data
96 register_rest_route(
97 $this->namespace,
98 '/' . $this->rest_base . '/dashboard',
99 [
100 [
101 'methods' => 'GET',
102 'callback' => [$this, 'get_dashboard_data'],
103 'permission_callback' => [$this, 'check_permissions'],
104 'args' => $this->get_dashboard_args()
105 ]
106 ]
107 );
108
109 // Get SEO opportunities
110 register_rest_route(
111 $this->namespace,
112 '/' . $this->rest_base . '/opportunities',
113 [
114 [
115 'methods' => 'GET',
116 'callback' => [$this, 'get_seo_opportunities'],
117 'permission_callback' => [$this, 'check_permissions'],
118 'args' => $this->get_opportunities_args()
119 ]
120 ]
121 );
122
123 // Setup Search Console verification
124 register_rest_route(
125 $this->namespace,
126 '/' . $this->rest_base . '/setup/search-console',
127 [
128 [
129 'methods' => 'POST',
130 'callback' => [$this, 'setup_search_console'],
131 'permission_callback' => [$this, 'check_permissions'],
132 'args' => $this->get_setup_args()
133 ]
134 ]
135 );
136
137 // Get indexing status
138 register_rest_route(
139 $this->namespace,
140 '/' . $this->rest_base . '/indexing-status',
141 [
142 [
143 'methods' => 'GET',
144 'callback' => [$this, 'get_indexing_status'],
145 'permission_callback' => [$this, 'check_permissions'],
146 ]
147 ]
148 );
149
150 // Refresh cached data
151 register_rest_route(
152 $this->namespace,
153 '/' . $this->rest_base . '/refresh',
154 [
155 [
156 'methods' => 'POST',
157 'callback' => [$this, 'refresh_data'],
158 'permission_callback' => [$this, 'check_permissions'],
159 ]
160 ]
161 );
162
163 // Get client status (for debugging)
164 register_rest_route(
165 $this->namespace,
166 '/' . $this->rest_base . '/status',
167 [
168 [
169 'methods' => 'GET',
170 'callback' => [$this, 'get_client_status'],
171 'permission_callback' => [$this, 'check_permissions'],
172 ]
173 ]
174 );
175
176 // ========================================
177 // SEO Intelligence Enhancement Endpoints
178 // ========================================
179
180 // Get intelligent dashboard data with trends and insights
181 register_rest_route(
182 $this->namespace,
183 '/' . $this->rest_base . '/intelligent-dashboard',
184 [
185 [
186 'methods' => 'GET',
187 'callback' => [$this, 'get_intelligent_dashboard'],
188 'permission_callback' => [$this, 'check_permissions'],
189 'args' => $this->get_dashboard_args()
190 ]
191 ]
192 );
193
194 // Get intelligent SEO opportunities with prioritization
195 register_rest_route(
196 $this->namespace,
197 '/' . $this->rest_base . '/intelligent-opportunities',
198 [
199 [
200 'methods' => 'GET',
201 'callback' => [$this, 'get_intelligent_opportunities'],
202 'permission_callback' => [$this, 'check_permissions'],
203 'args' => $this->get_opportunities_args()
204 ]
205 ]
206 );
207
208 // Get SEO insights
209 register_rest_route(
210 $this->namespace,
211 '/' . $this->rest_base . '/insights',
212 [
213 [
214 'methods' => 'GET',
215 'callback' => [$this, 'get_seo_insights'],
216 'permission_callback' => [$this, 'check_permissions'],
217 'args' => $this->get_dashboard_args()
218 ]
219 ]
220 );
221 }
222
223 /**
224 * Test Google API connections
225 * Following ThinkRank response patterns
226 *
227 * @param WP_REST_Request $request Request object
228 * @return WP_REST_Response|WP_Error Response object
229 */
230 public function test_connections(WP_REST_Request $request): WP_REST_Response|WP_Error {
231 try {
232 $connection_results = $this->analytics_manager->test_connections();
233
234 return new WP_REST_Response([
235 'success' => true,
236 'data' => $connection_results,
237 'message' => 'Connection tests completed'
238 ], 200);
239
240 } catch (\Exception $e) {
241 return new WP_Error(
242 'connection_test_failed',
243 'Connection test failed: ' . $e->getMessage(),
244 ['status' => 500]
245 );
246 }
247 }
248
249 /**
250 * Get analytics dashboard data
251 *
252 * @param WP_REST_Request $request Request object
253 * @return WP_REST_Response|WP_Error Response object
254 */
255 public function get_dashboard_data(WP_REST_Request $request): WP_REST_Response|WP_Error {
256 try {
257 $date_range = $request->get_param('date_range');
258 $dashboard_data = $this->analytics_manager->get_dashboard_data($date_range);
259
260 return new WP_REST_Response([
261 'success' => true,
262 'data' => $dashboard_data,
263 'message' => 'Dashboard data retrieved successfully'
264 ], 200);
265
266 } catch (\Exception $e) {
267 return new WP_Error(
268 'dashboard_data_failed',
269 'Failed to retrieve dashboard data: ' . $e->getMessage(),
270 ['status' => 500]
271 );
272 }
273 }
274
275 /**
276 * Get SEO opportunities
277 *
278 * @param WP_REST_Request $request Request object
279 * @return WP_REST_Response|WP_Error Response object
280 */
281 public function get_seo_opportunities(WP_REST_Request $request): WP_REST_Response|WP_Error {
282 try {
283 $date_range = $request->get_param('date_range');
284 $opportunities = $this->analytics_manager->get_seo_opportunities($date_range);
285
286 return new WP_REST_Response([
287 'success' => true,
288 'data' => $opportunities,
289 'message' => 'SEO opportunities retrieved successfully'
290 ], 200);
291
292 } catch (\Exception $e) {
293 return new WP_Error(
294 'opportunities_failed',
295 'Failed to retrieve SEO opportunities: ' . $e->getMessage(),
296 ['status' => 500]
297 );
298 }
299 }
300
301 /**
302 * Setup Search Console verification
303 *
304 * @param WP_REST_Request $request Request object
305 * @return WP_REST_Response|WP_Error Response object
306 */
307 public function setup_search_console(WP_REST_Request $request): WP_REST_Response|WP_Error {
308 try {
309 $site_url = $request->get_param('site_url');
310 $setup_result = $this->analytics_manager->setup_search_console_verification($site_url);
311
312 return new WP_REST_Response([
313 'success' => $setup_result['success'],
314 'data' => $setup_result,
315 'message' => $setup_result['message']
316 ], $setup_result['success'] ? 200 : 400);
317
318 } catch (\Exception $e) {
319 return new WP_Error(
320 'setup_failed',
321 'Search Console setup failed: ' . $e->getMessage(),
322 ['status' => 500]
323 );
324 }
325 }
326
327 /**
328 * Get indexing status
329 *
330 * @param WP_REST_Request $request Request object
331 * @return WP_REST_Response|WP_Error Response object
332 */
333 public function get_indexing_status(WP_REST_Request $request): WP_REST_Response|WP_Error {
334 try {
335 $indexing_status = $this->analytics_manager->get_indexing_status();
336
337 return new WP_REST_Response([
338 'success' => true,
339 'data' => $indexing_status,
340 'message' => 'Indexing status retrieved successfully'
341 ], 200);
342
343 } catch (\Exception $e) {
344 return new WP_Error(
345 'indexing_status_failed',
346 'Failed to retrieve indexing status: ' . $e->getMessage(),
347 ['status' => 500]
348 );
349 }
350 }
351
352 /**
353 * Refresh cached analytics data
354 *
355 * @param WP_REST_Request $request Request object
356 * @return WP_REST_Response|WP_Error Response object
357 */
358 public function refresh_data(WP_REST_Request $request): WP_REST_Response|WP_Error {
359 try {
360 $refresh_result = $this->analytics_manager->refresh_data();
361
362 return new WP_REST_Response([
363 'success' => $refresh_result['success'],
364 'data' => $refresh_result,
365 'message' => $refresh_result['message']
366 ], 200);
367
368 } catch (\Exception $e) {
369 return new WP_Error(
370 'refresh_failed',
371 'Failed to refresh data: ' . $e->getMessage(),
372 ['status' => 500]
373 );
374 }
375 }
376
377 /**
378 * Get client status for debugging
379 *
380 * @param WP_REST_Request $request Request object
381 * @return WP_REST_Response|WP_Error Response object
382 */
383 public function get_client_status(WP_REST_Request $request): WP_REST_Response|WP_Error {
384 try {
385 $client_status = $this->analytics_manager->get_client_status();
386
387 return new WP_REST_Response([
388 'success' => true,
389 'data' => $client_status,
390 'message' => 'Client status retrieved successfully'
391 ], 200);
392
393 } catch (\Exception $e) {
394 return new WP_Error(
395 'status_failed',
396 'Failed to retrieve client status: ' . $e->getMessage(),
397 ['status' => 500]
398 );
399 }
400 }
401
402 /**
403 * Get dashboard endpoint arguments
404 * Following ThinkRank argument validation patterns
405 *
406 * @return array Endpoint arguments
407 */
408 private function get_dashboard_args(): array {
409 return [
410 'date_range' => [
411 'type' => 'string',
412 'default' => '30d',
413 'enum' => ['7d', '30d', '90d'],
414 'sanitize_callback' => 'sanitize_key',
415 'description' => 'Date range for analytics data'
416 ]
417 ];
418 }
419
420 /**
421 * Get opportunities endpoint arguments
422 *
423 * @return array Endpoint arguments
424 */
425 private function get_opportunities_args(): array {
426 return [
427 'date_range' => [
428 'type' => 'string',
429 'default' => '30d',
430 'enum' => ['7d', '30d', '90d'],
431 'sanitize_callback' => 'sanitize_key',
432 'description' => 'Date range for opportunities analysis'
433 ]
434 ];
435 }
436
437 /**
438 * Get setup endpoint arguments
439 *
440 * @return array Endpoint arguments
441 */
442 private function get_setup_args(): array {
443 return [
444 'site_url' => [
445 'required' => true,
446 'type' => 'string',
447 'sanitize_callback' => 'esc_url_raw',
448 'validate_callback' => [$this, 'validate_site_url'],
449 'description' => 'Site URL to verify in Search Console'
450 ]
451 ];
452 }
453
454 /**
455 * Validate site URL parameter
456 * Following ThinkRank validation patterns
457 *
458 * @param string $site_url Site URL to validate
459 * @return bool|WP_Error Validation result
460 */
461 public function validate_site_url(string $site_url): bool|WP_Error {
462 if (empty($site_url)) {
463 return new WP_Error(
464 'invalid_site_url',
465 'Site URL is required',
466 ['status' => 400]
467 );
468 }
469
470 if (!filter_var($site_url, FILTER_VALIDATE_URL)) {
471 return new WP_Error(
472 'invalid_site_url',
473 'Site URL must be a valid URL',
474 ['status' => 400]
475 );
476 }
477
478 return true;
479 }
480
481 /**
482 * Check permissions for API access
483 * Following ThinkRank permission patterns
484 *
485 * @return bool Permission status
486 */
487 public function check_permissions(): bool {
488 return current_user_can('manage_options');
489 }
490
491 // ========================================
492 // SEO Intelligence Enhancement Endpoints
493 // ========================================
494
495 /**
496 * Get intelligent dashboard data with trends and insights
497 *
498 * @param WP_REST_Request $request Request object
499 * @return WP_REST_Response|WP_Error Response object
500 */
501 public function get_intelligent_dashboard(WP_REST_Request $request): WP_REST_Response|WP_Error {
502 try {
503 $date_range = $request->get_param('date_range');
504 $intelligent_data = $this->analytics_manager->get_intelligent_dashboard_data($date_range);
505
506 $success = isset($intelligent_data['success']) ? $intelligent_data['success'] : false;
507
508 return new WP_REST_Response([
509 'success' => $success,
510 'data' => $intelligent_data['data'] ?? null,
511 'message' => $intelligent_data['message'] ?? 'Intelligent dashboard data retrieved',
512 'timestamp' => current_time('mysql')
513 ], 200); // Always return 200 for successful API calls, even when no data available
514
515 } catch (Exception $e) {
516 return new WP_Error(
517 'intelligent_dashboard_error',
518 'Failed to retrieve intelligent dashboard data: ' . $e->getMessage(),
519 ['status' => 500]
520 );
521 }
522 }
523
524 /**
525 * Get intelligent SEO opportunities with prioritization
526 *
527 * @param WP_REST_Request $request Request object
528 * @return WP_REST_Response|WP_Error Response object
529 */
530 public function get_intelligent_opportunities(WP_REST_Request $request): WP_REST_Response|WP_Error {
531 try {
532 $date_range = $request->get_param('date_range');
533 $intelligent_opportunities = $this->analytics_manager->get_intelligent_seo_opportunities($date_range);
534
535 $success = isset($intelligent_opportunities['success']) ? $intelligent_opportunities['success'] : false;
536
537 return new WP_REST_Response([
538 'success' => $success,
539 'data' => $intelligent_opportunities['data'] ?? null,
540 'message' => $intelligent_opportunities['message'] ?? 'Intelligent opportunities retrieved',
541 'timestamp' => current_time('mysql')
542 ], 200); // Always return 200 for successful API calls, even when no data available
543
544 } catch (Exception $e) {
545 return new WP_Error(
546 'intelligent_opportunities_error',
547 'Failed to retrieve intelligent opportunities: ' . $e->getMessage(),
548 ['status' => 500]
549 );
550 }
551 }
552
553 /**
554 * Get SEO insights
555 *
556 * @param WP_REST_Request $request Request object
557 * @return WP_REST_Response|WP_Error Response object
558 */
559 public function get_seo_insights(WP_REST_Request $request): WP_REST_Response|WP_Error {
560 try {
561 $date_range = $request->get_param('date_range');
562 $insights = $this->analytics_manager->get_seo_insights($date_range);
563
564 $success = isset($insights['success']) ? $insights['success'] : false;
565
566 return new WP_REST_Response([
567 'success' => $success,
568 'data' => $insights['data'] ?? null,
569 'cached' => $insights['cached'] ?? false,
570 'message' => $insights['message'] ?? 'SEO insights retrieved',
571 'timestamp' => current_time('mysql')
572 ], 200); // Always return 200 for successful API calls, even when no data available
573
574 } catch (Exception $e) {
575 return new WP_Error(
576 'seo_insights_error',
577 'Failed to retrieve SEO insights: ' . $e->getMessage(),
578 ['status' => 500]
579 );
580 }
581 }
582 }
583