$sections * @return array */ public static function assess_sections(array $sections, bool $content_is_public): array { if (!$content_is_public) { return [ 'version' => self::VERSION, 'source' => 'local_content_structure', 'networkRequests' => 0, 'questionSectionsFound' => 0, 'reviewNeeded' => 0, 'status' => 'not_applicable', 'reason' => 'content_not_public', 'items' => [], 'limitation' => 'Private, draft, password-protected, and otherwise ineligible content is not assessed.', ]; } $items = []; foreach (array_slice($sections, 0, self::MAX_SECTIONS) as $section) { $heading = sanitize_text_field((string) ($section['heading'] ?? '')); if (!self::is_question_heading($heading)) { continue; } $lead = trim(wp_strip_all_tags((string) ($section['leadText'] ?? ''))); $lead_tag = strtolower(sanitize_key((string) ($section['leadTag'] ?? ''))); if ($lead === '') { $items[] = self::item($heading, 'review_needed', 'no_immediate_answer_text'); continue; } if (!in_array($lead_tag, ['p', 'ul', 'ol', 'blockquote'], true)) { $items[] = self::item($heading, 'review_needed', 'answer_container_needs_review'); continue; } $lead_length = function_exists('mb_strlen') ? mb_strlen($lead) : strlen($lead); if ($lead_length > self::MAX_LEAD_CHARS) { $items[] = self::item($heading, 'review_needed', 'lead_answer_is_long'); continue; } $items[] = self::item($heading, 'observed', 'answer_text_follows_heading'); } $review_count = count(array_filter( $items, static fn (array $item): bool => ($item['status'] ?? '') === 'review_needed', )); return [ 'version' => self::VERSION, 'source' => 'local_content_structure', 'networkRequests' => 0, 'questionSectionsFound' => count($items), 'reviewNeeded' => $review_count, 'status' => $items === [] ? 'not_applicable' : ($review_count > 0 ? 'review_needed' : 'observed'), 'items' => $items, 'limitation' => 'Structure only; this does not judge answer quality or predict AI citation.', ]; } /** @return array{heading: string, status: string, reason: string} */ private static function item(string $heading, string $status, string $reason): array { return [ 'heading' => function_exists('mb_substr') ? mb_substr($heading, 0, 160) : substr($heading, 0, 160), 'status' => $status, 'reason' => $reason, ]; } private static function is_question_heading(string $heading): bool { if ($heading === '') { return false; } if (str_ends_with($heading, '?')) { return true; } return preg_match('/^(who|what|when|where|why|how|can|could|do|does|is|are|should|will|would)\b/i', $heading) === 1; } }