self::check_summary_visibility( $post_id ), 'article' => self::check_article_schema( $post_id ), 'faq' => self::check_faq_schema( $post_id ), 'placement' => self::check_summary_placement( $post_id ), ); // Calculate visibility score (0-100) $score = self::calculate_visibility_score( $checks ); // Generate warnings and recommendations $warnings = self::generate_warnings( $checks ); // Generate AI preview snippet $preview = self::generate_preview_snippet( $post_id ); return array( 'checks' => $checks, 'score' => $score, 'warnings' => $warnings, 'preview' => $preview, ); } /** * Check if summary exists and is visible. * * @param int $post_id Post ID. * @return array Check result. */ private static function check_summary_visibility( $post_id ) { $final_summary = AI_Answer_Toolkit_Summary::get_final_summary( $post_id ); $summary_type = AI_Answer_Toolkit_Summary::get_summary_type( $post_id ); if ( ! empty( $final_summary ) ) { return array( 'status' => 'pass', 'message' => sprintf( // translators: %s is the type of summary (manual or auto). __( 'Summary is visible (%s)', 'ai-answer-toolkit' ), ucfirst( $summary_type ) ), ); } return array( 'status' => 'fail', 'message' => __( 'No summary found', 'ai-answer-toolkit' ), ); } /** * Check if Article schema is present. * * @param int $post_id Post ID. * @return array Check result. */ private static function check_article_schema( $post_id ) { $post = get_post( $post_id ); if ( ! $post ) { return array( 'status' => 'fail', 'message' => __( 'Post not found', 'ai-answer-toolkit' ), ); } // Check if post type supports Article schema $supported_types = array( 'post', 'page' ); if ( in_array( $post->post_type, $supported_types, true ) ) { return array( 'status' => 'pass', 'message' => __( 'Article schema enabled', 'ai-answer-toolkit' ), ); } return array( 'status' => 'warning', 'message' => __( 'Article schema not applicable', 'ai-answer-toolkit' ), ); } /** * Check if FAQ schema is present. * * @param int $post_id Post ID. * @return array Check result. */ private static function check_faq_schema( $post_id ) { $faq_count = AI_Answer_Toolkit_Score::get_faq_count( $post_id ); if ( $faq_count > 0 ) { return array( 'status' => 'pass', 'message' => sprintf( /* translators: %d: Number of FAQ items */ __( '%d FAQ items found', 'ai-answer-toolkit' ), $faq_count ), ); } return array( 'status' => 'warning', 'message' => __( 'No FAQ schema found', 'ai-answer-toolkit' ), ); } /** * Check if summary placement is correct. * * @param int $post_id Post ID. * @return array Check result. */ private static function check_summary_placement( $post_id ) { $final_summary = AI_Answer_Toolkit_Summary::get_final_summary( $post_id ); if ( empty( $final_summary ) ) { return array( 'status' => 'fail', 'message' => __( 'No summary to place', 'ai-answer-toolkit' ), ); } // Check if summary is at least 50 characters if ( strlen( wp_strip_all_tags( $final_summary ) ) >= 50 ) { return array( 'status' => 'pass', 'message' => __( 'Summary length is optimal', 'ai-answer-toolkit' ), ); } return array( 'status' => 'warning', 'message' => __( 'Summary is too short', 'ai-answer-toolkit' ), ); } /** * Calculate visibility score based on checks. * * @param array $checks Visibility checks. * @return int Score (0-100). */ private static function calculate_visibility_score( $checks ) { $score = 0; $weights = array( 'summary' => 40, // Most important 'article' => 25, 'faq' => 20, 'placement' => 15, ); foreach ( $checks as $key => $check ) { if ( $check['status'] === 'pass' ) { $score += $weights[ $key ]; } elseif ( $check['status'] === 'warning' ) { $score += $weights[ $key ] * 0.5; // Half points for warnings } } return (int) $score; } /** * Generate warnings and recommendations. * * @param array $checks Visibility checks. * @return array Warnings. */ private static function generate_warnings( $checks ) { $warnings = array(); if ( $checks['summary']['status'] === 'fail' ) { $warnings[] = array( 'severity' => 'error', 'icon' => 'dashicons-warning', 'message' => __( 'Add a summary to improve AI crawler visibility', 'ai-answer-toolkit' ), ); } if ( $checks['faq']['status'] === 'warning' ) { $warnings[] = array( 'severity' => 'warning', 'icon' => 'dashicons-info', 'message' => __( 'Consider adding FAQ blocks to enhance content structure', 'ai-answer-toolkit' ), ); } if ( $checks['placement']['status'] === 'warning' ) { $warnings[] = array( 'severity' => 'warning', 'icon' => 'dashicons-info', 'message' => __( 'Expand your summary to at least 50 characters', 'ai-answer-toolkit' ), ); } return $warnings; } /** * Generate AI preview snippet. * * @param int $post_id Post ID. * @return string HTML preview. */ private static function generate_preview_snippet( $post_id ) { $post = get_post( $post_id ); $final_summary = AI_Answer_Toolkit_Summary::get_final_summary( $post_id ); if ( ! $post ) { return '

' . esc_html__( 'Post not found', 'ai-answer-toolkit' ) . '

'; } $title = get_the_title( $post_id ); $excerpt = ! empty( $final_summary ) ? wp_trim_words( wp_strip_all_tags( $final_summary ), 30 ) : wp_trim_words( $post->post_content, 30 ); $preview = '
'; $preview .= '' . esc_html( $title ) . ''; $preview .= '

' . esc_html( $excerpt ) . '

'; $preview .= '
'; return $preview; } /** * Get score color class. * * @param int $score Visibility score. * @return string Color class. */ public static function get_score_color( $score ) { if ( $score >= 80 ) { return 'green'; } elseif ( $score >= 50 ) { return 'yellow'; } else { return 'red'; } } /** * Get score label. * * @param int $score Visibility score. * @return string Score label. */ public static function get_score_label( $score ) { if ( $score >= 80 ) { return __( 'Excellent Visibility', 'ai-answer-toolkit' ); } elseif ( $score >= 50 ) { return __( 'Good Visibility', 'ai-answer-toolkit' ); } else { return __( 'Poor Visibility', 'ai-answer-toolkit' ); } } }