(int) ($dist['top_3'] ?? 0), '4_10' => (int) ($dist['4_10'] ?? 0), '11_50' => (int) ($dist['10_50'] ?? 0), // GSC's `10_50` bucket starts at 11 '51_100' => (int) ($dist['51_100'] ?? 0), // Counted over the whole property since #913. A payload cached // before then has neither key and reads as before. 'over_100' => (int) ($dist['over_100'] ?? 0), 'complete' => (bool) ($dist['complete'] ?? true), ]; } public function has_data(array $payload): bool { $counts = array_intersect_key($payload, array_flip(['top_3', '4_10', '11_50', '51_100', 'over_100'])); return array_sum(array_map('intval', $counts)) > 0; } public function render(array $payload): string { $counts = [ 'top_3' => (int) ($payload['top_3'] ?? 0), '4_10' => (int) ($payload['4_10'] ?? 0), '11_50' => (int) ($payload['11_50'] ?? 0), '51_100' => (int) ($payload['51_100'] ?? 0), ]; // The bars share out the top 100; queries ranked past it still had // an impression, so they count toward the headline total (#913). $ranked = array_sum($counts); $over_100 = max(0, (int) ($payload['over_100'] ?? 0)); $total = $ranked + $over_100; if ($total === 0) { return ''; } $page_one = $counts['top_3'] + $counts['4_10']; // Incomplete means Search Console could not be paged to the end, so // the count covers the top of the property by clicks, not all of it. $subtitle = (bool) ($payload['complete'] ?? true) ? sprintf( /* translators: %s: number of queries. */ _n('%s query got at least one impression this period', '%s queries got at least one impression this period', $total, 'thinkrank'), number_format_i18n($total) ) : sprintf( /* translators: %s: number of queries counted. */ _n('Counted over your top %s query by clicks this period', 'Counted over your top %s queries by clicks this period', $total, 'thinkrank'), number_format_i18n($total) ); $html = Email_Report_Html::heading($this->label(), $subtitle); $html .= '