init_settings(); $this->init_hooks(); } /** * Obtenir l'instance unique. */ public static function get_instance(): self { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } /** * Initialiser les paramètres. */ private function init_settings(): void { $this->settings = array( 'enabled' => pdfib_get_option( 'pdfib_notifications_enabled', true ), 'position' => pdfib_get_option( 'pdfib_notifications_position', 'top-right' ), 'duration' => pdfib_get_option( 'pdfib_notifications_duration', 5000 ), 'max_notifications' => pdfib_get_option( 'pdfib_notifications_max', 5 ), 'animation' => pdfib_get_option( 'pdfib_notifications_animation', 'slide' ), 'sound_enabled' => pdfib_get_option( 'pdfib_notifications_sound', false ), 'types' => array( 'success' => array( 'icon' => '✅', 'color' => '#28a745', 'bg' => '#d4edda', ), 'error' => array( 'icon' => '❌', 'color' => '#dc3545', 'bg' => '#f8d7da', ), 'warning' => array( 'icon' => '⚠️', 'color' => '#ffc107', 'bg' => '#fff3cd', ), 'info' => array( 'icon' => 'ℹ️', 'color' => '#17a2b8', 'bg' => '#d1ecf1', ), ), ); } /** * Initialiser les hooks WordPress. */ private function init_hooks(): void { add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); add_action( 'wp_ajax_pdfib_show_notification', array( $this, 'ajax_show_notification' ) ); // Hooks pour les notifications automatiques. add_action( 'pdfib_template_saved', array( $this, 'notify_template_saved' ) ); add_action( 'pdfib_template_deleted', array( $this, 'notify_template_deleted' ) ); add_action( 'pdfib_settings_saved', array( $this, 'notify_settings_saved' ) ); } /** * Charger les scripts et styles. */ public function enqueue_scripts(): void { if ( ! $this->settings['enabled'] ) { return; } // Charger les styles et scripts seulement si les fichiers existent. $notifications_css = \plugin_dir_path( dirname( __DIR__ ) ) . 'assets/css/notifications-css.min.css'; if ( file_exists( $notifications_css ) ) { \wp_enqueue_style( 'pdf-builder-notifications', plugin_dir_url( dirname( __DIR__ ) ) . 'assets/css/notifications-css.min.css', array(), '1.0.0' ); } $notifications_js = \plugin_dir_path( dirname( __DIR__ ) ) . 'assets/js/notifications.js'; if ( file_exists( $notifications_js ) ) { wp_enqueue_script( 'pdf-builder-notifications', plugin_dir_url( dirname( __DIR__ ) ) . 'assets/js/notifications.js', array( 'jquery' ), '1.0.0-' . time(), false ); } // Localiser le script avec les paramètres. wp_localize_script( 'pdf-builder-notifications', 'pdfBuilderNotifications', array( 'settings' => $this->settings, 'ajax_url' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'pdfib_notifications' ), 'strings' => array( 'close' => __( 'Fermer', 'advanced-pdf-invoice-builder' ), 'dismiss_all' => __( 'Tout fermer', 'advanced-pdf-invoice-builder' ), ), ) ); } /** * Afficher une notification. * * @param string $message Notification message. * @param string $type Notification type (info|success|warning|error). * @param array $options Additional options. */ public function show_notification( string $message, string $type = 'info', array $options = array() ): ?array { if ( ! $this->settings['enabled'] ) { return null; } $allowed_types = array_keys( $this->settings['types'] ); if ( ! in_array( $type, $allowed_types, true ) ) { $type = 'info'; } $notification = array_merge( array( 'message' => $message, 'type' => $type, 'duration' => $this->settings['duration'], 'dismissible' => true, 'position' => $this->settings['position'], 'timestamp' => time(), ), $options ); // Ajouter à la file d'attente. $this->notification_queue[] = $notification; // Limiter le nombre de notifications. if ( count( $this->notification_queue ) > $this->settings['max_notifications'] ) { array_shift( $this->notification_queue ); } // Si on est en AJAX, retourner les données. if ( wp_doing_ajax() ) { return $notification; } // Sinon, ajouter au footer. add_action( 'wp_footer', array( $this, 'render_notifications' ) ); add_action( 'admin_footer', array( $this, 'render_notifications' ) ); return $notification; } /** * Rendre une notification individuelle. * * @param array $notification Notification data array. */ private function render_single_notification( array $notification ): void { $type_config = isset( $this->settings['types'][ $notification['type'] ] ) ? $this->settings['types'][ $notification['type'] ] : $this->settings['types']['info']; $classes = array( 'pdf-builder-notification', 'pdf-builder-notification-' . $notification['type'], 'pdf-builder-notification-' . $this->settings['animation'], ); if ( $notification['dismissible'] ) { $classes[] = 'dismissible'; } $style = sprintf( 'background-color: %s; color: %s; border-left-color: %s;', $type_config['bg'], $type_config['color'], $type_config['color'] ); ?>