496 lines
17 KiB
PHP
496 lines
17 KiB
PHP
<?php
|
|
|
|
class CRED_credit_sendy extends CRED_base {
|
|
|
|
public function __construct() {
|
|
// Le hook admin_menu est maintenant géré par le factory
|
|
}
|
|
|
|
public function init() {
|
|
|
|
}
|
|
|
|
public function add_admin_menu() {
|
|
add_submenu_page(
|
|
'credit-manager',
|
|
'Sendy',
|
|
'Sendy',
|
|
'manage_options',
|
|
'credit-sendy',
|
|
array($this, 'render_settings_page')
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Enregistre les réglages et champs via la Settings API
|
|
*/
|
|
public function register_settings() {
|
|
register_setting(
|
|
'cred_sendy_options_group',
|
|
'cred_sendy_options',
|
|
array(
|
|
'type' => '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 '<p>' . esc_html__('Renseignez l\'URL de votre installation Sendy et la clé API comme indiqué dans votre compte Sendy.', 'esi-creditdirect') . '</p>';
|
|
},
|
|
'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 '<input type="url" class="regular-text" id="cred_sendy_api_url" name="cred_sendy_options[api_url]" value="' . esc_attr($value) . '" placeholder="https://votre-domaine.com">';
|
|
echo '<p class="description">' . esc_html__('URL complète de votre installation Sendy (ex: https://sendy.example.com)', 'esi-creditdirect') . '</p>';
|
|
}
|
|
|
|
/**
|
|
* Callback du champ API Key
|
|
*/
|
|
public function field_api_key_cb() {
|
|
$options = $this->get_options();
|
|
$value = isset($options['api_key']) ? $options['api_key'] : '';
|
|
echo '<input type="text" class="regular-text" id="cred_sendy_api_key" name="cred_sendy_options[api_key]" value="' . esc_attr($value) . '" placeholder="YOUR_API_KEY">';
|
|
echo '<p class="description">' . esc_html__('Clé API disponible dans votre compte Sendy (Settings > API)', 'esi-creditdirect') . '</p>';
|
|
}
|
|
|
|
/**
|
|
* 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 '<em>' . esc_html__('Renseignez d\'abord l\'URL et la clé API, puis enregistrez.', 'esi-creditdirect') . '</em>';
|
|
echo '<br />';
|
|
echo '<input type="text" class="regular-text" name="cred_sendy_options[brand_id]" value="' . esc_attr($selected) . '" placeholder="Brand ID">';
|
|
return;
|
|
}
|
|
|
|
$brands = array();
|
|
try {
|
|
$brands = $this->get_brands();
|
|
} catch (\Throwable $e) {
|
|
echo '<div class="notice notice-error"><p>' . esc_html(sprintf(__('Erreur lors du chargement des brands: %s', 'esi-creditdirect'), $e->getMessage())) . '</p></div>';
|
|
}
|
|
|
|
if (empty($brands)) {
|
|
echo '<em>' . esc_html__('Aucun brand trouvé ou erreur. Vous pouvez saisir un ID manuellement.', 'esi-creditdirect') . '</em>';
|
|
echo '<br />';
|
|
echo '<input type="text" class="regular-text" name="cred_sendy_options[brand_id]" value="' . esc_attr($selected) . '" placeholder="Brand ID">';
|
|
return;
|
|
}
|
|
|
|
echo '<select id="cred_sendy_brand_id" name="cred_sendy_options[brand_id]">';
|
|
echo '<option value="">' . esc_html__('— Sélectionner —', 'esi-creditdirect') . '</option>';
|
|
foreach ($brands as $brand) {
|
|
$isSel = selected($selected, $brand['id'], false);
|
|
echo '<option value="' . esc_attr($brand['id']) . '" ' . $isSel . '>' . esc_html($brand['name'] . ' (' . $brand['id'] . ')') . '</option>';
|
|
}
|
|
echo '</select>';
|
|
echo '<p class="description">' . esc_html__('Sélectionnez un brand pour filtrer les listes disponibles (optionnel)', 'esi-creditdirect') . '</p>';
|
|
}
|
|
|
|
/**
|
|
* 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 '<em>' . esc_html__('Renseignez d\'abord l\'URL et la clé API, puis enregistrez.', 'esi-creditdirect') . '</em>';
|
|
echo '<br />';
|
|
echo '<input type="text" class="regular-text" name="cred_sendy_options[list_id]" value="' . esc_attr($selected) . '" placeholder="List ID">';
|
|
return;
|
|
}
|
|
|
|
$lists = array();
|
|
try {
|
|
$lists = $this->get_lists();
|
|
} catch (\Throwable $e) {
|
|
echo '<div class="notice notice-error"><p>' . esc_html(sprintf(__('Erreur lors du chargement des listes: %s', 'esi-creditdirect'), $e->getMessage())) . '</p></div>';
|
|
}
|
|
|
|
if (empty($lists)) {
|
|
echo '<em>' . esc_html__('Aucune liste trouvée ou erreur. Vous pouvez saisir un ID manuellement.', 'esi-creditdirect') . '</em>';
|
|
echo '<br />';
|
|
echo '<input type="text" class="regular-text" name="cred_sendy_options[list_id]" value="' . esc_attr($selected) . '" placeholder="List ID">';
|
|
return;
|
|
}
|
|
|
|
echo '<select id="cred_sendy_list_id" name="cred_sendy_options[list_id]">';
|
|
echo '<option value="">' . esc_html__('— Sélectionner —', 'esi-creditdirect') . '</option>';
|
|
foreach ($lists as $list) {
|
|
$isSel = selected($selected, $list['id'], false);
|
|
$displayName = $list['name'];
|
|
if (isset($list['brand_name'])) {
|
|
$displayName = $list['brand_name'] . ' - ' . $list['name'];
|
|
}
|
|
echo '<option value="' . esc_attr($list['id']) . '" ' . $isSel . '>' . esc_html($displayName . ' (' . $list['id'] . ')') . '</option>';
|
|
}
|
|
echo '</select>';
|
|
}
|
|
|
|
/**
|
|
* 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());
|
|
}
|
|
}
|
|
}
|