Как сделать на сайте WordPress динамический watermark для Woocommerce?

Инструкция: Для того чтобы сделать на сайте WordPress динамический watermark для Woocommerce

Dynamic Watermark WordPress Woocommerce

1. В корне сайта создаем пустую папку wm-cache (права 777)

2. В корень сайта добавляем сам файл watermark с названием logo.png (Размер: 1000x1000 px (или больше), PNG с прозрачным фоном, 644)

3. В корне сайта создаем файл watermark.php

<?php
// watermark.php — Динамическое наложение водяного знака

// НАСТРОЙКИ
$watermark_file = __DIR__ . '/logo.png'; 
$cache_folder   = __DIR__ . '/wm-cache'; 
$opacity        = 100; // Ставим 100, так как используем imagecopy (прозрачность берется из файла logo.png)
$margin         = 20;                    
$position       = 'center'; // По центру

if (!isset($_GET['src'])) {
    http_response_code(400);
    die('No image provided');
}

$image_path = urldecode($_GET['src']);

$uploads_dir = 'wp-content/uploads';
if (strpos($image_path, $uploads_dir) === false) {
    http_response_code(403);
    die('Access denied');
}

$image_path = preg_replace('#^https?://[^/]+#', '', $image_path);
$abs_path = $_SERVER['DOCUMENT_ROOT'] . '/' . $image_path;

if (!file_exists($abs_path)) {
    http_response_code(404);
    die('Image not found');
}

if (!is_dir($cache_folder)) mkdir($cache_folder, 0755, true);
// Добавил v3, чтобы сбросить старый кэш с черными квадратами
$cache_name = md5($image_path . $opacity . $position . 'v3') . '.jpg';
$cache_path = $cache_folder . '/' . $cache_name;

if (file_exists($cache_path)) {
    header('Content-Type: image/jpeg');
    header('Cache-Control: public, max-age=31536000');
    readfile($cache_path);
    exit;
}

if (!extension_loaded('gd')) die('GD Library not installed');

$info = getimagesize($abs_path);
$mime = $info['mime'];

switch ($mime) {
    case 'image/jpeg': $source = imagecreatefromjpeg($abs_path); break;
    case 'image/png':  $source = imagecreatefrompng($abs_path); break;
    case 'image/gif':  $source = imagecreatefromgif($abs_path); break;
    case 'image/webp': $source = imagecreatefromwebp($abs_path); break;
    default: die('Unsupported format');
}

// === ВАЖНО: Включаем поддержку альфа-канала ===
imagealphablending($source, true);
imagesavealpha($source, true);

$wm = imagecreatefrompng($watermark_file);
// Сохраняем прозрачность логотипа
imagealphablending($wm, true);
imagesavealpha($wm, true);

$wm_w = imagesx($wm);
$wm_h = imagesy($wm);
$img_w = imagesx($source);
$img_h = imagesy($source);

// Масштабируем, если логотип больше 50% картинки
if ($wm_w > $img_w * 0.5) {
    $ratio = ($img_w * 0.5) / $wm_w;
    $new_w = $wm_w * $ratio;
    $new_h = $wm_h * $ratio;
    $wm_resized = imagecreatetruecolor($new_w, $new_h);
    imagealphablending($wm_resized, false);
    imagesavealpha($wm_resized, true);
    $transparent = imagecolorallocatealpha($wm_resized, 0, 0, 0, 127);
    imagefill($wm_resized, 0, 0, $transparent);
    imagecopyresampled($wm_resized, $wm, 0, 0, 0, 0, $new_w, $new_h, $wm_w, $wm_h);
    $wm = $wm_resized;
    $wm_w = $new_w;
    $wm_h = $new_h;
}

// Координаты (Центр)
$x = ($img_w - $wm_w) / 2;
$y = ($img_h - $wm_h) / 2;

// === НАКЛАДКА (ИСПОЛЬЗУЕМ imagecopy для идеальной прозрачности) ===
// imagecopymerge дает черный фон на прозрачных PNG. imagecopy - нет.
imagecopy($source, $wm, $x, $y, 0, 0, $wm_w, $wm_h);
// ===========================================================

// Сохраняем в кэш
imagejpeg($source, $cache_path, 85);
header('Content-Type: image/jpeg');
header('Cache-Control: public, max-age=31536000');
imagejpeg($source, null, 85);

imagedestroy($source);
imagedestroy($wm);
?>

4. В файл functions.php добавляем код:


add_filter('wp_get_attachment_image_src', 'wm_woo_by_id', 999, 4);

function wm_woo_by_id($image, $attachment_id, $size, $icon) {
    if (is_admin() || empty($image) || $icon) return $image;
    
    $url = $image[0];
    if (!preg_match('/\.(jpe?g|png|webp)/i', $url)) return $image;
    if (strpos($url, '/wp-content/uploads/') === false) return $image;
    
    // Получаем все ID товаров
    $product_ids = get_posts([
        'post_type' => 'product',
        'fields' => 'ids',
        'numberposts' => -1,
        'post_status' => 'publish'
    ]);
    
    // Проверяем, используется ли это изображение в товаре
    $is_used = false;
    foreach ($product_ids as $pid) {
        if (get_post_thumbnail_id($pid) == $attachment_id) {
            $is_used = true;
            break;
        }
        $gallery = get_post_meta($pid, '_product_image_gallery', true);
        if ($gallery && in_array($attachment_id, array_map('intval', explode(',', $gallery)))) {
            $is_used = true;
            break;
        }
    }
    
    if (!$is_used) return $image;
    
    // Формируем маскированный URL
    $relative = str_replace(home_url(), '', $url);
    $relative = str_replace('/wp-content/uploads/', '', $relative);
    $image[0] = home_url('/wm-uploads/' . $relative);
    
    return $image;
}

5. В файл .htaccess
Найди в .htaccess строку # BEGIN WordPress и вставь правило маскировки сразу перед ней.
Или вообще в самом начале после RewriteEngine On

# === МАСКИРОВКА ВОДЯНОГО ЗНАКА ===
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^wm-uploads/(.+)$ /watermark.php?src=/wp-content/uploads/$1 [L,QSA]
# =================================
guest
Закрыть меню