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' ) );