array( array( 'handle' => 'aiforya-sm-tab-optimizer', 'src' => AIFORYA_SM_URL . 'assets/css/tab-optimizer.css', 'ver' => AIFORYA_SM_VERSION, ), ), ); } public function render( array $args = array() ): void { $optimizer = Aiforya_Schema_Markup_Optimizer::get_instance(); $conflicts = $optimizer->detect_dedup_conflicts(); $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, $log, $cb, $ * seraient vidés par un heredoc, sans qu aucun contrôle ne crie. */ $handle = 'aiforya-sm-tab-optimizer-js'; wp_register_script( $handle, false, array( 'jquery' ), AIFORYA_SM_VERSION, true ); wp_enqueue_script( $handle ); wp_localize_script( $handle, 'aiforyaSmOptimizerL10n', array( 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'nonce' => $nonce, 'optimizing' => __( 'Optimization in progress…', 'aiforya-schema-markup' ), 'done' => __( 'Done.', 'aiforya-schema-markup' ), 'failed' => __( 'Failed.', 'aiforya-schema-markup' ), 'network' => __( 'Network error.', 'aiforya-schema-markup' ), ) ); $js = <<<'JS' jQuery(function($){ var L = window.aiforyaSmOptimizerL10n || {}; var ajaxUrl = window.ajaxurl || L.ajaxUrl; var nonce = L.nonce; $('#aiforya-sm-optimizer-toast-host').appendTo('body'); function smToast(message, type, ttl) { type = type || 'info'; ttl = ttl || 4500; var $host = $('.aiforya-sm-toast-host').last(); var $t = $('
', { 'class': 'aiforya-sm-toast aiforya-sm-toast--' + type, role: 'status' }).text(message); $host.append($t); setTimeout(function(){ $t.addClass('is-visible'); }, 10); setTimeout(function(){ $t.removeClass('is-visible'); setTimeout(function(){ $t.remove(); }, 300); }, ttl); } // F16 One-Click $('#aiforya-sm-optimize-btn').on('click', function(){ var $btn = $(this); var $status = $('.aiforya-sm-optimize-status'); var $log = $('.aiforya-sm-optimize-log'); $btn.prop('disabled', true); $status.text(L.optimizing).css('color', '#94a3b8'); $log.empty(); runOptimizeBatch($btn, $status, $log); }); function runOptimizeBatch($btn, $status, $log) { $.post(ajaxUrl, { action: 'aiforya_sm_optimize_run', nonce: nonce, batch_size: 25 }).done(function(r){ if (r && r.success) { var d = r.data || {}; var line = $('
').text(d.message || ''); $log.append(line); if ((d.remaining || 0) > 0 && (d.ok || 0) > 0) { setTimeout(function(){ runOptimizeBatch($btn, $status, $log); }, 600); } else { $status.text(L.done).css('color', '#4ade80'); $btn.prop('disabled', false); smToast(d.message || 'OK', 'success'); } } else { $status.text((r && r.data && r.data.message) || L.failed).css('color', '#f87171'); $btn.prop('disabled', false); } }).fail(function(){ $status.text(L.network).css('color', '#f87171'); $btn.prop('disabled', false); }); } // Dedup toggles $(document).on('change', '.aiforya-sm-dedup-checkbox', function(){ var $cb = $(this); var plugin = $cb.data('plugin'); var enable = $cb.prop('checked'); $.post(ajaxUrl, { action: 'aiforya_sm_dedup_disable', nonce: nonce, plugin: plugin, enable: enable ? 1 : 0 }).done(function(r){ if (r && r.success) smToast((r.data && r.data.message) || 'OK', 'success'); else smToast((r && r.data && r.data.message) || L.failed, 'error'); }); }); }); 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 ) ); }; ?>

in addition to ours = duplication, which can break Google Rich Results. AIFORYA can cleanly disable their Schema output (all other SEO features remain intact). Enable this toggle after importing their data via Migration.', 'aiforya-schema-markup' ); ?>