.
This commit is contained in:
156
wp-thumbor.php
156
wp-thumbor.php
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
/*
|
/*
|
||||||
Plugin Name: WP Thumbor Integration
|
Plugin Name: WP Thumbor Integration
|
||||||
Description: Intègre Thumbor dans WordPress en transformant les URLs des images sur le front-end. 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 les erreurs getimagesize().
|
Description: Intègre Thumbor dans WordPress en transformant les URLs des images présentes dans le <body> (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 <body> ne sont pas modifiés.
|
||||||
Version: 1.3
|
Version: 1.4
|
||||||
Author: MrRaph_
|
Author: Votre Nom
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('ABSPATH')) {
|
if (!defined('ABSPATH')) {
|
||||||
@@ -25,7 +25,7 @@ function wp_thumbor_get_options() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Vérifie si la transformation Thumbor doit être désactivée pour l'appelant.
|
* Vérifie si la transformation Thumbor doit être désactivée pour l'appelant.
|
||||||
* Par exemple, si l'appel provient du plugin Optimize More (pour éviter des getimagesize sur une URL Thumbor).
|
* Par exemple, si l'appel provient du plugin Optimize More.
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
@@ -61,7 +61,6 @@ function wp_thumbor_settings_page() {
|
|||||||
wp_die(__('Vous n\'avez pas l\'autorisation d\'accéder à cette page.'));
|
wp_die(__('Vous n\'avez pas l\'autorisation d\'accéder à cette page.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sauvegarde des réglages lors de la soumission du formulaire.
|
|
||||||
if (isset($_POST['wp_thumbor_nonce']) && wp_verify_nonce($_POST['wp_thumbor_nonce'], 'wp_thumbor_save_settings')) {
|
if (isset($_POST['wp_thumbor_nonce']) && wp_verify_nonce($_POST['wp_thumbor_nonce'], 'wp_thumbor_save_settings')) {
|
||||||
$options = array();
|
$options = array();
|
||||||
$options['thumbor_base_url'] = isset($_POST['thumbor_base_url']) ? esc_url_raw(trim($_POST['thumbor_base_url'])) : '';
|
$options['thumbor_base_url'] = isset($_POST['thumbor_base_url']) ? esc_url_raw(trim($_POST['thumbor_base_url'])) : '';
|
||||||
@@ -129,7 +128,7 @@ function wp_thumbor_extract_dimensions_from_url($url) {
|
|||||||
* Si aucune dimension n'est précisée, la partie redimensionnement est omise.
|
* Si aucune dimension n'est précisée, la partie redimensionnement est omise.
|
||||||
*
|
*
|
||||||
* @param string $url L'URL originale de l'image.
|
* @param string $url L'URL originale de l'image.
|
||||||
* @param int|null $width La largeur souhaitée (provenant éventuellement des attributs HTML).
|
* @param int|null $width La largeur souhaitée.
|
||||||
* @param int|null $height La hauteur souhaitée.
|
* @param int|null $height La hauteur souhaitée.
|
||||||
* @return string L'URL transformée.
|
* @return string L'URL transformée.
|
||||||
*/
|
*/
|
||||||
@@ -138,7 +137,10 @@ function wp_thumbor_transform_url($url, $width = null, $height = null) {
|
|||||||
if (is_admin()) {
|
if (is_admin()) {
|
||||||
return $url;
|
return $url;
|
||||||
}
|
}
|
||||||
// Si l'appel provient d'un plugin tiers (ex. Optimize More), on retourne l'URL d'origine
|
// Ignorer le fichier favicon.ico
|
||||||
|
if (basename(parse_url($url, PHP_URL_PATH)) === 'favicon.ico') {
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
if (wp_thumbor_should_skip_transform()) {
|
if (wp_thumbor_should_skip_transform()) {
|
||||||
return $url;
|
return $url;
|
||||||
}
|
}
|
||||||
@@ -176,7 +178,7 @@ function wp_thumbor_transform_url($url, $width = null, $height = null) {
|
|||||||
// Préparation de la partie filtres à partir des réglages
|
// Préparation de la partie filtres à partir des réglages
|
||||||
$thumbor_filters = isset($options['thumbor_filters']) ? trim($options['thumbor_filters']) : '';
|
$thumbor_filters = isset($options['thumbor_filters']) ? trim($options['thumbor_filters']) : '';
|
||||||
if (!empty($thumbor_filters)) {
|
if (!empty($thumbor_filters)) {
|
||||||
// Correction apportée ici : utiliser "/" au lieu de ":/" après les filtres.
|
// Utilise "/" comme séparateur attendu par Thumbor.
|
||||||
$filterPart = 'filters:' . $thumbor_filters . '/';
|
$filterPart = 'filters:' . $thumbor_filters . '/';
|
||||||
} else {
|
} else {
|
||||||
$filterPart = '';
|
$filterPart = '';
|
||||||
@@ -187,80 +189,53 @@ function wp_thumbor_transform_url($url, $width = null, $height = null) {
|
|||||||
|
|
||||||
// Détermine l'endpoint : si une clé secrète est renseignée, on signe, sinon on utilise "unsafe"
|
// Détermine l'endpoint : si une clé secrète est renseignée, on signe, sinon on utilise "unsafe"
|
||||||
if (!empty($options['thumbor_secret_key'])) {
|
if (!empty($options['thumbor_secret_key'])) {
|
||||||
// Calcul du HMAC-SHA1 en mode binaire
|
|
||||||
$hmac = hash_hmac('sha1', $path_to_sign, $options['thumbor_secret_key'], true);
|
$hmac = hash_hmac('sha1', $path_to_sign, $options['thumbor_secret_key'], true);
|
||||||
// Encodage en base64 en mode URL-safe (remplacement + -> - et / -> _)
|
|
||||||
$encoded_signature = strtr(base64_encode($hmac), '+/', '-_');
|
$encoded_signature = strtr(base64_encode($hmac), '+/', '-_');
|
||||||
// L'endpoint sécurisé est le code signé
|
|
||||||
$endpoint = $encoded_signature;
|
$endpoint = $encoded_signature;
|
||||||
} else {
|
} else {
|
||||||
$endpoint = 'unsafe';
|
$endpoint = 'unsafe';
|
||||||
}
|
}
|
||||||
|
|
||||||
$transformed_url = $thumbor_base_url . '/' . $endpoint . '/' . $path_to_sign;
|
return $thumbor_base_url . '/' . $endpoint . '/' . $path_to_sign;
|
||||||
return $transformed_url;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filtre l'URL d'une pièce jointe image pour y intégrer Thumbor.
|
* Filtre le contenu des articles (the_content) pour transformer les images.
|
||||||
*/
|
* Cette fonction travaille sur le HTML complet.
|
||||||
function wp_thumbor_filter_attachment_url($url, $post_id) {
|
|
||||||
// Si l'appel provient d'un plugin tiers (ex. Optimize More), on retourne l'URL d'origine.
|
|
||||||
if (wp_thumbor_should_skip_transform()) {
|
|
||||||
return $url;
|
|
||||||
}
|
|
||||||
|
|
||||||
$mime = get_post_mime_type($post_id);
|
|
||||||
if (strpos($mime, 'image/') === 0) {
|
|
||||||
return wp_thumbor_transform_url($url);
|
|
||||||
}
|
|
||||||
return $url;
|
|
||||||
}
|
|
||||||
//add_filter('wp_get_attachment_url', 'wp_thumbor_filter_attachment_url', 10, 2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parcourt le contenu HTML d'un article et modifie les attributs src, data-src, srcset et data-srcset
|
|
||||||
* des balises <img> en y intégrant les paramètres de redimensionnement (issus des attributs width/height)
|
|
||||||
* et les filtres Thumbor.
|
|
||||||
*/
|
*/
|
||||||
function wp_thumbor_filter_content_images($content) {
|
function wp_thumbor_filter_content_images($content) {
|
||||||
// Ne pas transformer dans l'administration
|
|
||||||
if (is_admin()) {
|
if (is_admin()) {
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
if (empty($content)) {
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
libxml_use_internal_errors(true);
|
libxml_use_internal_errors(true);
|
||||||
$dom = new DOMDocument();
|
$dom = new DOMDocument();
|
||||||
// Conversion pour éviter les problèmes d'encodage
|
$html = mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8');
|
||||||
$dom->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'));
|
if (empty($html)) {
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
$dom->loadHTML($html);
|
||||||
$images = $dom->getElementsByTagName('img');
|
$images = $dom->getElementsByTagName('img');
|
||||||
foreach ($images as $img) {
|
foreach ($images as $img) {
|
||||||
// Récupération de la largeur et hauteur si présentes
|
|
||||||
$width = $img->getAttribute('width');
|
$width = $img->getAttribute('width');
|
||||||
$height = $img->getAttribute('height');
|
$height = $img->getAttribute('height');
|
||||||
$width = $width ? intval($width) : null;
|
$width = $width ? intval($width) : null;
|
||||||
$height = $height ? intval($height) : null;
|
$height = $height ? intval($height) : null;
|
||||||
|
|
||||||
// Transformation de l'attribut "src" si c'est une URL absolue
|
|
||||||
if ($img->hasAttribute('src') && preg_match('/^https?:\/\//', $img->getAttribute('src'))) {
|
if ($img->hasAttribute('src') && preg_match('/^https?:\/\//', $img->getAttribute('src'))) {
|
||||||
$new_src = wp_thumbor_transform_url($img->getAttribute('src'), $width, $height);
|
$img->setAttribute('src', wp_thumbor_transform_url($img->getAttribute('src'), $width, $height));
|
||||||
$img->setAttribute('src', $new_src);
|
|
||||||
}
|
}
|
||||||
// Transformation de "data-src" pour le lazyload
|
|
||||||
if ($img->hasAttribute('data-src') && preg_match('/^https?:\/\//', $img->getAttribute('data-src'))) {
|
if ($img->hasAttribute('data-src') && preg_match('/^https?:\/\//', $img->getAttribute('data-src'))) {
|
||||||
$new_data_src = wp_thumbor_transform_url($img->getAttribute('data-src'), $width, $height);
|
$img->setAttribute('data-src', wp_thumbor_transform_url($img->getAttribute('data-src'), $width, $height));
|
||||||
$img->setAttribute('data-src', $new_data_src);
|
|
||||||
}
|
}
|
||||||
// Traitement de l'attribut "srcset"
|
|
||||||
if ($img->hasAttribute('srcset')) {
|
if ($img->hasAttribute('srcset')) {
|
||||||
$srcset = $img->getAttribute('srcset');
|
$srcsetItems = explode(',', $img->getAttribute('srcset'));
|
||||||
$newSrcset = array();
|
$newSrcset = array();
|
||||||
// Chaque élément est séparé par une virgule
|
|
||||||
$srcsetItems = explode(',', $srcset);
|
|
||||||
foreach ($srcsetItems as $item) {
|
foreach ($srcsetItems as $item) {
|
||||||
$parts = preg_split('/\s+/', trim($item));
|
$parts = preg_split('/\s+/', trim($item));
|
||||||
if (!empty($parts[0]) && preg_match('/^https?:\/\//', $parts[0])) {
|
if (!empty($parts[0]) && preg_match('/^https?:\/\//', $parts[0])) {
|
||||||
$newURL = wp_thumbor_transform_url($parts[0]);
|
$newURL = wp_thumbor_transform_url($parts[0]);
|
||||||
// Conserver le descripteur (ex: "1707w") si présent
|
|
||||||
$newSrcset[] = isset($parts[1]) ? $newURL . ' ' . $parts[1] : $newURL;
|
$newSrcset[] = isset($parts[1]) ? $newURL . ' ' . $parts[1] : $newURL;
|
||||||
} else {
|
} else {
|
||||||
$newSrcset[] = $item;
|
$newSrcset[] = $item;
|
||||||
@@ -268,11 +243,9 @@ function wp_thumbor_filter_content_images($content) {
|
|||||||
}
|
}
|
||||||
$img->setAttribute('srcset', implode(', ', $newSrcset));
|
$img->setAttribute('srcset', implode(', ', $newSrcset));
|
||||||
}
|
}
|
||||||
// Traitement de l'attribut "data-srcset"
|
|
||||||
if ($img->hasAttribute('data-srcset')) {
|
if ($img->hasAttribute('data-srcset')) {
|
||||||
$srcset = $img->getAttribute('data-srcset');
|
$srcsetItems = explode(',', $img->getAttribute('data-srcset'));
|
||||||
$newSrcset = array();
|
$newSrcset = array();
|
||||||
$srcsetItems = explode(',', $srcset);
|
|
||||||
foreach ($srcsetItems as $item) {
|
foreach ($srcsetItems as $item) {
|
||||||
$parts = preg_split('/\s+/', trim($item));
|
$parts = preg_split('/\s+/', trim($item));
|
||||||
if (!empty($parts[0]) && preg_match('/^https?:\/\//', $parts[0])) {
|
if (!empty($parts[0]) && preg_match('/^https?:\/\//', $parts[0])) {
|
||||||
@@ -285,16 +258,81 @@ function wp_thumbor_filter_content_images($content) {
|
|||||||
$img->setAttribute('data-srcset', implode(', ', $newSrcset));
|
$img->setAttribute('data-srcset', implode(', ', $newSrcset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// On récupère le contenu du <body> pour éviter d'inclure la balise <html> ou <body>
|
// Renvoie le document HTML complet (head, body, etc.)
|
||||||
$body = $dom->getElementsByTagName('body')->item(0);
|
return $dom->saveHTML();
|
||||||
$new_content = '';
|
|
||||||
foreach ($body->childNodes as $child) {
|
|
||||||
$new_content .= $dom->saveHTML($child);
|
|
||||||
}
|
|
||||||
return $new_content;
|
|
||||||
}
|
}
|
||||||
add_filter('the_content', 'wp_thumbor_filter_content_images');
|
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 <img>.
|
||||||
|
*/
|
||||||
|
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 <html>, <head> et <body>.
|
||||||
|
return $dom->saveHTML();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialisation du plugin (chargement des traductions, etc.).
|
* Initialisation du plugin (chargement des traductions, etc.).
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user