Массовое изменение формата изображений в WordPress

17.09.2019 / development
Задача: на сайте более 1000 изображений в png формате, движок Wordpress, надо все изображения перевести в jpg и изменить расширение с png на jpg

Задача: на сайте более 1000 изображений в png формате, движок Wordpress, надо все изображения перевести в jpg и изменить расширение с png на jpg.

Для начала результаты тестов: оказалось что аналогичные jpg файлы весят от 1,5 до 5 раз меньше нежели png файлы, причем без потери качества.

Обновление базы данных

Таблица wp_posts

Замена значений post_mime_type и расширения в guid (видимо ссылка на изображение) у всех постов с post_type равным attachment и post_mime_type равным image/png:

UPDATE `wp_posts`
SET `post_mime_type`='image/jpg', `guid`=REPLACE(`guid`, '.png', '.jpg')
WHERE `post_type`='attachment' and `post_mime_type`='image/png'

Замена во всех постах расширения в ссылках на изображения:

UPDATE 'wp_posts'
SET 'post_content'=REPLACE('post_content', '.png', '.jpg')
WHERE 'post_type'='post'

Таблица wp_postmeta

Замена расширения файлов в meta_value у тех строк таблицы, которые имеют meta_key равным _wp_attached_file:

UPDATE 'wp_postmeta'
SET 'meta_value'=REPLACE('meta_value', '.png', '.jpg')
WHERE 'meta_key'='_wp_attached_file'`

Замена расширения файлов в meta_value у тех строк таблицы, которые имеют meta_key равным _wp_attachment_metadata:

UPDATE 'wp_postmeta'
SET 'meta_value'=REPLACE('meta_value', '.png', '.jpg')
WHERE 'meta_key'='_wp_attachment_metadata'

Замена значения meta_value у тех строк таблицы, которые имеют meta_key равным _wp_attachment_metadata:

UPDATE 'wp_postmeta'
SET 'meta_value'=REPLACE('meta_value', 'image/png', 'image/jpg')
WHERE 'meta_key'='_wp_attachment_metadata'

Конвертирование файлов на сервере

Необходимо конвертировать все изображения на сервере и изменить расширения при помощи php скрипта extensionedit.php, который разместим в директории wp-content:

set_time_limit(0);
 
//! пути относительно скрипта, откуда берем картинки
$srcPath = array(
    "uploads/2017",
    "uploads/2018"
    );

$extCurr = "png";
$extNew = "jpg";
 
//**************************************************************************
 
//! сканируем директорию, на выходе получаем все пути до файлов (в том числе и вложенных)
function ScanPath($dir)
{
    $d = [];
    $arr = opendir($dir);
  
    while($v = readdir($arr))
    {
        if($v == '.' or $v == '..') continue;
        if(!is_dir($dir.DIRECTORY_SEPARATOR.$v)) 
            $d[] = $v;
        if(is_dir($dir.DIRECTORY_SEPARATOR.$v)) 
        {
            $aArr = ScanPath($dir.DIRECTORY_SEPARATOR.$v);
                     
            for($i=0, $il=count($aArr); $i<$il; ++$i)
            {
                $d[] = $v.DIRECTORY_SEPARATOR.$aArr[$i];
            }
        }
    }
  
    return $d;
}
 
//! загрузка изображения, возвращает resource
function LoadImg($path)
{
    return imagecreatefromstring(file_get_contents($path));
}
 
function GetExtension($file) 
{
    return substr(strrchr($file, '.'), 1);
}
 
//**************************************************************************
 
$countEdit = 0;
    
//проходимся по всем указанным путям, ищем изображения
for($i=0, $il=count($srcPath); $i<$il; ++$i) {
    //получаем список файлов (с путями)
    $files = ScanPath($srcPath[$i]);
        
    //проходимся по списку файлов
    for($k=0, $kl=count($files); $k<$kl; ++$k) {
        if(mb_stripos($files[$k], "favicon") !== false)
            continue;
            
            
        $srcParh = $srcPath[$i] . DIRECTORY_SEPARATOR . $files[$k];
            
        //echo $srcParh . "|" . GetExtension($srcParh);
            
        if(GetExtension($srcParh) == $extCurr) {
            $fileName = basename($srcParh, "." . $extCurr);
            $newParh = dirname($srcParh);
            $newParh = $newParh . DIRECTORY_SEPARATOR . $fileName . "." . $extNew;
                
            $srcImg = LoadImg($srcParh);
            rename($srcParh, $newParh);
            imagejpeg($srcImg, $newParh, 100);
            ++$countEdit;
        }
    }
}

echo "Edit extension " . $countEdit . " files";

Запуск скрипта: my-site.ru/wp-content/extensionedit.php

Ссылки на изображения на сторонних сайтах

Будет плохо если ссылки на png файлы будут битыми, поэтому надо сделать чтобы они стали доступны, но с редиректом.

Для этого в файл .htaccess нужно добавить (перед всеми правилами):

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(wp\-content/uploads/.*)\.png$ /$1.jpg [L,QSA]

Мой итоговый .htaccess для Wordpress:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(wp\-content/uploads/.*)\.png$ /$1.jpg [L,QSA]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
 
# END WordPress

Теперь все изображения доступны и по адресу с png расширение, однако с редиректом.

Итог