get_supported_post_types(); $current_type = sanitize_key($this->get_query_value('seo_post_type', 'all')); if ('all' !== $current_type && !in_array($current_type, $post_types, true)) { $current_type = 'all'; } $score_bucket = sanitize_key($this->get_query_value('seo_score_bucket')); $issue_filter = sanitize_key($this->get_query_value('seo_issue')); $search_term = $this->get_query_value('s'); $paged = max(1, $this->get_query_int('paged', 1)); $per_page = isset($settings['dashboard_page_size']) ? max(10, (int) $settings['dashboard_page_size']) : 20; $query = $this->get_filtered_query($post_types, $current_type, $score_bucket, $issue_filter, $search_term, $paged, $per_page); $stats = $this->get_dashboard_stats($post_types); $base_url = admin_url('tools.php?page=kbyte-seo-workbench'); $query_posts = (isset($query->posts) && is_array($query->posts)) ? $query->posts : array(); $max_num_pages = (isset($query->max_num_pages) && is_numeric($query->max_num_pages)) ? (int) $query->max_num_pages : 1; ?>

/100

ID, '_KSWB_Analyzer_score', true); $issue = (string) get_post_meta($post->ID, '_KSWB_Analyzer_primary_issue', true); $inbound = (int) get_post_meta($post->ID, '_KSWB_Analyzer_inbound_internal_links', true); $broken = (int) get_post_meta($post->ID, '_KSWB_Analyzer_broken_link_count', true); $edit_link = $this->get_admin_edit_link($post->ID); $post_title = $this->get_post_display_title($post->ID); $checkbox_id = 'kbyte-seo-workbench-post-check-' . (int) $post->ID; ?>
|
get_post_type_label($post->post_type)); ?> render_score_badge($score)); ?> get_issue_label($issue)); ?> post_modified)); ?>
add_query_arg('paged', '%#%'), 'format' => '', 'current' => $paged, 'total' => max(1, $max_num_pages), 'type' => 'array', )); if (!empty($pagination)) : ?>
0, 'average_score' => 0, 'healthy_items' => 0, 'orphan_items' => 0, ); } $ids = get_posts(array( 'post_type' => $post_types, 'post_status' => 'publish', 'posts_per_page' => -1, 'fields' => 'ids', 'orderby' => 'ID', 'order' => 'ASC', )); $total_items = count($ids); $total_score = 0; $scored_items = 0; $healthy_items = 0; $orphan_items = 0; if (!empty($ids)) { update_meta_cache('post', $ids); foreach ($ids as $post_id) { $score = get_post_meta($post_id, '_KSWB_Analyzer_score', true); if ('' !== $score && is_numeric($score)) { $score = (int) $score; $total_score += $score; $scored_items++; if ($score >= 80) { $healthy_items++; } } if ('1' === get_post_meta($post_id, '_KSWB_Analyzer_is_orphan', true)) { $orphan_items++; } } } return array( 'total_items' => $total_items, 'average_score' => $scored_items > 0 ? (int) round($total_score / $scored_items) : 0, 'healthy_items' => $healthy_items, 'orphan_items' => $orphan_items, ); } private function get_filtered_query($post_types, $current_type, $score_bucket, $issue_filter, $search_term, $paged, $per_page) { $candidate_ids = get_posts(array( 'post_type' => ('all' === $current_type) ? $post_types : array($current_type), 'post_status' => 'publish', 'posts_per_page' => -1, 'fields' => 'ids', 'orderby' => 'modified', 'order' => 'DESC', 's' => $search_term, )); $filtered_ids = array(); if (!empty($candidate_ids)) { update_meta_cache('post', $candidate_ids); foreach ($candidate_ids as $post_id) { if (!$this->matches_score_bucket($post_id, $score_bucket)) { continue; } if (!$this->matches_issue_filter($post_id, $issue_filter)) { continue; } $filtered_ids[] = (int) $post_id; } } $total = count($filtered_ids); $offset = max(0, ($paged - 1) * $per_page); $page_ids = array_slice($filtered_ids, $offset, $per_page); $posts = array(); if (!empty($page_ids)) { $posts = get_posts(array( 'post_type' => ('all' === $current_type) ? $post_types : array($current_type), 'post_status' => 'publish', 'post__in' => $page_ids, 'posts_per_page' => count($page_ids), 'orderby' => 'post__in', )); } return (object) array( 'posts' => $posts, 'max_num_pages' => max(1, (int) ceil($total / $per_page)), ); } private function matches_score_bucket($post_id, $score_bucket) { if ('' === $score_bucket) { return true; } $score = get_post_meta($post_id, '_KSWB_Analyzer_score', true); if ('' === $score || !is_numeric($score)) { return ('unanalyzed' === $score_bucket); } $score = (int) $score; if ('good' === $score_bucket) { return $score >= 80; } if ('medium' === $score_bucket) { return ($score >= 60 && $score <= 79); } if ('poor' === $score_bucket) { return $score < 60; } return true; } private function matches_issue_filter($post_id, $issue_filter) { if ('' === $issue_filter) { return true; } $map = array( 'missing_meta_title' => array('_KSWB_Analyzer_has_meta_title', '0'), 'missing_meta_description' => array('_KSWB_Analyzer_has_meta_description', '0'), 'orphan' => array('_KSWB_Analyzer_is_orphan', '1'), 'cornerstone' => array('_KSWB_Analyzer_cornerstone_needs_work', '1'), 'broken_links' => array('_KSWB_Analyzer_has_broken_links', '1'), 'noindex' => array('_KSWB_Analyzer_is_noindex', '1'), ); if (!isset($map[$issue_filter])) { return true; } return get_post_meta($post_id, $map[$issue_filter][0], true) === $map[$issue_filter][1]; } private function get_query_value($key, $default = '') { $value = filter_input(INPUT_GET, $key, FILTER_UNSAFE_RAW); return is_string($value) ? sanitize_text_field(wp_unslash($value)) : $default; } private function get_query_int($key, $default = 0) { $value = filter_input(INPUT_GET, $key, FILTER_VALIDATE_INT); return (false !== $value && null !== $value) ? absint($value) : $default; } private function get_admin_edit_link($post_id) { $post_id = absint($post_id); if ($post_id <= 0) { return admin_url('edit.php'); } return add_query_arg( array( 'post' => $post_id, 'action' => 'edit', ), admin_url('post.php') ); } private function get_post_type_label($post_type) { $object = get_post_type_object($post_type); if ($object && isset($object->labels->singular_name) && is_string($object->labels->singular_name) && '' !== $object->labels->singular_name) { return $object->labels->singular_name; } if ($object && isset($object->label) && is_string($object->label) && '' !== $object->label) { return $object->label; } return ucwords(str_replace(array('-', '_'), ' ', (string) $post_type)); } private function get_post_display_title($post_id) { $title = get_the_title($post_id); if (is_string($title) && '' !== trim($title)) { return $title; } return sprintf( /* translators: %d: post ID. */ __('Untitled (#%d)', 'kbyte-seo-workbench'), (int) $post_id ); } private function render_score_badge($score) { if ('' === $score || !is_numeric($score)) { return '' . esc_html__('Not analyzed', 'kbyte-seo-workbench') . ''; } $score = (int) $score; return '' . esc_html($score . '/100') . ''; } private function get_issue_label($issue) { $labels = array( 'missing_meta_title' => __('Missing meta title', 'kbyte-seo-workbench'), 'missing_meta_description' => __('Missing meta description', 'kbyte-seo-workbench'), 'missing_focus_keyword' => __('Missing focus keyword', 'kbyte-seo-workbench'), 'orphan' => __('Orphan page', 'kbyte-seo-workbench'), 'broken_links' => __('Broken outgoing links', 'kbyte-seo-workbench'), 'noindex' => __('Noindex enabled', 'kbyte-seo-workbench'), 'cornerstone' => __('Cornerstone content', 'kbyte-seo-workbench'), 'thin_content' => __('Thin content', 'kbyte-seo-workbench'), 'keyword_placement' => __('Keyword placement', 'kbyte-seo-workbench'), 'keyword_density' => __('Keyword density', 'kbyte-seo-workbench'), 'links' => __('Link coverage', 'kbyte-seo-workbench'), 'canonical' => __('Canonical issue', 'kbyte-seo-workbench'), 'readability' => __('Readability', 'kbyte-seo-workbench'), 'healthy' => __('Healthy', 'kbyte-seo-workbench'), 'general' => __('General improvements', 'kbyte-seo-workbench'), ); return isset($labels[$issue]) ? $labels[$issue] : __('Not analyzed', 'kbyte-seo-workbench'); } private function get_score_color($score) { if ($score >= 80) { return '#1f9d55'; } if ($score >= 60) { return '#d97706'; } return '#dc2626'; } }