> */ public static function faq_items( int $post_id ): array { $raw = get_post_meta( $post_id, '_airanksuite_faq', true ); if ( ! is_string( $raw ) || '' === $raw ) { return array(); } $decoded = json_decode( $raw, true ); return is_array( $decoded ) ? $decoded : array(); } /** The run id of the last completed link scan, or null when none finished. */ public static function linkscan_run_id(): ?string { $last = get_option( self::LINKSCAN_LAST ); if ( is_array( $last ) && isset( $last['run_id'] ) ) { return (string) $last['run_id']; } $job = get_option( self::LINKSCAN_JOB ); if ( is_array( $job ) && 'done' === ( $job['state'] ?? '' ) && isset( $job['run_id'] ) ) { return (string) $job['run_id']; } return null; } /** * The two values that limit a link query to the published scan. * * The caller writes the scope into its own statement as a literal — * `( %d = 1 AND run_id = %s )` — and binds this pair to it. With no * completed scan the flag is 0 and the scope matches no rows rather than * every row, because a half-finished scan must never be read as the * site's state. * * @return array{0: int, 1: string} */ public static function linkscan_scope(): array { $run = self::linkscan_run_id(); return array( null === $run ? 0 : 1, (string) $run ); } }