(contenu, header, etc.). L'URL de Thumbor, les filtres et la clé secrète sont configurables. Les images sont redimensionnées si une taille est spécifiée dans le nom du fichier ou dans les attributs HTML. La transformation est désactivée dans certains cas (ex. Optimize More) pour éviter des erreurs getimagesize(). Le favicon et les images en dehors du ne sont pas modifiés. Version: 1.4 Author: Votre Nom */ if (!defined('ABSPATH')) { exit; // Sécurisation } /** * Récupère les options du plugin avec des valeurs par défaut. */ function wp_thumbor_get_options() { $defaults = array( 'thumbor_base_url' => '', 'thumbor_filters' => '', 'thumbor_secret_key' => '', ); $options = get_option('wp_thumbor_options', $defaults); return wp_parse_args($options, $defaults); } /** * Vérifie si la transformation Thumbor doit être désactivée pour l'appelant. * Par exemple, si l'appel provient du plugin Optimize More. * * @return bool */ function wp_thumbor_should_skip_transform() { $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10); foreach ($trace as $frame) { if (isset($frame['file']) && stripos($frame['file'], 'optimize-more') !== false) { return true; } } return false; } /** * Ajoute un menu de réglages dans l'administration de WordPress. */ function wp_thumbor_admin_menu() { add_options_page( 'Réglages WP Thumbor Integration', 'WP Thumbor Integration', 'manage_options', 'wp-thumbor-integration', 'wp_thumbor_settings_page' ); } add_action('admin_menu', 'wp_thumbor_admin_menu'); /** * Affiche la page de réglages du plugin dans l'administration. */ function wp_thumbor_settings_page() { if (!current_user_can('manage_options')) { wp_die(__('Vous n\'avez pas l\'autorisation d\'accéder à cette page.')); } if (isset($_POST['wp_thumbor_nonce']) && wp_verify_nonce($_POST['wp_thumbor_nonce'], 'wp_thumbor_save_settings')) { $options = array(); $options['thumbor_base_url'] = isset($_POST['thumbor_base_url']) ? esc_url_raw(trim($_POST['thumbor_base_url'])) : ''; $options['thumbor_filters'] = isset($_POST['thumbor_filters']) ? sanitize_text_field(trim($_POST['thumbor_filters'])) : ''; $options['thumbor_secret_key'] = isset($_POST['thumbor_secret_key']) ? sanitize_text_field(trim($_POST['thumbor_secret_key'])) : ''; update_option('wp_thumbor_options', $options); echo '

Les paramètres ont été mis à jour.

'; } $options = wp_thumbor_get_options(); ?>

WP Thumbor Integration - Réglages

Thumbor Base URL

Entrez l'URL de base de votre serveur Thumbor (sans barre oblique finale).

Filtres Thumbor

Entrez la liste des filtres à appliquer, séparés par des virgules, sans le préfixe "filters:" ni le suffixe ":/".

Clé secrète Thumbor

Entrez la clé secrète pour signer les URLs Thumbor. Laissez vide pour utiliser l'endpoint "unsafe".

intval($matches[1]), 'height' => intval($matches[2])); } return false; } /** * Transforme l'URL d'une image en ajoutant l'endpoint Thumbor (signé si clé secrète renseignée), * les options de redimensionnement et les filtres configurés. * * Le format généré est : * {thumbor_base_url}/{endpoint}/[width]x[height]/[filters:...]/{url} * * Si aucune dimension n'est précisée, la partie redimensionnement est omise. * * @param string $url L'URL originale de l'image. * @param int|null $width La largeur souhaitée. * @param int|null $height La hauteur souhaitée. * @return string L'URL transformée. */ function wp_thumbor_transform_url($url, $width = null, $height = null) { // Ne pas transformer dans l'administration if (is_admin()) { return $url; } // Ignorer le fichier favicon.ico if (basename(parse_url($url, PHP_URL_PATH)) === 'favicon.ico') { return $url; } if (wp_thumbor_should_skip_transform()) { return $url; } $options = wp_thumbor_get_options(); $thumbor_base_url = isset($options['thumbor_base_url']) ? rtrim($options['thumbor_base_url'], '/') : ''; if (empty($thumbor_base_url)) { return $url; } // Évite une double transformation if (strpos($url, $thumbor_base_url) === 0) { return $url; } // Si aucune dimension n'est fournie via les attributs, tenter d'extraire depuis le nom du fichier if (empty($width) && empty($height)) { $dimensions = wp_thumbor_extract_dimensions_from_url($url); if ($dimensions) { $width = $dimensions['width']; $height = $dimensions['height']; } } // Préparation de la partie redimensionnement if ($width || $height) { $w = $width ? $width : 0; $h = $height ? $height : 0; $resize = $w . 'x' . $h . '/'; } else { $resize = ''; } // Préparation de la partie filtres à partir des réglages $thumbor_filters = isset($options['thumbor_filters']) ? trim($options['thumbor_filters']) : ''; if (!empty($thumbor_filters)) { // Utilise "/" comme séparateur attendu par Thumbor. $filterPart = 'filters:' . $thumbor_filters . '/'; } else { $filterPart = ''; } // Construction de la chaîne d'options à signer $path_to_sign = $resize . $filterPart . $url; // Détermine l'endpoint : si une clé secrète est renseignée, on signe, sinon on utilise "unsafe" if (!empty($options['thumbor_secret_key'])) { $hmac = hash_hmac('sha1', $path_to_sign, $options['thumbor_secret_key'], true); $encoded_signature = strtr(base64_encode($hmac), '+/', '-_'); $endpoint = $encoded_signature; } else { $endpoint = 'unsafe'; } return $thumbor_base_url . '/' . $endpoint . '/' . $path_to_sign; } /** * Filtre le contenu des articles (the_content) pour transformer les images. * Cette fonction travaille sur le HTML complet. */ function wp_thumbor_filter_content_images($content) { if (is_admin()) { return $content; } if (empty($content)) { return $content; } libxml_use_internal_errors(true); $dom = new DOMDocument(); $html = mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'); if (empty($html)) { return $content; } $dom->loadHTML($html); $images = $dom->getElementsByTagName('img'); foreach ($images as $img) { $width = $img->getAttribute('width'); $height = $img->getAttribute('height'); $width = $width ? intval($width) : null; $height = $height ? intval($height) : null; if ($img->hasAttribute('src') && preg_match('/^https?:\/\//', $img->getAttribute('src'))) { $img->setAttribute('src', wp_thumbor_transform_url($img->getAttribute('src'), $width, $height)); } if ($img->hasAttribute('data-src') && preg_match('/^https?:\/\//', $img->getAttribute('data-src'))) { $img->setAttribute('data-src', wp_thumbor_transform_url($img->getAttribute('data-src'), $width, $height)); } if ($img->hasAttribute('srcset')) { $srcsetItems = explode(',', $img->getAttribute('srcset')); $newSrcset = array(); foreach ($srcsetItems as $item) { $parts = preg_split('/\s+/', trim($item)); if (!empty($parts[0]) && preg_match('/^https?:\/\//', $parts[0])) { $newURL = wp_thumbor_transform_url($parts[0]); $newSrcset[] = isset($parts[1]) ? $newURL . ' ' . $parts[1] : $newURL; } else { $newSrcset[] = $item; } } $img->setAttribute('srcset', implode(', ', $newSrcset)); } if ($img->hasAttribute('data-srcset')) { $srcsetItems = explode(',', $img->getAttribute('data-srcset')); $newSrcset = array(); foreach ($srcsetItems as $item) { $parts = preg_split('/\s+/', trim($item)); if (!empty($parts[0]) && preg_match('/^https?:\/\//', $parts[0])) { $newURL = wp_thumbor_transform_url($parts[0]); $newSrcset[] = isset($parts[1]) ? $newURL . ' ' . $parts[1] : $newURL; } else { $newSrcset[] = $item; } } $img->setAttribute('data-srcset', implode(', ', $newSrcset)); } } // Renvoie le document HTML complet (head, body, etc.) return $dom->saveHTML(); } add_filter('the_content', 'wp_thumbor_filter_content_images'); /** * Démarre la mise en tampon de la sortie pour traiter toutes les images présentes dans le HTML final. */ function wp_thumbor_start_output_buffer() { if (!is_admin() && !defined('DOING_AJAX')) { ob_start('wp_thumbor_output_buffer_callback'); } } add_action('template_redirect', 'wp_thumbor_start_output_buffer'); /** * Callback de traitement de la sortie (output buffer). * Parcourt le document HTML complet et transforme les URLs de toutes les balises . */ function wp_thumbor_output_buffer_callback($buffer) { if (empty($buffer)) { return $buffer; } libxml_use_internal_errors(true); $dom = new DOMDocument(); $html = mb_convert_encoding($buffer, 'HTML-ENTITIES', 'UTF-8'); if (empty($html)) { return $buffer; } $dom->loadHTML($html); $images = $dom->getElementsByTagName('img'); foreach ($images as $img) { $width = $img->getAttribute('width'); $height = $img->getAttribute('height'); $width = $width ? intval($width) : null; $height = $height ? intval($height) : null; if ($img->hasAttribute('src') && preg_match('/^https?:\/\//', $img->getAttribute('src'))) { $img->setAttribute('src', wp_thumbor_transform_url($img->getAttribute('src'), $width, $height)); } if ($img->hasAttribute('data-src') && preg_match('/^https?:\/\//', $img->getAttribute('data-src'))) { $img->setAttribute('data-src', wp_thumbor_transform_url($img->getAttribute('data-src'), $width, $height)); } if ($img->hasAttribute('srcset')) { $srcsetItems = explode(',', $img->getAttribute('srcset')); $newSrcset = array(); foreach ($srcsetItems as $item) { $parts = preg_split('/\s+/', trim($item)); if (!empty($parts[0]) && preg_match('/^https?:\/\//', $parts[0])) { $newURL = wp_thumbor_transform_url($parts[0]); $newSrcset[] = isset($parts[1]) ? $newURL . ' ' . $parts[1] : $newURL; } else { $newSrcset[] = $item; } } $img->setAttribute('srcset', implode(', ', $newSrcset)); } if ($img->hasAttribute('data-srcset')) { $srcsetItems = explode(',', $img->getAttribute('data-srcset')); $newSrcset = array(); foreach ($srcsetItems as $item) { $parts = preg_split('/\s+/', trim($item)); if (!empty($parts[0]) && preg_match('/^https?:\/\//', $parts[0])) { $newURL = wp_thumbor_transform_url($parts[0]); $newSrcset[] = isset($parts[1]) ? $newURL . ' ' . $parts[1] : $newURL; } else { $newSrcset[] = $item; } } $img->setAttribute('data-srcset', implode(', ', $newSrcset)); } } // Renvoie le document HTML complet, préservant , et . return $dom->saveHTML(); } /** * Initialisation du plugin (chargement des traductions, etc.). */ function wp_thumbor_init() { load_plugin_textdomain('wp-thumbor-integration', false, dirname(plugin_basename(__FILE__)) . '/languages/'); } add_action('plugins_loaded', 'wp_thumbor_init');