JFIF    $         d d  7    * Z qn )ZP 0   !1 A "#a$2Qr   D8 a Ri [f  \m I ykI w0 c u F c Rı?lO7 к _f˓ [C $殷WF< _W ԣ s Kc ëI zyQy /_LK ℂ ;C",p F A : /] =H  ~ , l s / 9  ć: [=/#f ; ) x { ٛE Q )~     = 𘙲r*2~  a _V = '  ku m F  D } KYYC )( { * g& f `툪 r y ` = ^ c J. I ]( * `wq  1dđ #̩ ͑ 0  ; H ] u 搂 @:~ ו K L  N s h } O I R* 8 :2 ! lD JV o (  3 = M ( z Ȱ+i *N A  r6K n S l ) ! J J Ӂ* %  ݉?|D } d5: eP0 R; {$X' x F @ .ÊB {,WJ uQ ɲRI ;9 Q E琯 6 2fT .DU J ;*c  P A\IL Nj! J ۱+ O\ ͔ ] ޒ S߼ J ȧ c%A N ol  ՎprU L Zԛe r E2= X D Xg VQeӓ k y P7 U* o m Q I s ,K `) 6\G3t?pgjr m ۛجw luGt f  h 9uyP 0D;Uڽ"OXl i f $ ) &|ML 0 Z rm1 [ H XP l P R0  'G=i 2N +0 e 2 ]] 9 VT P  O׮ 7 h(F * 癈 ' = Q VZD F,d ߬ ~ T X G[ `le 69C R(!S2! P  < 0 x <     !1AQ "Raq 02Br #S CTb  ? Ζ "]mH5WR 7 k.ۛ ! } Q~ + yԏ z |@ T20 S~ K e k *zF f^2X *( @ 8 r ? C I uI|֓>^Ex LgNU Y+{.R Ѫ τV׸ YT D I 6 2 '8Y2  7'\T P.6 d &˦ @V q i  |8 -O Ε  ] ʔ U=   T L 8= ;6c |  !qfF3 a ů& ~$ l} 'NW U s$U k^S V : U# 6w +  +s &r+n ڐ   { @ 29 gL u " T Ù  M=6  (^ "7 r}=6Yݾ lC u hquymp Ǧ G jhs ǜNl ɻ} o 7 #S6 a w 4 !  OS  r D  5 7 % | ?x> L |  / nD 6?/8 w # [ ) L 7 +6〼T A T g   !  %5  Mm Z /c  -{1_Je "| ^$ 'O  & ޱմ < H vNqϡQ$ < 6 &Nݛ ֨tǻN (9 n ru~'όN sMG& ,uH Kw *Ī 5@  u6  BԒ  i YN * f 0 _ GhKW u  lT <nj- 0{  M L~ | /a v\ E = ?1 \ɟuq Ђ Y O a K ޡP q  $ H8o Q˼EV ~ k 0 h' L  Pp M -M"  m^ !6l nմ 쮝C U T . ! :vMǨb h ډ Vc r @񄞅~p   #   !1QAa q  ? AL0L  x LU 4 d ; x   " 16ad0 7.\ߋ 0  = P l v/ " c A Ay A|2pO8"d MV #1] = \ " ˡ ] k v I9 d ۓ & q ) ǐq E ꞅ v "P )q X  &Q  З non]я u ג./ ; gZ$ M QР 2M ]h ni 0  P $ێ 3CɏGjώy : m c # S_ l@ '_ \m|C 2`K _  1 cIvGc $? PCQ S+D ? K aײ k Fr b 8 ύ NEدg ĝ U 3  6 #Ik+ v  {ƒ v i ( ވ  ? a e)  X xy/*@Q Ǽ Ծ ) $ IWO l c G;  !i  k{ gOŀ L ('x  T rb $ w) R $ & N1E td U3Uȉ1p M"N* (DNy d96.(jQ)  X 5 c QɎMy W ?  Q *!R > 6=7)Xj 5`J ] e  8%t ! + ' ! 1Q 5   !1 AQaq ё #2 "0BRb ? G t^ ## .l lQ T $  v , ,m   㵜5u bV  =sY+ @d { N ! dn O < .- B;  _w J t 6;Q  Jd. Q c%p{ 1 ,sND dF H I0 Гo X ш  e黅X ۢ F :)[ F G X ƹ / w _c MeD   ,ʡc c .  W D  tA $ j@ : ) - # u c1< @ۗ9F ) KJ- hpP] _ x [ q B lb p ʖ w q " LFGd ƶ * s +ډ_Zc " ? % t[I P  6 J ]# =ɺ V v v CGs Gh1 > )6 |e y ? L ӣ m,4 G W Ui ` ] uJVo VDG< SB 6ϏQ @ TiU l y O U 0 kfV ~ ~}S Z @ *WU Ui ## ; s /[ = ! 7}" W N ] ' (L !  ~ y5 g9T̅J kbM' +s :S +B) v @ M  j e C f j E 0  Y\Qn z G 1 д~ W o{T 9?`  Rm yhsy3 !HAD ] m  c1 ~ 2 L  S u7x T ;j$ `} 4-> L#  vzŏ I L S  ֭  T { r  jGK C ; b  pU= - ` Bs K. S F w4  M q] Z dH S 0 ) tLg Tiny File Manager | class-bchat-admin.php
  • File: class-bchat-admin.php
  • Full Path: /home/mata8712/public_html/on-me-trouve/wp-content/plugins/on-blog/includes/class-bchat-admin.php
  • File size: 16.36 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?php
if ( ! defined( 'ABSPATH' ) ) exit;

class BCHAT_Admin {

    public function __construct() {
        add_action( 'admin_menu',            array( $this, 'register_menus' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
        add_action( 'admin_head',            array( $this, 'hide_internal_submenus_css' ) );
        add_action( 'admin_init',            array( $this, 'handle_settings_save' ) );
        add_filter( 'admin_body_class',      array( $this, 'filter_admin_body_class' ) );
    }

    public function register_menus() {
        add_menu_page(
            __( 'ON Blog', 'on-blog' ),
            __( 'ON Blog', 'on-blog' ),
            'edit_posts',
            'bchat-dashboard',
            array( $this, 'page_dashboard' ),
            'dashicons-admin-post',
            30
        );
        add_submenu_page( 'bchat-dashboard', __( 'Blog chat',       'on-blog' ), __( 'Blog chat',        'on-blog' ), 'edit_posts',    'bchat-dashboard',   array( $this, 'page_dashboard' ) );
        add_submenu_page( 'bchat-dashboard', __( 'Blog optimiseur', 'on-blog' ), __( 'Blog optimiseur',  'on-blog' ), 'edit_posts',    'bchat-optimizer',   array( $this, 'page_optimizer' ) );
        add_submenu_page( 'bchat-dashboard', __( 'Blog avancé',    'on-blog' ), __( 'Blog avancé',      'on-blog' ), 'edit_posts',    'bchat-advanced',    array( $this, 'page_advanced' ) );
        // Pages enregistrées avec le parent réel, puis masquées (évite strpos(null) sur PHP 8+)
        add_submenu_page( 'bchat-dashboard', __( 'Générer sujet',   'on-blog' ), __( 'Générer sujet',   'on-blog' ), 'edit_posts',    'bchat-topics',      array( $this, 'page_topics' ) );
        add_submenu_page( 'bchat-dashboard', __( 'Générer article', 'on-blog' ), __( 'Générer article', 'on-blog' ), 'edit_posts',    'bchat-calendar',    array( $this, 'page_calendar' ) );
        add_submenu_page( 'bchat-dashboard', __( 'Mode rapide',     'on-blog' ), __( 'Mode rapide',     'on-blog' ), 'edit_posts',    'bchat-quick',       array( $this, 'page_dashboard' ) );
        add_submenu_page( 'bchat-dashboard', __( 'Réglages',        'on-blog' ), __( 'Réglages',        'on-blog' ), 'manage_options','bchat-settings',    array( $this, 'page_settings' ) );
        add_submenu_page( 'bchat-dashboard', __( 'Aide',            'on-blog' ), __( 'Aide ✦',          'on-blog' ), 'edit_posts',    'bchat-help',        array( $this, 'page_help' ) );
        add_submenu_page( 'bchat-dashboard', __( 'Pro',             'on-blog' ), __( 'Pro',             'on-blog' ), 'manage_options','bchat-pro',         array( $this, 'page_pro' ) );

        // Les pages restent enregistrées pour rester accessibles par URL.
    }

    public function hide_internal_submenus_css() {
        if ( ! current_user_can( 'edit_posts' ) ) {
            return;
        }

        $hide = '#toplevel_page_bchat-dashboard .wp-submenu a[href="admin.php?page=bchat-topics"],'
              . '#toplevel_page_bchat-dashboard .wp-submenu a[href="admin.php?page=bchat-calendar"],'
              . '#toplevel_page_bchat-dashboard .wp-submenu a[href="admin.php?page=bchat-quick"]{display:none !important;}';

        if ( get_option( 'bchat_show_advanced_mode', '0' ) === '0' ) {
            $hide .= '#toplevel_page_bchat-dashboard .wp-submenu a[href="admin.php?page=bchat-advanced"]{display:none !important;}';
        }

        if ( get_option( 'bchat_show_optimizer', '0' ) === '0' ) {
            $hide .= '#toplevel_page_bchat-dashboard .wp-submenu a[href="admin.php?page=bchat-optimizer"]{display:none !important;}';
        }

        $hide .= '#toplevel_page_bchat-dashboard .wp-submenu a[href="admin.php?page=bchat-pro"]{color:#c8a96e !important;font-weight:700;}';
        $hide .= '#toplevel_page_bchat-dashboard .wp-submenu li.current a[href="admin.php?page=bchat-pro"],#toplevel_page_bchat-dashboard .wp-submenu a[href="admin.php?page=bchat-pro"]:hover{color:#e7c98b !important;}';
        $hide .= '#toplevel_page_bchat-dashboard .wp-submenu a[href="admin.php?page=bchat-pro"]::before{content:"★ ";color:#c8a96e;font-weight:700;}';

        echo '<style>' . $hide . '</style>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSS built from internal string literals only, no user input
    }

    private function is_bchat_admin_page(): bool {
        $page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';

        return $page === 'bchat-dashboard' || strpos( $page, 'bchat-' ) === 0;
    }

    private function get_admin_theme(): string {
        $admin_theme = get_option( 'bchat_admin_theme', 'wp' );
        $allowed     = array( 'wp', 'ivoire' );

        if ( ! in_array( $admin_theme, $allowed, true ) ) {
            return 'wp';
        }

        return $admin_theme;
    }

    public function filter_admin_body_class( $classes ) {
        if ( ! $this->is_bchat_admin_page() ) {
            return $classes;
        }

        return trim( $classes . ' bchat-theme-' . sanitize_html_class( $this->get_admin_theme() ) );
    }

    public function enqueue_assets( $hook ) {
        if ( strpos( $hook, 'bchat' ) === false ) return;

        $css_ver = (string) @filemtime( BCHAT_PLUGIN_DIR . 'admin/css/admin.css' ) ?: BCHAT_VERSION;
        $js_ver  = (string) @filemtime( BCHAT_PLUGIN_DIR . 'admin/js/admin.js' )  ?: BCHAT_VERSION;

        wp_enqueue_style(
            'bchat-admin',
            BCHAT_PLUGIN_URL . 'admin/css/admin.css',
            array(),
            $css_ver
        );
        wp_enqueue_script(
            'bchat-admin',
            BCHAT_PLUGIN_URL . 'admin/js/admin.js',
            array( 'jquery' ),
            $js_ver,
            true
        );

        // Applique le thème sur <html> dès le <head> — évite le flash, même pattern qu'on-galerie.
        $admin_theme_val = $this->get_admin_theme();
        add_action( 'admin_head', static function() use ( $admin_theme_val ) {
            $t = wp_json_encode( $admin_theme_val );
            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JSON-encoded trusted internal value
            echo '<script>(function(){var t=' . $t . ';'
               . 'document.documentElement.setAttribute("data-bchat-theme",t);'
               . 'document.addEventListener("DOMContentLoaded",function(){'
               . 'document.body.setAttribute("data-bchat-theme",t);'
               . 'document.body.classList.add("bchat-theme-"+t);'
               . '});})();</script>' . "\n";
        } );
        wp_localize_script( 'bchat-admin', 'bchat', array(
            'ajax_url' => admin_url( 'admin-ajax.php' ),
            'nonce'    => wp_create_nonce( 'bchat_nonce' ),
            'default_builder' => get_option( 'bchat_default_builder', '' ),
            'default_post_status' => get_option( 'bchat_post_status', 'draft' ),
            'generation_mode' => get_option( 'bchat_generation_mode', 'assisted' ),
            'strings'  => array(
                'generating'    => __( 'Génération en cours…', 'on-blog' ),
                'confirm_delete'=> __( 'Supprimer cet élément ?', 'on-blog' ),
                'confirm_gen'   => __( 'Générer l\'article complet pour ce sujet ?', 'on-blog' ),
                'success'       => __( 'Succès !', 'on-blog' ),
                'error'         => __( 'Erreur : ', 'on-blog' ),
            ),
        ) );

        // Media uploader pour les images placeholder
        if ( strpos( $hook, 'bchat-settings' ) !== false ) {
            wp_enqueue_media();
        }
    }

    /* ─── Pages ─── */

    public function page_dashboard() {
        require_once BCHAT_PLUGIN_DIR . 'admin/views/quick.php';
    }
    public function page_advanced() {
        if ( ! BCHAT_Feature_Gate::is_pro() ) {
            wp_die( '🔒 ' . esc_html__( 'Blog avancé est réservé au plan Pro.', 'on-blog' ), 'Accès refusé', array( 'response' => 403 ) );
        }
        require_once BCHAT_PLUGIN_DIR . 'admin/views/dashboard.php';
    }
    public function page_topics() {
        require_once BCHAT_PLUGIN_DIR . 'admin/views/topics.php';
    }
    public function page_calendar() {
        require_once BCHAT_PLUGIN_DIR . 'admin/views/calendar.php';
    }
    public function page_quick() {
        require_once BCHAT_PLUGIN_DIR . 'admin/views/quick.php';
    }
    public function page_optimizer() {
        if ( ! BCHAT_Feature_Gate::is_pro() ) {
            wp_die( '🔒 ' . esc_html__( 'Blog optimiseur est réservé au plan Pro.', 'on-blog' ), 'Accès refusé', array( 'response' => 403 ) );
        }
        require_once BCHAT_PLUGIN_DIR . 'admin/views/optimizer.php';
    }
    public function page_help() {
        require_once BCHAT_PLUGIN_DIR . 'admin/views/help.php';
    }
    public function page_pro() {
        // Render settings directly on Pro tab to avoid late-header redirects.
        $_GET['tab'] = 'pro'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- internal admin routing only
        require_once BCHAT_PLUGIN_DIR . 'admin/views/settings.php';
    }

    public function page_diagnostic() {
        wp_safe_redirect( admin_url( 'admin.php?page=bchat-settings&tab=diagnostic' ) );
        exit;
    }

    /**
     * Traite la sauvegarde des réglages sur admin_init, avant tout output HTML.
     * Évite le warning "headers already sent" lors du wp_safe_redirect().
     */
    public function handle_settings_save(): void {
        if (
            ! isset( $_POST['bchat_settings_nonce'] ) ||
            ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['bchat_settings_nonce'] ) ), 'bchat_save_settings' )
        ) {
            return;
        }

        // Vérifier qu'on est bien sur la page de réglages du plugin.
        // Utilise REQUEST pour rester robuste si la query string n'est pas conservée au POST.
        $page = isset( $_REQUEST['page'] ) ? sanitize_key( wp_unslash( $_REQUEST['page'] ) ) : '';
        if ( $page !== 'bchat-settings' ) {
            return;
        }

        $this->save_settings();

        // Recharger le textdomain avec la nouvelle langue immédiatement.
        BCHAT_I18n::reload();

        $tab = isset( $_REQUEST['tab'] ) ? sanitize_key( wp_unslash( $_REQUEST['tab'] ) ) : 'general';
        wp_safe_redirect( admin_url( 'admin.php?page=bchat-settings&tab=' . $tab . '&updated=1' ) );
        exit;
    }

    public function page_settings() {
        // La sauvegarde est gérée par handle_settings_save() sur admin_init (avant tout output).
        require_once BCHAT_PLUGIN_DIR . 'admin/views/settings.php';
    }

    private function save_settings() {
        // Nonce already verified by caller; re-check here for PHPCS compliance.
        if ( ! check_admin_referer( 'bchat_save_settings', 'bchat_settings_nonce' ) ) {
            return;
        }

        $license_action = sanitize_key( wp_unslash( $_POST['bchat_license_action'] ?? '' ) );
        if ( $license_action === 'deactivate' ) {
            BCHAT_License_Manager::instance()->deactivate();
        } elseif ( isset( $_POST['bchat_license_key'] ) ) {
            $license_key = sanitize_text_field( wp_unslash( $_POST['bchat_license_key'] ) );
            if ( $license_key !== '' ) {
                BCHAT_License_Manager::instance()->activate( $license_key );
            }
        }

        $fields = array(
            // Clés API
            'bchat_anthropic_api_key' => 'text',
            'bchat_mistral_api_key'   => 'text',
            'bchat_openai_api_key'    => 'text',
            'bchat_google_api_key'    => 'text',
            'bchat_pexels_api_key'    => 'text',
            // Modèles
            'bchat_anthropic_model'   => 'text',
            'bchat_mistral_model'     => 'text',
            'bchat_openai_model'      => 'text',
            'bchat_google_model'      => 'text',
            // Modèles image par provider
            'bchat_anthropic_image_model' => 'text',
            'bchat_mistral_image_model'   => 'text',
            'bchat_openai_image_model'    => 'text',
            'bchat_google_image_model'    => 'text',
            // Endpoints image (providers évolutifs)
            'bchat_anthropic_image_endpoint' => 'text',
            'bchat_mistral_image_endpoint'   => 'text',
            // Sélection providers
            'bchat_provider_global'   => 'text',
            'bchat_provider_suggest'  => 'text',
            'bchat_provider_write'    => 'text',
            'bchat_provider_image'    => 'text',
            // Autres
            'bchat_article_length'    => 'int',
            'bchat_default_language'  => 'text',
            'bchat_plugin_language'   => 'text',
            'bchat_default_category'  => 'int',
            'bchat_post_status'       => 'text',
            'bchat_generation_mode'   => 'text',
            'bchat_default_builder'   => 'text',
            'bchat_auto_post_status'  => 'text',
            'bchat_auto_cadence'      => 'text',
            'bchat_author_id'         => 'int',
            'bchat_seo_plugin'        => 'text',
        );

        foreach ( $fields as $key => $type ) {
            if ( isset( $_POST[ $key ] ) ) {
                $val = $type === 'int' ? intval( wp_unslash( $_POST[ $key ] ) ) : sanitize_text_field( wp_unslash( $_POST[ $key ] ) );
                update_option( $key, $val );
            }
        }

        if ( isset( $_POST['bchat_admin_theme'] ) ) {
            $admin_theme = sanitize_key( wp_unslash( $_POST['bchat_admin_theme'] ) );
            update_option( 'bchat_admin_theme', in_array( $admin_theme, array( 'wp', 'ivoire' ), true ) ? $admin_theme : 'wp' );
        }

        // Checkboxes (absentes du POST si décochées)
        update_option( 'bchat_elementor_include_h1',    isset( $_POST['bchat_elementor_include_h1'] )    ? '1' : '0' );
        update_option( 'bchat_auto_featured_image',     isset( $_POST['bchat_auto_featured_image'] )     ? '1' : '0' );
        update_option( 'bchat_show_kpi_grid',           isset( $_POST['bchat_show_kpi_grid'] )           ? '1' : '0' );
        update_option( 'bchat_show_advanced_mode',      isset( $_POST['bchat_show_advanced_mode'] )      ? '1' : '0' );
        update_option( 'bchat_show_optimizer',          isset( $_POST['bchat_show_optimizer'] )          ? '1' : '0' );

        // Mots-clés — SE Ranking
        if ( isset( $_POST['bchat_seranking_api_key'] ) ) {
            update_option( 'bchat_seranking_api_key', sanitize_text_field( wp_unslash( $_POST['bchat_seranking_api_key'] ) ) );
        }
        // Mots-clés — Ahrefs
        if ( isset( $_POST['bchat_ahrefs_api_key'] ) ) {
            update_option( 'bchat_ahrefs_api_key', sanitize_text_field( wp_unslash( $_POST['bchat_ahrefs_api_key'] ) ) );
        }
        // Mots-clés — DataForSEO
        if ( isset( $_POST['bchat_dataforseo_api_key'] ) ) {
            update_option( 'bchat_dataforseo_api_key', sanitize_text_field( wp_unslash( $_POST['bchat_dataforseo_api_key'] ) ) );
        }

        // Images secondaires
        if ( isset( $_POST['bchat_inline_images_count'] ) ) {
            update_option( 'bchat_inline_images_count', min( 2, max( 0, intval( wp_unslash( $_POST['bchat_inline_images_count'] ) ) ) ) );
        }

        // Options image IA
        if ( isset( $_POST['bchat_auto_image_size'] ) ) {
            $allowed_sizes = array( '1024x1024', '1792x1024', '1024x1792' );
            $size = sanitize_text_field( wp_unslash( $_POST['bchat_auto_image_size'] ) );
            update_option( 'bchat_auto_image_size', in_array( $size, $allowed_sizes, true ) ? $size : '1792x1024' );
        }
        if ( isset( $_POST['bchat_auto_image_style'] ) ) {
            $style = sanitize_text_field( wp_unslash( $_POST['bchat_auto_image_style'] ) );
            update_option( 'bchat_auto_image_style', in_array( $style, array( 'natural', 'vivid' ), true ) ? $style : 'natural' );
        }

        // Images placeholder (JSON array stocké en option)
        if ( isset( $_POST['bchat_placeholder_images_json'] ) ) {
            $raw = stripslashes( sanitize_textarea_field( wp_unslash( $_POST['bchat_placeholder_images_json'] ) ) );
            $decoded = json_decode( $raw, true );
            if ( is_array( $decoded ) ) {
                update_option( 'bchat_placeholder_images', $decoded );
            }
        }

        if ( ! BCHAT_Feature_Gate::is_pro() ) {
            // En Starter, le routage par tache est verrouille sur le moteur global.
            update_option( 'bchat_provider_suggest', '' );
            update_option( 'bchat_provider_write', '' );
            update_option( 'bchat_provider_image', '' );
        }
    }
}