analytics_manager = $analytics_manager ?? new Analytics_Manager(); } /** * Register API routes * Following ThinkRank endpoint registration patterns * * @since 1.0.0 */ public function register_routes(): void { // Test Google API connections register_rest_route( $this->namespace, '/' . $this->rest_base . '/test-connections', [ [ 'methods' => 'GET', 'callback' => [$this, 'test_connections'], 'permission_callback' => [$this, 'check_permissions'], ] ] ); // Get dashboard data register_rest_route( $this->namespace, '/' . $this->rest_base . '/dashboard', [ [ 'methods' => 'GET', 'callback' => [$this, 'get_dashboard_data'], 'permission_callback' => [$this, 'check_permissions'], 'args' => $this->get_dashboard_args() ] ] ); // Get SEO opportunities register_rest_route( $this->namespace, '/' . $this->rest_base . '/opportunities', [ [ 'methods' => 'GET', 'callback' => [$this, 'get_seo_opportunities'], 'permission_callback' => [$this, 'check_permissions'], 'args' => $this->get_opportunities_args() ] ] ); // Setup Search Console verification register_rest_route( $this->namespace, '/' . $this->rest_base . '/setup/search-console', [ [ 'methods' => 'POST', 'callback' => [$this, 'setup_search_console'], 'permission_callback' => [$this, 'check_permissions'], 'args' => $this->get_setup_args() ] ] ); // Get indexing status register_rest_route( $this->namespace, '/' . $this->rest_base . '/indexing-status', [ [ 'methods' => 'GET', 'callback' => [$this, 'get_indexing_status'], 'permission_callback' => [$this, 'check_permissions'], ] ] ); // Refresh cached data register_rest_route( $this->namespace, '/' . $this->rest_base . '/refresh', [ [ 'methods' => 'POST', 'callback' => [$this, 'refresh_data'], 'permission_callback' => [$this, 'check_permissions'], ] ] ); // Get client status (for debugging) register_rest_route( $this->namespace, '/' . $this->rest_base . '/status', [ [ 'methods' => 'GET', 'callback' => [$this, 'get_client_status'], 'permission_callback' => [$this, 'check_permissions'], ] ] ); // ======================================== // SEO Intelligence Enhancement Endpoints // ======================================== // Get intelligent dashboard data with trends and insights register_rest_route( $this->namespace, '/' . $this->rest_base . '/intelligent-dashboard', [ [ 'methods' => 'GET', 'callback' => [$this, 'get_intelligent_dashboard'], 'permission_callback' => [$this, 'check_permissions'], 'args' => $this->get_dashboard_args() ] ] ); // Get intelligent SEO opportunities with prioritization register_rest_route( $this->namespace, '/' . $this->rest_base . '/intelligent-opportunities', [ [ 'methods' => 'GET', 'callback' => [$this, 'get_intelligent_opportunities'], 'permission_callback' => [$this, 'check_permissions'], 'args' => $this->get_opportunities_args() ] ] ); // Get SEO insights register_rest_route( $this->namespace, '/' . $this->rest_base . '/insights', [ [ 'methods' => 'GET', 'callback' => [$this, 'get_seo_insights'], 'permission_callback' => [$this, 'check_permissions'], 'args' => $this->get_dashboard_args() ] ] ); } /** * Test Google API connections * Following ThinkRank response patterns * * @param WP_REST_Request $request Request object * @return WP_REST_Response|WP_Error Response object */ public function test_connections(WP_REST_Request $request): WP_REST_Response|WP_Error { try { $connection_results = $this->analytics_manager->test_connections(); return new WP_REST_Response([ 'success' => true, 'data' => $connection_results, 'message' => 'Connection tests completed' ], 200); } catch (\Exception $e) { return new WP_Error( 'connection_test_failed', 'Connection test failed: ' . $e->getMessage(), ['status' => 500] ); } } /** * Get analytics dashboard data * * @param WP_REST_Request $request Request object * @return WP_REST_Response|WP_Error Response object */ public function get_dashboard_data(WP_REST_Request $request): WP_REST_Response|WP_Error { try { $date_range = $request->get_param('date_range'); $dashboard_data = $this->analytics_manager->get_dashboard_data($date_range); return new WP_REST_Response([ 'success' => true, 'data' => $dashboard_data, 'message' => 'Dashboard data retrieved successfully' ], 200); } catch (\Exception $e) { return new WP_Error( 'dashboard_data_failed', 'Failed to retrieve dashboard data: ' . $e->getMessage(), ['status' => 500] ); } } /** * Get SEO opportunities * * @param WP_REST_Request $request Request object * @return WP_REST_Response|WP_Error Response object */ public function get_seo_opportunities(WP_REST_Request $request): WP_REST_Response|WP_Error { try { $date_range = $request->get_param('date_range'); $opportunities = $this->analytics_manager->get_seo_opportunities($date_range); return new WP_REST_Response([ 'success' => true, 'data' => $opportunities, 'message' => 'SEO opportunities retrieved successfully' ], 200); } catch (\Exception $e) { return new WP_Error( 'opportunities_failed', 'Failed to retrieve SEO opportunities: ' . $e->getMessage(), ['status' => 500] ); } } /** * Setup Search Console verification * * @param WP_REST_Request $request Request object * @return WP_REST_Response|WP_Error Response object */ public function setup_search_console(WP_REST_Request $request): WP_REST_Response|WP_Error { try { $site_url = $request->get_param('site_url'); $setup_result = $this->analytics_manager->setup_search_console_verification($site_url); return new WP_REST_Response([ 'success' => $setup_result['success'], 'data' => $setup_result, 'message' => $setup_result['message'] ], $setup_result['success'] ? 200 : 400); } catch (\Exception $e) { return new WP_Error( 'setup_failed', 'Search Console setup failed: ' . $e->getMessage(), ['status' => 500] ); } } /** * Get indexing status * * @param WP_REST_Request $request Request object * @return WP_REST_Response|WP_Error Response object */ public function get_indexing_status(WP_REST_Request $request): WP_REST_Response|WP_Error { try { $indexing_status = $this->analytics_manager->get_indexing_status(); return new WP_REST_Response([ 'success' => true, 'data' => $indexing_status, 'message' => 'Indexing status retrieved successfully' ], 200); } catch (\Exception $e) { return new WP_Error( 'indexing_status_failed', 'Failed to retrieve indexing status: ' . $e->getMessage(), ['status' => 500] ); } } /** * Refresh cached analytics data * * @param WP_REST_Request $request Request object * @return WP_REST_Response|WP_Error Response object */ public function refresh_data(WP_REST_Request $request): WP_REST_Response|WP_Error { try { $refresh_result = $this->analytics_manager->refresh_data(); return new WP_REST_Response([ 'success' => $refresh_result['success'], 'data' => $refresh_result, 'message' => $refresh_result['message'] ], 200); } catch (\Exception $e) { return new WP_Error( 'refresh_failed', 'Failed to refresh data: ' . $e->getMessage(), ['status' => 500] ); } } /** * Get client status for debugging * * @param WP_REST_Request $request Request object * @return WP_REST_Response|WP_Error Response object */ public function get_client_status(WP_REST_Request $request): WP_REST_Response|WP_Error { try { $client_status = $this->analytics_manager->get_client_status(); return new WP_REST_Response([ 'success' => true, 'data' => $client_status, 'message' => 'Client status retrieved successfully' ], 200); } catch (\Exception $e) { return new WP_Error( 'status_failed', 'Failed to retrieve client status: ' . $e->getMessage(), ['status' => 500] ); } } /** * Get dashboard endpoint arguments * Following ThinkRank argument validation patterns * * @return array Endpoint arguments */ private function get_dashboard_args(): array { return [ 'date_range' => [ 'type' => 'string', 'default' => '30d', 'enum' => ['7d', '30d', '90d'], 'sanitize_callback' => 'sanitize_key', 'description' => 'Date range for analytics data' ] ]; } /** * Get opportunities endpoint arguments * * @return array Endpoint arguments */ private function get_opportunities_args(): array { return [ 'date_range' => [ 'type' => 'string', 'default' => '30d', 'enum' => ['7d', '30d', '90d'], 'sanitize_callback' => 'sanitize_key', 'description' => 'Date range for opportunities analysis' ] ]; } /** * Get setup endpoint arguments * * @return array Endpoint arguments */ private function get_setup_args(): array { return [ 'site_url' => [ 'required' => true, 'type' => 'string', 'sanitize_callback' => 'esc_url_raw', 'validate_callback' => [$this, 'validate_site_url'], 'description' => 'Site URL to verify in Search Console' ] ]; } /** * Validate site URL parameter * Following ThinkRank validation patterns * * @param string $site_url Site URL to validate * @return bool|WP_Error Validation result */ public function validate_site_url(string $site_url): bool|WP_Error { if (empty($site_url)) { return new WP_Error( 'invalid_site_url', 'Site URL is required', ['status' => 400] ); } if (!filter_var($site_url, FILTER_VALIDATE_URL)) { return new WP_Error( 'invalid_site_url', 'Site URL must be a valid URL', ['status' => 400] ); } return true; } /** * Check permissions for API access * Following ThinkRank permission patterns * * @return bool Permission status */ public function check_permissions(): bool { return current_user_can('manage_options'); } // ======================================== // SEO Intelligence Enhancement Endpoints // ======================================== /** * Get intelligent dashboard data with trends and insights * * @param WP_REST_Request $request Request object * @return WP_REST_Response|WP_Error Response object */ public function get_intelligent_dashboard(WP_REST_Request $request): WP_REST_Response|WP_Error { try { $date_range = $request->get_param('date_range'); $intelligent_data = $this->analytics_manager->get_intelligent_dashboard_data($date_range); $success = isset($intelligent_data['success']) ? $intelligent_data['success'] : false; return new WP_REST_Response([ 'success' => $success, 'data' => $intelligent_data['data'] ?? null, 'message' => $intelligent_data['message'] ?? 'Intelligent dashboard data retrieved', 'timestamp' => current_time('mysql') ], 200); // Always return 200 for successful API calls, even when no data available } catch (Exception $e) { return new WP_Error( 'intelligent_dashboard_error', 'Failed to retrieve intelligent dashboard data: ' . $e->getMessage(), ['status' => 500] ); } } /** * Get intelligent SEO opportunities with prioritization * * @param WP_REST_Request $request Request object * @return WP_REST_Response|WP_Error Response object */ public function get_intelligent_opportunities(WP_REST_Request $request): WP_REST_Response|WP_Error { try { $date_range = $request->get_param('date_range'); $intelligent_opportunities = $this->analytics_manager->get_intelligent_seo_opportunities($date_range); $success = isset($intelligent_opportunities['success']) ? $intelligent_opportunities['success'] : false; return new WP_REST_Response([ 'success' => $success, 'data' => $intelligent_opportunities['data'] ?? null, 'message' => $intelligent_opportunities['message'] ?? 'Intelligent opportunities retrieved', 'timestamp' => current_time('mysql') ], 200); // Always return 200 for successful API calls, even when no data available } catch (Exception $e) { return new WP_Error( 'intelligent_opportunities_error', 'Failed to retrieve intelligent opportunities: ' . $e->getMessage(), ['status' => 500] ); } } /** * Get SEO insights * * @param WP_REST_Request $request Request object * @return WP_REST_Response|WP_Error Response object */ public function get_seo_insights(WP_REST_Request $request): WP_REST_Response|WP_Error { try { $date_range = $request->get_param('date_range'); $insights = $this->analytics_manager->get_seo_insights($date_range); $success = isset($insights['success']) ? $insights['success'] : false; return new WP_REST_Response([ 'success' => $success, 'data' => $insights['data'] ?? null, 'cached' => $insights['cached'] ?? false, 'message' => $insights['message'] ?? 'SEO insights retrieved', 'timestamp' => current_time('mysql') ], 200); // Always return 200 for successful API calls, even when no data available } catch (Exception $e) { return new WP_Error( 'seo_insights_error', 'Failed to retrieve SEO insights: ' . $e->getMessage(), ['status' => 500] ); } } }