Исправление сломанных названий кириллических файлов-картинок в папке uploads
Здравствуйте.
Есть сайт на котором раньше загружались картинки с кириллическими названиями фалов. Теперь я перенес этот сайт на другой хостинг и все названия картинок где есть кириллица поломались.
Было: картинка.jpg, стало картинка.jpg.
Таких поврежденных картинок у меня много и исправлять их вручную практически нереально...
Помогите пожалуйста это поправить, как-то пакетно с помощью скрипта.
Я в PHP немного разбираюсь, не сложные коды могу править.
Я как-то сталкивался с таким ниже выложу код которым я это поправил.
Но для начала замечу: названия файлов желательно хранить в латинице всегда! Так проблем меньше. И если даже загружается файл с кириллицей в названии, то название налету должно менять на латиницу, как это происходит при использовании плагина cry-to-lat, кстати в плагине Cyr to Lat enhanced этот момент учтен и если использовать его, то у таких проблем не будет.
Этот код переделывает кириллические названия в латиницу...
Код, который я написал для исправления таких файлов разделен на части. Для его использования надо понимать PHP, хотя бы на уровне того что примерно происходит и если надо кое-где подправить под себя или для проверки... Если использовать код сразу без проверок и понимания что происходит, то последствия могут быть неожиданными...
Перед использованием кода, обязательно сделайте бэкап всего что можно... Далее запускайте каждую часть отдельно и смотрите все ли делается правильно...
Для вызова каждой части добавляйте в URL GET параметр: например первая часть вызывается так:
example.com?repair_files.<?php /** * ЧАСТЬ 1: ремонтирует поломанные названия кириллических файлов в папке uploads. * Когда файл выглядит так: Дом_РёР·_клеёного_Р±СЂСѓСЃР° - это 'cp-1251' */ if( isset($_GET['repair_files']) ){ // настройки $maindir = wp_upload_dir(); $debug = 1; // проверка - $debug // Прежде чем запускать, закиньте один файл в папку uploads и запустите эту проверку, этот файл должен переименоваться. // Если все работает, то выключаем debug, удаляем проверочный файл и запускаем полное переименование - это может занять время. Для работы с большим объемом файлов скрипт не рассчитан... if( $debug ){ foreach( glob( $maindir['basedir'] ."/*") as $fname ){ if( is_file($fname) ){ echo var_dump( __repair_cyrilic_filenames_rename( $fname ) ); echo ' - '. dirname($fname) .' - '. basename( $fname ) ."<br>\n"; } } die('КОНЕЦ'); } // запускаем полное переименование в папке uploads if( ! $debug ){ repair_cyrilic_filenames( $maindir['basedir'] ); die('КОНЕЦ'); } } // функции function repair_cyrilic_filenames( $dir ){ if( is_dir($dir) ){ foreach( glob("$dir/*") as $fname ){ call_user_func( __FUNCTION__, $fname ); // рекурсия } } //repair elseif( is_file($dir) ){ echo __repair_cyrilic_filenames_rename( $dir ) ? 'ОК - ' : 'ERROR - '; echo $dir ."<br>\n"; } } function __repair_cyrilic_filenames_rename( $fname ){ $new_fname = mb_convert_encoding( $fname, 'cp-1251', 'utf-8'); return @ rename( $fname, $new_fname ); } /** * ЧАСТЬ 2: транслитерация названий файлов в каталоге */ if( isset($_GET['sanitize_file_name_in_dir']) ){ // запуск $maindir = wp_upload_dir(); sanitize_file_name_in_dir( $maindir['basedir'] ); die('КОНЕЦ'); } function sanitize_file_name_in_dir( $dir ){ if( is_dir($dir) ){ foreach( glob("$dir/*") as $fname ){ call_user_func( __FUNCTION__, $fname ); // рекурсия } } //repair elseif( is_file($dir) ){ if( preg_match( '~[^/]+$~', $dir, $m ) ){ $_fname = $m[0]; $_dir = str_replace( $_fname, '', $dir ); $_fname = mb_convert_encoding( $_fname, 'utf-8', 'cp-1251'); $_fname = sanitize_file_name( $_fname ); if($_fname){ $new_fname = $_dir . $_fname; if( ($dir != $new_fname) && @ rename( $dir, $new_fname ) ) echo 'OK - '. $dir .' >>> '. $new_fname ."<br>\n"; else echo 'ERROR - '. $dir .' >>> '. $new_fname ."<br>\n"; } } } } /** * ЧАСТЬ 3: транслитерация названий файлов в базе данных */ if( isset($_GET['sanitize_filename_in_db']) ){ sanitize_filename_in_db(); die('КОНЕЦ'); } function sanitize_filename_in_db(){ global $wpdb; $ress = $wpdb->get_results("SELECT ID, guid FROM $wpdb->posts WHERE post_type = 'attachment' AND guid LIKE '%uploads%'"); if( $ress ){ foreach( $ress as $item ){ if( ! preg_match( '~[^/]+$~', $item->guid, $m ) ) continue; $_fname = $m[0]; $_pre = str_replace( $_fname, '', $item->guid ); $_fname = sanitize_file_name( $_fname ); $new_guid = $_pre . $_fname; if( $item->guid != $new_guid ){ $done = $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET guid = %s WHERE ID = %d", $new_guid, $item->ID ) ); echo ($done ? "OK - $item->guid >>> $new_guid" : "ERROR - $item->guid") ."<br>\n"; } } } // поправим данные в метаданных //_wp_attached_file $ress = $wpdb->get_results("SELECT * FROM $wpdb->postmeta WHERE meta_key = '_wp_attached_file'"); if( $ress ){ foreach( $ress as $item ){ if( ! preg_match( '~[^/]+$~', $item->meta_value, $m ) ) continue; $_fname = $m[0]; $_pre = str_replace( $_fname, '', $item->meta_value ); $_fname = sanitize_file_name( $_fname ); $new_guid = $_pre . $_fname; if( $item->meta_value != $new_guid ){ $done = $wpdb->query( $wpdb->prepare("UPDATE $wpdb->postmeta SET meta_value = %s WHERE meta_id = %d", $new_guid, $item->meta_id ) ); echo ($done ? "OK - $item->meta_value >>> $new_guid" : "ERROR - $item->meta_value") ."<br>\n"; } } } // поправим данные в метаданных // _wp_attachment_metadata // для этого лучше использовать плагин Forse Regenerate Thumbnails } /** * ЧАСТЬ 4: транслитерация URL картинок из папки /uploads/ в контенте записи */ if( isset($_GET['sanitize_filename_in_post_content']) ){ sanitize_filename_in_post_content(); die('КОНЕЦ'); } function sanitize_filename_in_post_content(){ global $wpdb; $ress = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE post_status = 'publish' AND post_content LIKE '%/uploads/%'"); $out = ''; foreach( $ress as $post ){ $_out = array(); $_out[] = $post->post_title . ' - '. get_permalink($post->ID) ."\n\n"; preg_match_all('~/uploads/[^"\']+~', $post->post_content, $mm ); foreach( $mm as $arr ){ $echo_out = false; foreach( $arr as $url ){ preg_match( '~[^/]+$~', $url, $m ); $_fname = $m[0]; $_pre = str_replace( $_fname, '', $url ); $_fname = sanitize_file_name( $_fname ); $new_url = $_pre . $_fname; // заменяем if( $url != $new_url ){ $wpdb->query("UPDATE $wpdb->posts SET post_content = REPLACE(post_content, '$url', '$new_url') WHERE ID = $post->ID"); $echo_out = true; $_out[] = $new_url ."\n"; } } } echo $echo_out ? implode('',$_out)."\n\n" : ''; } } /** * ЧАСТЬ 5 (если надо): исправление размеров после регенерации миниатюр (forse-regenerate). * Некоторые файлы, например, имели размер 300-200 а стали 300-201 */ if( isset($_GET['fix_sizes_after_force_regenerate']) ){ fix_sizes_after_force_regenerate(); die('КОНЕЦ'); } function fix_sizes_after_force_regenerate(){ global $wpdb; $upload_dir_path = wp_upload_dir()['basedir']; $ress = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE post_status = 'publish' AND post_content LIKE '%/uploads/%'"); $out = ''; $i=1; foreach( $ress as $post ){ $_out = array(); $_out[] = $post->post_title . ' - '. get_permalink($post->ID) ."\n\n"; preg_match_all('~/uploads/[^"\']+~', $post->post_content, $mm ); foreach( $mm as $arr ){ $echo_out = false; foreach( $arr as $url ){ $fpath = $upload_dir_path . str_replace('/uploads','',$url); if( ! file_exists($fpath) ){ //$echo_out = true; //$_out[] = $i++ .' - '. $fpath ."\n"; // получим все имеющиеся размеры файла $fpath_patt = preg_replace('~-[0-9]+x[0-9]+(?=\.jpg|\.jpeg|\.png|\.gif)~', '*', $fpath ); //echo $fpath_patt; //print_r( glob( $fpath_patt ) ); // удалим неподходящие размеры и получим нужный, он там один $new_fpath = ''; foreach( glob( $fpath_patt ) as $pth ){ if( preg_match('~80x80~',$pth) ) continue; if( ! preg_match('~-[0-9]+x[0-9]+\.(jpg|jpeg|png|gif)~',$pth) ) continue; $new_fpath = $pth; // удалим лишнюю начальную часть и заменяем все в контенте $old_url = preg_replace('~^.*?/uploads/~','/uploads/', $fpath); $new_url = preg_replace('~^.*?/uploads/~','/uploads/', $new_fpath); $echo_out = $wpdb->query("UPDATE $wpdb->posts SET post_content = REPLACE(post_content, '$old_url', '$new_url') WHERE ID = $post->ID"); //$echo_out = true; $_out[] = $old_url . ' - '. $new_url ."\n"; } } } } echo $echo_out ? implode('',$_out)."\n\n" : ''; } }