post_title ); ?> post_type ) ); ?>
true, ), 'objects' ); $available = array(); foreach ( $post_types as $post_type ) { // Skip attachments if ( $post_type->name === 'attachment' ) { continue; } $available[ $post_type->name ] = $post_type->labels->name; } return $available; } /** * Get posts with calculated scores. * * @param string $post_type Post type filter. * @param string $score_filter Score filter. * @param string $orderby Order by field. * @param string $order Order direction. * @return array Posts with score data. */ private static function get_posts_with_scores( $post_type, $score_filter, $orderby, $order ) { // Get all available post types for 'all' filter $query_post_types = $post_type; if ( $post_type === 'all' ) { $available = self::get_available_post_types(); $query_post_types = array_keys( $available ); } // Query args $args = array( 'post_type' => $query_post_types, 'post_status' => 'publish', 'posts_per_page' => -1, 'orderby' => 'date', 'order' => 'DESC', ); $query = new WP_Query( $args ); $posts_data = array(); if ( $query->have_posts() ) { while ( $query->have_posts() ) { $query->the_post(); $post = get_post(); // Calculate score using Ultimate Score if available, fallback to legacy Score $score_data = array(); if ( class_exists( 'AI_Answer_Toolkit_Ultimate_Score' ) ) { $ultimate_score = AI_Answer_Toolkit_Ultimate_Score::calculate_ultimate_score( $post->ID ); $score_data = array( 'score' => $ultimate_score['score'], 'color' => $ultimate_score['color'], 'label' => $ultimate_score['label'], 'summary_type' => AI_Answer_Toolkit_Summary::get_summary_type( $post->ID ), 'breakdown' => isset( $ultimate_score['breakdown'] ) ? $ultimate_score['breakdown'] : array(), 'issues' => isset( $ultimate_score['issues'] ) ? $ultimate_score['issues'] : array(), ); } else { $score_data = AI_Answer_Toolkit_Score::calculate_score( $post->ID ); } // Apply score filter if ( $score_filter !== 'all' ) { if ( $score_filter === 'excellent' && $score_data['score'] < 80 ) { continue; } if ( $score_filter === 'needs_improvement' && ( $score_data['score'] < 50 || $score_data['score'] >= 80 ) ) { continue; } if ( $score_filter === 'poor' && $score_data['score'] >= 50 ) { continue; } } // Get FAQ count $faq_count = AI_Answer_Toolkit_Score::get_faq_count( $post->ID ); $posts_data[] = array( 'post' => $post, 'score_data' => $score_data, 'faq_count' => $faq_count, ); } wp_reset_postdata(); } // Sort posts usort( $posts_data, function( $a, $b ) use ( $orderby, $order ) { $result = 0; switch ( $orderby ) { case 'score': $result = $a['score_data']['score'] - $b['score_data']['score']; break; case 'title': $result = strcmp( $a['post']->post_title, $b['post']->post_title ); break; case 'type': $result = strcmp( $a['post']->post_type, $b['post']->post_type ); break; } return $order === 'asc' ? $result : -$result; }); return $posts_data; } /** * Calculate statistics from posts data. * * @param array $posts Posts with score data. * @return array Statistics. */ private static function calculate_statistics( $posts ) { $stats = array( 'excellent' => 0, 'needs_improvement' => 0, 'poor' => 0, 'average_score' => 0, ); if ( empty( $posts ) ) { return $stats; } $total_score = 0; foreach ( $posts as $post_data ) { $score = $post_data['score_data']['score']; $total_score += $score; if ( $score >= 80 ) { $stats['excellent']++; } elseif ( $score >= 50 ) { $stats['needs_improvement']++; } else { $stats['poor']++; } } $stats['average_score'] = $total_score / count( $posts ); return $stats; } /** * Render score badge. * * @param array $score_data Score data. */ private static function render_score_badge( $score_data ) { $score = $score_data['score']; $color = $score_data['color']; $label = AI_Answer_Toolkit_Score::get_score_label( $color ); $class = 'aeo-score-badge aeo-score-badge-' . $color; echo ''; echo '' . esc_html( $score ) . '/100'; echo ''; } /** * Render summary type badge. * * @param string $summary_type Summary type. */ private static function render_summary_badge( $summary_type ) { $badges = array( 'manual' => array( 'label' => __( 'Manual', 'ai-answer-toolkit' ), 'class' => 'aeo-badge-manual', ), 'auto' => array( 'label' => __( 'Auto', 'ai-answer-toolkit' ), 'class' => 'aeo-badge-auto', ), 'none' => array( 'label' => __( 'None', 'ai-answer-toolkit' ), 'class' => 'aeo-badge-none', ), ); $badge = isset( $badges[ $summary_type ] ) ? $badges[ $summary_type ] : $badges['none']; echo ''; echo esc_html( $badge['label'] ); echo ''; } /** * Get sort URL. * * @param string $column Column to sort by. * @param string $orderby Current orderby. * @param string $order Current order. * @return string Sort URL. */ private static function get_sort_url( $column, $orderby, $order ) { $new_order = ( $orderby === $column && $order === 'desc' ) ? 'asc' : 'desc'; $args = array( 'page' => 'ai-answer-toolkit-reporting', 'orderby' => $column, 'order' => $new_order, ); // phpcs:disable WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['aitk_post_type'] ) ) { $args['aitk_post_type'] = sanitize_text_field( wp_unslash( $_GET['aitk_post_type'] ) ); } if ( isset( $_GET['score_filter'] ) ) { $args['score_filter'] = sanitize_text_field( wp_unslash( $_GET['score_filter'] ) ); } // phpcs:enable WordPress.Security.NonceVerification.Recommended return add_query_arg( $args, admin_url( 'admin.php' ) ); } /** * Render sort indicator. * * @param string $column Column name. * @param string $orderby Current orderby. * @param string $order Current order. */ private static function render_sort_indicator( $column, $orderby, $order ) { if ( $orderby === $column ) { $icon = $order === 'asc' ? 'arrow-up' : 'arrow-down'; echo ''; } } /** * Render audit report table. * * @param array $posts Posts data. */ private static function render_audit_report_table( $posts ) { // Get top 5 posts needing improvement (lowest scores) $posts_sorted = $posts; usort( $posts_sorted, function( $a, $b ) { return $a['score_data']['score'] - $b['score_data']['score']; }); $top_needs_improvement = array_slice( $posts_sorted, 0, 5 ); $top_ids = array_map( function( $p ) { return $p['post']->ID; }, $top_needs_improvement ); ?>
ID, $top_ids, true ); $row_class = $is_priority ? 'aeo-priority-row' : ''; $warnings_count = count( $post_data['score_data']['issues'] ); ?>
post_title ); ?> post_type ) ); ?> 0 ) : ?>
getMessage() ); } wp_die( '

' . esc_html__( 'PDF Generation Error', 'ai-answer-toolkit' ) . '

' . '

' . esc_html__( 'Unable to generate PDF. Error details:', 'ai-answer-toolkit' ) . '

' . '
' . esc_html( $e->getMessage() ) . '
' . '

' . esc_html__( 'Solution:', 'ai-answer-toolkit' ) . ' ' . esc_html__( 'Install TCPDF library by running "composer install" in the plugin directory, or the system will use browser print fallback.', 'ai-answer-toolkit' ) . '

', esc_html__( 'PDF Generation Error', 'ai-answer-toolkit' ), array( 'back_link' => true ) ); } } } // Initialize dashboard AI_Answer_Toolkit_Dashboard::init(); // Register AJAX handler for PDF download add_action( 'wp_ajax_aitk_download_audit_pdf', array( 'AI_Answer_Toolkit_Dashboard', 'handle_pdf_download' ) );