PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 2.10.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v2.10.0
2.10.0 2.9.0 2.8.0 2.7.0 2.6.0 2.5.0 2.4.0 2.3.0 2.2.0 2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.32.0 1.31.0 1.30.0 1.29.0 1.28.0 1.27.0 1.26.0 1.25.0 trunk 1.0.0 1.0.1 All 51 releases
thinkrank / includes / seo / email-report-sections / class-position-summary-section.php

class-position-summary-section.php in ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO 2.10.0, at includes/seo/email-report-sections/class-position-summary-section.php

106 lines 3.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Position Summary Section — "Where your keywords rank".
4 *
5 * Buckets the period's queries into Top 3 / 4–10 / 11–50 / 51–100 and draws
6 * them as bars. Source: GSC `position_distribution` already computed by
7 * Analytics_Manager.
8 *
9 * @package ThinkRank
10 * @subpackage SEO\Email_Report_Sections
11 * @since 1.9.0
12 */
13
14 declare(strict_types=1);
15
16 namespace ThinkRank\SEO\Email_Report_Sections;
17
18 if (!defined('ABSPATH')) {
19 exit;
20 }
21
22 final class Position_Summary_Section implements Email_Report_Section_Interface {
23
24 public function key(): string {
25 return 'position_summary';
26 }
27
28 public function label(): string {
29 return __('Where your keywords rank', 'thinkrank');
30 }
31
32 public function default_enabled(): bool {
33 return true;
34 }
35
36 public function requires_capability(): ?string {
37 return null;
38 }
39
40 public function renders_own_heading(): bool {
41 return true;
42 }
43
44 public function collect(array $context): array {
45 $shared = $context['shared'] ?? [];
46 if (empty($shared['available'])) {
47 return [];
48 }
49 $dist = $shared['current']['search_performance']['position_distribution'] ?? [];
50 if (!is_array($dist) || empty($dist)) {
51 return [];
52 }
53 return [
54 'top_3' => (int) ($dist['top_3'] ?? 0),
55 '4_10' => (int) ($dist['4_10'] ?? 0),
56 '11_50' => (int) ($dist['10_50'] ?? 0), // GSC's `10_50` bucket starts at 11
57 '51_100' => (int) ($dist['51_100'] ?? 0),
58 ];
59 }
60
61 public function has_data(array $payload): bool {
62 return array_sum(array_map('intval', $payload)) > 0;
63 }
64
65 public function render(array $payload): string {
66 $counts = [
67 'top_3' => (int) ($payload['top_3'] ?? 0),
68 '4_10' => (int) ($payload['4_10'] ?? 0),
69 '11_50' => (int) ($payload['11_50'] ?? 0),
70 '51_100' => (int) ($payload['51_100'] ?? 0),
71 ];
72 $total = array_sum($counts);
73 if ($total === 0) {
74 return '';
75 }
76 $page_one = $counts['top_3'] + $counts['4_10'];
77
78 $html = Email_Report_Html::heading(
79 $this->label(),
80 sprintf(
81 /* translators: %s: number of queries. */
82 _n('%s query got at least one impression this period', '%s queries got at least one impression this period', $total, 'thinkrank'),
83 number_format_i18n($total)
84 )
85 );
86 $html .= '<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin-top:14px;">'
87 . Email_Report_Html::bar_row(__('Top 3', 'thinkrank'), $counts['top_3'], $total, Email_Report_Html::PRIMARY)
88 . Email_Report_Html::bar_row(__('Positions 4–10', 'thinkrank'), $counts['4_10'], $total, '#6e79ff')
89 . Email_Report_Html::bar_row(__('Positions 11–50', 'thinkrank'), $counts['11_50'], $total, '#b3b9ff')
90 . Email_Report_Html::bar_row(__('Positions 51–100', 'thinkrank'), $counts['51_100'], $total, '#dcdfff')
91 . '</table>';
92 $html .= Email_Report_Html::note(sprintf(
93 /* translators: %s: number of queries ranking in positions 1–10. */
94 _n('%s query is on page one.', '%s queries are on page one.', $page_one, 'thinkrank'),
95 number_format_i18n($page_one)
96 ));
97 $html .= Email_Report_Html::link(__('See all keywords', 'thinkrank'), Email_Report_Html::admin_link('analytics', 'keywords'));
98
99 return $html;
100 }
101
102 public function fallback_html(): string {
103 return '';
104 }
105 }
106