'array', 'sanitize_callback' => array($this, 'sanitize_options'), 'default' => array( 'api_url' => '', 'api_key' => '', 'brand_id' => '', 'list_id' => '' ) ) ); add_settings_section( 'cred_sendy_main_section', __('Paramètres de connexion', 'esi-creditdirect'), function() { echo '

' . esc_html__('Renseignez l\'URL de votre installation Sendy et la clé API comme indiqué dans votre compte Sendy.', 'esi-creditdirect') . '

'; }, 'credit-sendy' ); add_settings_field( 'cred_sendy_api_url', __('URL Sendy', 'esi-creditdirect'), array($this, 'field_api_url_cb'), 'credit-sendy', 'cred_sendy_main_section' ); add_settings_field( 'cred_sendy_api_key', __('Clé API', 'esi-creditdirect'), array($this, 'field_api_key_cb'), 'credit-sendy', 'cred_sendy_main_section' ); add_settings_field( 'cred_sendy_brand_id', __('ID du Brand', 'esi-creditdirect'), array($this, 'field_brand_id_cb'), 'credit-sendy', 'cred_sendy_main_section' ); add_settings_field( 'cred_sendy_list_id', __('ID de la liste', 'esi-creditdirect'), array($this, 'field_list_id_cb'), 'credit-sendy', 'cred_sendy_main_section' ); } /** * Affiche la page de réglages */ public function render_settings_page() { $options = $this->get_options(); include plugin_dir_path(__FILE__) . '../../templates/admin/sendy_settings.php'; } /** * Callback du champ API URL */ public function field_api_url_cb() { $options = $this->get_options(); $value = isset($options['api_url']) ? $options['api_url'] : ''; echo ''; echo '

' . esc_html__('URL complète de votre installation Sendy (ex: https://sendy.example.com)', 'esi-creditdirect') . '

'; } /** * Callback du champ API Key */ public function field_api_key_cb() { $options = $this->get_options(); $value = isset($options['api_key']) ? $options['api_key'] : ''; echo ''; echo '

' . esc_html__('Clé API disponible dans votre compte Sendy (Settings > API)', 'esi-creditdirect') . '

'; } /** * Callback du champ Brand ID */ public function field_brand_id_cb() { $options = $this->get_options(); $selected = isset($options['brand_id']) ? $options['brand_id'] : ''; $client = $this->get_client(); if ($client === null) { echo '' . esc_html__('Renseignez d\'abord l\'URL et la clé API, puis enregistrez.', 'esi-creditdirect') . ''; echo '
'; echo ''; return; } $brands = array(); try { $brands = $this->get_brands(); } catch (\Throwable $e) { echo '

' . esc_html(sprintf(__('Erreur lors du chargement des brands: %s', 'esi-creditdirect'), $e->getMessage())) . '

'; } if (empty($brands)) { echo '' . esc_html__('Aucun brand trouvé ou erreur. Vous pouvez saisir un ID manuellement.', 'esi-creditdirect') . ''; echo '
'; echo ''; return; } echo ''; echo '

' . esc_html__('Sélectionnez un brand pour filtrer les listes disponibles (optionnel)', 'esi-creditdirect') . '

'; } /** * Callback du champ Liste ID */ public function field_list_id_cb() { $options = $this->get_options(); $selected = isset($options['list_id']) ? $options['list_id'] : ''; $client = $this->get_client(); if ($client === null) { echo '' . esc_html__('Renseignez d\'abord l\'URL et la clé API, puis enregistrez.', 'esi-creditdirect') . ''; echo '
'; echo ''; return; } $lists = array(); try { $lists = $this->get_lists(); } catch (\Throwable $e) { echo '

' . esc_html(sprintf(__('Erreur lors du chargement des listes: %s', 'esi-creditdirect'), $e->getMessage())) . '

'; } if (empty($lists)) { echo '' . esc_html__('Aucune liste trouvée ou erreur. Vous pouvez saisir un ID manuellement.', 'esi-creditdirect') . ''; echo '
'; echo ''; return; } echo ''; } /** * Sanitize des options */ public function sanitize_options($options) { $sanitized = array(); $sanitized['api_url'] = isset($options['api_url']) ? esc_url_raw($options['api_url']) : ''; $sanitized['api_key'] = isset($options['api_key']) ? sanitize_text_field($options['api_key']) : ''; $sanitized['brand_id'] = isset($options['brand_id']) ? sanitize_text_field($options['brand_id']) : ''; $sanitized['list_id'] = isset($options['list_id']) ? sanitize_text_field($options['list_id']) : ''; return $sanitized; } /** * Récupère les options du plugin */ private function get_options() { $defaults = array( 'api_url' => '', 'api_key' => '', 'brand_id' => '', 'list_id' => '' ); $options = get_option('cred_sendy_options', array()); if (!is_array($options)) { $options = array(); } return array_merge($defaults, $options); } /** * Retourne les informations de connexion Sendy * ou null si les informations de connexion sont incomplètes. */ public function get_client() { $options = $this->get_options(); $apiUrl = isset($options['api_url']) ? trim($options['api_url']) : ''; $apiKey = isset($options['api_key']) ? trim($options['api_key']) : ''; if ($apiUrl === '' || $apiKey === '') { return null; } // Retourne un tableau avec les infos de connexion return array( 'api_url' => rtrim($apiUrl, '/'), 'api_key' => $apiKey ); } /** * Récupère la liste des brands Sendy * @return array Tableau de brands avec id et name */ private function get_brands() { $client = $this->get_client(); if ($client === null) { return array(); } $apiUrl = $client['api_url']; $apiKey = $client['api_key']; // Sendy API endpoint pour récupérer les brands $url = $apiUrl . '/api/brands/get-brands.php'; $response = wp_remote_post($url, array( 'body' => array( 'api_key' => $apiKey ), 'timeout' => 15 )); if (is_wp_error($response)) { throw new \Exception($response->get_error_message()); } $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); if (!$data || !is_array($data)) { return array(); } $brands = array(); foreach ($data as $id => $name) { $brands[] = array( 'id' => (string) $id, 'name' => (string) $name ); } return $brands; } /** * Récupère la liste des listes Sendy pour un brand donné * @param string $brandId ID du brand * @return array Tableau de listes avec id et name */ private function get_lists_for_brand($brandId) { $client = $this->get_client(); if ($client === null) { return array(); } $apiUrl = $client['api_url']; $apiKey = $client['api_key']; // Sendy API endpoint pour récupérer les listes $url = $apiUrl . '/api/lists/get-lists.php'; $response = wp_remote_post($url, array( 'body' => array( 'api_key' => $apiKey, 'brand_id' => $brandId, 'include_hidden' => 'no' ), 'timeout' => 15 )); if (is_wp_error($response)) { throw new \Exception($response->get_error_message()); } $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); if (!$data || !is_array($data)) { return array(); } $lists = array(); foreach ($data as $id => $name) { $lists[] = array( 'id' => (string) $id, 'name' => (string) $name ); } return $lists; } /** * Récupère toutes les listes Sendy de tous les brands ou d'un brand spécifique * @return array Tableau de listes avec id, name et brand_name */ private function get_lists() { $client = $this->get_client(); if ($client === null) { return array(); } try { $options = $this->get_options(); $selectedBrandId = isset($options['brand_id']) ? trim($options['brand_id']) : ''; // Si un brand_id est sélectionné, ne récupérer que les listes de ce brand if ($selectedBrandId !== '') { $brands = $this->get_brands(); $selectedBrand = null; foreach ($brands as $brand) { if ($brand['id'] === $selectedBrandId) { $selectedBrand = $brand; break; } } if ($selectedBrand) { $lists = $this->get_lists_for_brand($selectedBrandId); $allLists = array(); foreach ($lists as $list) { $allLists[] = array( 'id' => $list['id'], 'name' => $list['name'], 'brand_name' => $selectedBrand['name'] ); } return $allLists; } } // Sinon, récupérer toutes les listes de tous les brands $brands = $this->get_brands(); if (empty($brands)) { return array(); } $allLists = array(); foreach ($brands as $brand) { $lists = $this->get_lists_for_brand($brand['id']); foreach ($lists as $list) { $allLists[] = array( 'id' => $list['id'], 'name' => $list['name'], 'brand_name' => $brand['name'] ); } } return $allLists; } catch (\Throwable $e) { throw $e; } } /** * AJAX: ping Sendy pour valider la connexion */ public function ajax_ping() { check_ajax_referer('cred_sendy_ping', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error(array('message' => __('Permissions insuffisantes', 'esi-creditdirect')), 403); } $client = $this->get_client(); if ($client === null) { wp_send_json_error(array('message' => __('Configuration incomplète (URL/clé API).', 'esi-creditdirect')), 400); } try { // Test de connexion en récupérant les brands $brands = $this->get_brands(); $lists = $this->get_lists(); wp_send_json_success(array( 'message' => __('Connexion réussie', 'esi-creditdirect'), 'brands_count' => count($brands), 'lists_count' => count($lists) )); } catch (\Throwable $e) { wp_send_json_error(array('message' => $e->getMessage()), 500); } } /** * Abonne ou met à jour un contact à partir d'un objet crédit. * @param object $credit Objet avec au minimum les propriétés email, prenom, nom */ public function subscribe_from_credit($credit) { if (!$credit || !isset($credit->email)) { return; } $email = trim((string)$credit->email); if ($email === '' || !is_email($email)) { return; } $options = $this->get_options(); $listId = isset($options['list_id']) ? trim((string)$options['list_id']) : ''; if ($listId === '') { return; } $client = $this->get_client(); if ($client === null) { return; } $firstName = isset($credit->prenom) ? (string)$credit->prenom : ''; $lastName = isset($credit->nom) ? (string)$credit->nom : ''; $apiUrl = $client['api_url']; $apiKey = $client['api_key']; // Sendy API endpoint pour s'abonner $url = $apiUrl . '/subscribe'; $body = array( 'api_key' => $apiKey, 'email' => $email, 'list' => $listId, 'boolean' => 'true' ); // Ajouter le nom si disponible if ($firstName !== '' || $lastName !== '') { $name = trim($firstName . ' ' . $lastName); if ($name !== '') { $body['name'] = $name; } } try { $response = wp_remote_post($url, array( 'body' => $body, 'timeout' => 15 )); if (is_wp_error($response)) { throw new \Exception($response->get_error_message()); } $responseBody = wp_remote_retrieve_body($response); // Sendy retourne généralement "true" ou "1" en cas de succès if ($responseBody !== 'true' && $responseBody !== '1') { error_log('Sendy subscribe error (from credit): ' . $responseBody); } } catch (\Throwable $e) { error_log('Sendy subscribe error (from credit): ' . $e->getMessage()); } } }