PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 2.9.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v2.9.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 1.0.2 All 50 releases
thinkrank / includes / seo / email-report-sections / class-top-winning-posts-section.php

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

95 lines 2.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Top Winning Posts Section — "Top growing pages".
4 *
5 * Pages with the largest click gain vs the previous period, computed from
6 * the shared current-vs-previous comparison the Data Provider builds from
7 * Search Console (page dimension).
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 Top_Winning_Posts_Section implements Email_Report_Section_Interface {
23
24 private const MAX_ROWS = 5;
25
26 public function key(): string {
27 return 'top_winning_posts';
28 }
29
30 public function label(): string {
31 return __('Top growing pages', 'thinkrank');
32 }
33
34 public function default_enabled(): bool {
35 return true;
36 }
37
38 public function requires_capability(): ?string {
39 return null;
40 }
41
42 public function renders_own_heading(): bool {
43 return true;
44 }
45
46 public function collect(array $context): array {
47 $shared = $context['shared'] ?? [];
48 $comparison = $shared['comparison'] ?? [];
49 if (empty($comparison['available']) || empty($comparison['pages'])) {
50 return [];
51 }
52
53 // Real gainers: pages whose clicks grew vs the previous period.
54 $rows = [];
55 foreach ($comparison['pages'] as $entry) {
56 $delta = (int) $entry['cur_clicks'] - (int) $entry['prev_clicks'];
57 if ($delta <= 0) {
58 continue;
59 }
60 $rows[] = [
61 'url' => $entry['url'] ?? '',
62 'clicks' => (int) $entry['cur_clicks'],
63 'change' => $delta,
64 ];
65 }
66
67 usort($rows, static fn($a, $b) => $b['change'] <=> $a['change']);
68
69 return [
70 'rows' => array_slice($rows, 0, self::MAX_ROWS),
71 ];
72 }
73
74 public function has_data(array $payload): bool {
75 return !empty($payload['rows']);
76 }
77
78 public function render(array $payload): string {
79 $rows = Top_Posts_Renderer::page_rows($payload['rows'] ?? []);
80 if ($rows === []) {
81 return '';
82 }
83 return Email_Report_Html::heading(
84 $this->label(),
85 __('Pages that gained the most clicks vs the previous period', 'thinkrank')
86 )
87 . Email_Report_Html::list_rows($rows, 'up')
88 . Email_Report_Html::link(__('See all pages', 'thinkrank'), Email_Report_Html::admin_link('analytics', 'dashboard'));
89 }
90
91 public function fallback_html(): string {
92 return '';
93 }
94 }
95