> */ public static function snapshots_for_current_site(int $site_id): array { if ($site_id <= 0 || $site_id !== (int) get_current_blog_id()) { return []; } $snapshots = []; TheDotDevAgenticBridge_Content_Policy::each_outbound_candidate( static function (WP_Post $post) use (&$snapshots): bool { if (count($snapshots) >= self::MAX_POSTS) { return false; } if (!TheDotDevAgenticBridge_Content_Policy::is_eligible_post($post)) { return true; } $snapshot = self::snapshot_from_post($post); if ($snapshot !== null) { $snapshots[] = $snapshot; } return true; } ); return $snapshots; } /** @return array|null */ private static function snapshot_from_post(WP_Post $post): ?array { $permalink = (string) get_permalink($post); $path = self::path_from_permalink($permalink); $origin = rtrim((string) home_url('/'), '/'); if ($path === '' || $origin === '') { return null; } $content = (string) $post->post_content; return [ 'siteId' => (int) get_current_blog_id(), 'pageId' => (int) $post->ID, 'path' => $path, 'pageType' => $post->post_type === 'page' ? 'page' : 'post', 'status' => 'publish', 'title' => sanitize_text_field((string) get_the_title($post)), 'metaDescription' => self::meta_description($post), // A post query cannot establish the rendered canonical tag. Keep // this unknown rather than making a claim about theme output. 'canonical' => '', 'canonicalKnown' => false, 'robots' => TheDotDevAgenticBridge_Content_Policy::has_post_noindex($post) ? 'noindex' : '', 'headings' => self::headings($content), 'imageMissingAlt' => self::images_missing_alt($content), 'decorativeImages' => 0, 'contentWords' => self::word_count($content), 'snapshotSource' => 'local_post_snapshot', 'snapshotTime' => TheDotDevAgenticBridge_Readiness_Clock::format_mysql_gmt_as_utc_z( get_post_modified_time('Y-m-d H:i:s', true, $post) ), 'scope' => 'indexable', 'exclusions' => [], 'siteOrigin' => $origin, ]; } private static function path_from_permalink(string $permalink): string { $parts = wp_parse_url($permalink); if (!is_array($parts) || isset($parts['query'], $parts['fragment'])) { return ''; } $path = (string) ($parts['path'] ?? '/'); return str_starts_with($path, '/') ? $path : ''; } private static function meta_description(WP_Post $post): string { foreach (['_yoast_wpseo_metadesc', 'rank_math_description', '_aioseo_description'] as $key) { $value = get_post_meta((int) $post->ID, $key, true); if (is_string($value) && trim($value) !== '') { return sanitize_text_field($value); } } return ''; } /** @return list */ private static function headings(string $content): array { preg_match_all('/]*>/i', $content, $matches); return array_map(static fn(string $level): array => ['level' => (int) $level], $matches[1] ?? []); } private static function images_missing_alt(string $content): int { preg_match_all('/]*>/i', $content, $images); $missing = 0; foreach ($images[0] ?? [] as $image) { if (preg_match('/\\balt\\s*=\\s*(["\\\']).*?\\1/i', $image) !== 1) { ++$missing; } } return $missing; } private static function word_count(string $content): int { $plain = trim(wp_strip_all_tags($content)); if ($plain === '') { return 0; } preg_match_all('/[^\\s]+/u', $plain, $words); return min(100000, count($words[0] ?? [])); } }