engine = AI_Explainer_Pro_Detection_Engine::get_instance();
}
public function render() {
global $wpdb;
$this->ensure_history_table();
$this->handle_actions();
$history_table = $wpdb->prefix . 'ai_explainer_scan_history';
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,PluginCheck.Security.DirectDB.UnescapedDBParameter -- Plugin-owned table name; built from $wpdb->prefix and a hardcoded suffix, no user input.
$history = $wpdb->get_results( "SELECT * FROM {$history_table} ORDER BY scan_date DESC LIMIT 10" );
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Aggregate read on demand; staleness from cache would be misleading after a fresh scan.
$total_posts = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_key = '_ai_explainer_scanned_date'" );
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
$human_posts = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_key = '_ai_explainer_human_score' AND CAST(meta_value AS DECIMAL(5,2)) >= %f", 0.7 ) );
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
$ai_posts = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_key = '_ai_explainer_human_score' AND CAST(meta_value AS DECIMAL(5,2)) < %f", 0.4 ) );
$uncertain = $total_posts - $human_posts - $ai_posts;
$never_used = ( 0 === (int) $total_posts );
?>
0 ) : ?>
render_content_table( 'human' ); ?>
render_content_table( 'ai' ); ?>
clear_history();
echo '' .
esc_html__( 'Scan history cleared.', 'ai-explainer-pro' ) . '
';
}
}
private function render_content_table( $type ) {
global $wpdb;
if ( 'human' === $type ) {
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Aggregate read on postmeta for dashboard table.
$results = $wpdb->get_results( $wpdb->prepare(
"SELECT p.ID, p.post_title, pm.meta_value as human_score
FROM {$wpdb->posts} p
INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = '_ai_explainer_human_score'
WHERE p.post_status = 'publish'
ORDER BY CAST(pm.meta_value AS DECIMAL(5,3)) DESC
LIMIT %d",
10
) );
} else {
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Aggregate read on postmeta for dashboard table.
$results = $wpdb->get_results( $wpdb->prepare(
"SELECT p.ID, p.post_title, pm.meta_value as human_score
FROM {$wpdb->posts} p
INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = '_ai_explainer_human_score'
WHERE p.post_status = 'publish'
ORDER BY CAST(pm.meta_value AS DECIMAL(5,3)) ASC
LIMIT %d",
10
) );
}
if ( empty( $results ) ) {
echo '' . esc_html__( 'No data available.', 'ai-explainer-pro' ) . '
';
return;
}
?>
|
|
|
human_score );
$pct = round( $score * 100 );
if ( $score >= 0.7 ) {
$cls = 'high'; $label = __( 'Human', 'ai-explainer-pro' );
} elseif ( $score >= 0.4 ) {
$cls = 'medium'; $label = __( 'Uncertain', 'ai-explainer-pro' );
} else {
$cls = 'low'; $label = __( 'AI', 'ai-explainer-pro' );
}
?>
| post_title ); ?> |
% |
|
prefix . 'ai_explainer_scan_history';
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange,WordPress.DB.PreparedSQL.InterpolatedNotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- Plugin-owned table, name built from $wpdb->prefix; user-triggered admin action to truncate plugin history.
$wpdb->query( "TRUNCATE TABLE {$table}" );
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Bulk delete of plugin-owned post meta; admin action.
$wpdb->query( "DELETE FROM {$wpdb->postmeta} WHERE meta_key IN ('_ai_explainer_scanned_date','_ai_explainer_human_score','_ai_explainer_ai_score','_ai_explainer_detection_data')" );
}
private function ensure_history_table() {
global $wpdb;
$table = $wpdb->prefix . 'ai_explainer_scan_history';
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Existence check is one-off per page load.
if ( $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $table ) ) !== $table ) {
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
$charset = $wpdb->get_charset_collate();
dbDelta( "CREATE TABLE {$table} (
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
scan_date datetime NOT NULL,
total_scanned int(11) DEFAULT 0,
scan_results longtext,
user_id bigint(20) DEFAULT 0,
PRIMARY KEY (id),
KEY scan_date (scan_date)
) {$charset};" );
}
}
}