, * durée du cache frontend, option de nettoyage à la désinstallation. Aucune clé * API, aucun fournisseur IA, aucun service externe. * * Charte AIFORYA (thème sombre, zéro emoji, zéro classe inventée, boutons * WordPress standard `button button-primary`, notifications via AiforyaToast). * * @package aiforya-schema-markup */ if ( ! defined( 'ABSPATH' ) ) { exit; } if ( class_exists( 'Aiforya_Schema_Markup_Tab_Settings', false ) ) { return; } class Aiforya_Schema_Markup_Tab_Settings extends Aiforya_Schema_Tab { public function slug(): string { return 'settings'; } public function label(): string { return __( 'Settings', 'aiforya-schema-markup' ); } public function order(): int { return 40; } public function render( array $args = array() ): void { $settings = get_option( 'aiforya_sm_settings', array() ); $advanced = get_option( 'aiforya_sm_advanced', array() ); if ( ! is_array( $settings ) ) { $settings = array(); } if ( ! is_array( $advanced ) ) { $advanced = array(); } $auto_inject = ! empty( $settings['auto_inject_enabled'] ); $cache_ttl = (int) ( $settings['cache_ttl_minutes'] ?? 1440 ); if ( $cache_ttl < 60 ) { $cache_ttl = 60; } elseif ( $cache_ttl > 43200 ) { $cache_ttl = 43200; } $cleanup_opt_in = ! empty( $advanced['cleanup_on_uninstall'] ); $nonce = wp_create_nonce( 'aiforya_sm_admin_nonce' ); /* * V786-B — le comportement part par wp_add_inline_script() (grief n°2 de wordpress.org, * compté ERREUR par le Plugin Check). NOWDOC obligatoire : $btn, $status, $ seraient * vidés par un heredoc, en silence. */ $handle = 'aiforya-sm-tab-settings-js'; wp_register_script( $handle, false, array( 'jquery' ), AIFORYA_SM_VERSION, true ); wp_enqueue_script( $handle ); wp_localize_script( $handle, 'aiforyaSmSettingsL10n', array( 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'nonce' => $nonce, 'saving' => __( 'Saving…', 'aiforya-schema-markup' ), 'saved' => __( 'Settings saved.', 'aiforya-schema-markup' ), 'failed' => __( 'Saving failed.', 'aiforya-schema-markup' ), 'network' => __( 'Network error.', 'aiforya-schema-markup' ), ) ); $js = <<<'JS' jQuery(function($){ var L = window.aiforyaSmSettingsL10n || {}; var ajaxUrl = window.ajaxurl || L.ajaxUrl; var nonce = L.nonce; $('#aiforya-sm-settings-form').on('submit', function(e){ e.preventDefault(); var $btn = $(this).find('button[type="submit"]').prop('disabled', true); var $status = $('.aiforya-sm-save-status').css('color', '#94a3b8').text(L.saving); var data = $(this).serializeArray(); data.push({ name: 'action', value: 'aiforya_sm_save_settings' }); data.push({ name: 'nonce', value: nonce }); $.post(ajaxUrl, $.param(data)).done(function(r){ if (r && r.success) { var okMsg = (r.data && r.data.message) || L.saved; $status.css('color', '#4ade80').text(okMsg); if (window.AiforyaToast) { window.AiforyaToast.success(okMsg); } } else { var errMsg = (r && r.data && r.data.message) || L.failed; $status.css('color', '#f87171').text(errMsg); if (window.AiforyaToast) { window.AiforyaToast.error(errMsg); } } }).fail(function(){ var netMsg = L.network; $status.css('color', '#f87171').text(netMsg); if (window.AiforyaToast) { window.AiforyaToast.error(netMsg); } }).always(function(){ $btn.prop('disabled', false); }); }); }); JS; wp_add_inline_script( $handle, $js ); // Helper D2 : pastille d'aide « ? » charte (AiforyaTooltip). $text déjà traduit. $tip = static function ( $text ) { printf( '', esc_attr( $text ) ); }; ?>
This free version generates your structured data by rules, on your own site. The AI version adds automatic detection of the best type, competitive SERP analysis, emerging type predictions and A/B testing.