pick_variant_for_request( (int) $post_id );
if ( is_array( $picked ) && ! empty( $picked['json'] ) ) {
$json = (string) $picked['json'];
$ab_variant_marker = sprintf( ' (A/B test #%d, variant %s)', (int) $picked['test_id'], (string) $picked['variant'] );
$decoded = json_decode( $json, true );
if ( null !== $decoded ) {
echo "\n\n";
echo '' . "\n";
}
return;
}
}
// Lecture du schema stocké en DB (déjà généré par cron / AJAX admin).
$cache_key = 'aiforya_sm_schema_' . $post_id;
$json = get_transient( $cache_key );
if ( false === $json ) {
// Pas de cache → tente lecture DB (sans appel LLM).
if ( class_exists( 'Aiforya_Schema_Markup_Db' ) ) {
$db = Aiforya_Schema_Markup_Db::get_instance();
$schema = method_exists( $db, 'get_active_schema_for_post' )
? $db->get_active_schema_for_post( $post_id )
: null;
if ( is_array( $schema ) && ! empty( $schema['schema_json'] ) ) {
$json = (string) $schema['schema_json'];
$ttl = (int) ( $settings['cache_ttl_minutes'] ?? 1440 ) * MINUTE_IN_SECONDS;
set_transient( $cache_key, $json, max( 300, $ttl ) );
}
}
}
if ( ! is_string( $json ) || '' === $json ) {
return;
}
// Validation JSON minimale avant injection.
$decoded = json_decode( $json, true );
if ( null === $decoded ) {
return;
}
// F12 — WPML/Polylang : ajout auto du champ inLanguage si absent.
$decoded = $this->maybe_add_in_language( $decoded, $post_id );
$json = wp_json_encode( $decoded, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
echo "\n\n";
echo '' . "\n";
// Multi-schema : injecte les schémas additionnels (slot != 'primary') si activés pour ce post.
$this->maybe_inject_secondary_schemas( $post_id );
}
/**
* F12 — Détection langue WPML/Polylang/site et ajout du champ inLanguage.
*/
private function maybe_add_in_language( array $data, int $post_id ): array {
if ( isset( $data['inLanguage'] ) ) return $data;
$lang = '';
// WPML
if ( function_exists( 'apply_filters' ) ) {
// This is WPML's own public API hook: the name is imposed by WPML and must not be
// prefixed, otherwise WPML would never answer. We consume it, we do not define it.
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- third-party hook defined by WPML; renaming it would break the integration.
$wpml = apply_filters( 'wpml_post_language_details', null, $post_id );
if ( is_array( $wpml ) && ! empty( $wpml['language_code'] ) ) {
$lang = (string) $wpml['language_code'];
}
}
// Polylang
if ( $lang === '' && function_exists( 'pll_get_post_language' ) ) {
$pll = pll_get_post_language( $post_id );
if ( is_string( $pll ) && $pll !== '' ) $lang = $pll;
}
// Fallback site default
if ( $lang === '' ) {
$site_lang = get_bloginfo( 'language' );
if ( is_string( $site_lang ) && $site_lang !== '' ) $lang = strtolower( substr( $site_lang, 0, 2 ) );
}
if ( $lang !== '' ) $data['inLanguage'] = $lang;
return $data;
}
/**
* Multi-schema per post — injecte les schémas additionnels stockés avec slot != 'primary'.
* Doctrine PRIO 10 : lecture seule DB, pas d'appel LLM.
*/
private function maybe_inject_secondary_schemas( int $post_id ): void {
global $wpdb;
$table = $wpdb->prefix . 'aiforya_sm_schemas';
$rows = $wpdb->get_results( $wpdb->prepare(
"SELECT schema_json FROM %i WHERE post_id = %d AND status = 'active' AND is_primary = 0 LIMIT 5", $table,
$post_id
) );
if ( empty( $rows ) ) return;
foreach ( $rows as $r ) {
$json = (string) ( $r->schema_json ?? '' );
if ( $json === '' ) continue;
$decoded = json_decode( $json, true );
if ( null === $decoded ) continue;
$decoded = $this->maybe_add_in_language( $decoded, $post_id );
$json = wp_json_encode( $decoded, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
echo "\n\n";
echo '' . "\n";
}
}
}