Вопрос или проблема
Я выполняю миграцию с сайта на wordpress/woocommerce, я успешно экспортировал/импортировал все данные, кроме одного:
файлы с вложениями для загрузки из моего продукта woocommerce.
Я использую wp-cli, это работает нормально для обычных медиафайлов (все мои страницы и статьи блога имеют свои медиафайлы), но все мои файлы woocommerce загружаются в папку wp-content/uploads/year/month вместо: /wp-content/uploads/woocommerce_uploads/year/month.
Я посмотрел в XML, путь верный.
Кто-нибудь знает, как wordpress решает, в какую директорию он помещает файлы во время импорта?
Как мне загрузить мой файл с продуктом для загрузки woocommerce в нужную директорию?
Изменение: экспорт из wp 4.8.6 и wc 3.2.1,
импорт в wp 4.9.5 и wc 3.3.4.
Вот решение, которое я нашел:
в функции process_posts плагина wordpress-importer:
// пытаемся использовать _wp_attached_file для размещения файловой папки, чтобы гарантировать такое же местоположение, как на экспортируемом сайте
// например, местоположение 2003/05/image.jpg, но дата поста вложения 2010/09, см. media_handle_upload()
$postdata['upload_date'] = $post['post_date'];
if ( isset( $post['postmeta'] ) ) {
foreach( $post['postmeta'] as $meta ) {
if ( $meta['key'] == '_wp_attached_file' ) {
if ( preg_match( '%^[0-9]{4}/[0-9]{2}%', $meta['value'], $matches) )
{
$postdata['upload_date'] = $matches[0];
$postdata['woocommerce'] = false;
}
else if ( preg_match( '%^(woocommerce_uploads)/([0-9]{4}/[0-9]{2})%', $meta['value'], $matches ) ) {
$postdata['upload_date'] = $matches[2];
$postdata['woocommerce'] = true;
}
break;
}
}
}
(это часть, где wordpress пытается получить дату загрузки, используя имя директории – с структурой woocommerce_uploads это не сработает)
в функции fetch_remote_file плагина wordpress-importer:
function fetch_remote_file( $url, $post ) {
// извлекаем имя файла и расширение из url
$file_name = basename( $url );
global $wp_filter;
if ( isset($wp_filter['pre_option_upload_path']) ) {
remove_filter( 'pre_option_upload_path', 'woocommerce_path_upload' );
}
if ( $post['woocommerce'] == true ) {
add_filter( 'pre_option_upload_path', 'woocommerce_path_upload' );
}
$upload = wp_upload_bits( $file_name, 0, '', $post['upload_date'] );
(это часть перед загрузкой файла, где мы добавляем путь перед путем загрузки, если это файл woocommerce)
function woocommerce_path_upload () { return 'wp-content/uploads/woocommerce_uploads'; }
(функция используется в фильтре для корректировки пути)
И наконец, в ядре wordpress wp-includes/functions.php установите $refresh_cache в true (по умолчанию false):
function wp_upload_dir( $time = null, $create_dir = true, $refresh_cache = true ) {
(если вы не измените это, wordpress сохранит путь загрузки в кэше и не будет проверять его для каждого файла; в нашей ситуации нам нужно проверять это каждый раз)
Обратите внимание, что это изменение вы делаете только во время миграции, после этого верните назад.
Ответ или решение
Краткий обзор проблемы
При миграции сайта с использованием WordPress и WooCommerce вы успешно экспортировали и импортировали данные, за исключением вложенных файлов для загружаемых товаров. Эти файлы сохраняются в папке wp-content/uploads/woocommerce_uploads/year/month, однако после импорта они оказались в стандартной папке wp-content/uploads/year/month. Эта проблема вызвана тем, как WordPress обрабатывает пути к загружаемым файлам во время импорта.
Решение
Чтобы правильно импортировать загружаемые вложения WooCommerce в правильную директорию, вам потребуется внести некоторые изменения в код плагина импорта WordPress, чтобы корректно обрабатывать пути загрузки.
Изменение в плагине импорта WordPress
-
Модификация функции
process_posts
:
В этой функции вам нужно убедиться, что WordPress правильно определяет путь загрузки файла, основываясь на его метаданных. В частности, у вас есть код, который проверяет, начинается ли путь к файлу сwoocommerce_uploads
, чтобы выставить соответствующий путь для загрузки.Пример изменения:
// Добавить логику, позволящую обрабатывать пути к загружаемым файлам foreach( $post['postmeta'] as $meta ) { if ( $meta['key'] == '_wp_attached_file' ) { if ( preg_match( '%^(woocommerce_uploads)/([0-9]{4}/[0-9]{2})%', $meta['value'], $matches ) ) { $postdata['upload_date'] = $matches[2]; $postdata['woocommerce'] = true; } break; } }
-
Модификация функции
fetch_remote_file
:
Здесь вы добавите фильтр, чтобы указать правильный путь для загрузок файлов WooCommerce. Это гарантирует, что файлы загружаются в указанную директорию.Пример изменения:
if ( $post['woocommerce'] == true ) { add_filter( 'pre_option_upload_path', 'woocommerce_path_upload' ); }
-
Создание функции
woocommerce_path_upload
:
Эта функция вернет путь к директории для загрузок WooCommerce.Пример функции:
function woocommerce_path_upload() { return 'wp-content/uploads/woocommerce_uploads'; }
-
Обновление функции
wp_upload_dir
:
По умолчанию WordPress кэширует путь для загрузки. Чтобы избежать проблем с кэшированием, необходимо установить параметр$refresh_cache
вtrue
.Пример изменения:
function wp_upload_dir( $time = null, $create_dir = true, $refresh_cache = true ) { // Логика получения путей к директории для загрузок }
Важные замечания
- Все изменения рекомендуется вносить только на время миграции, после чего стоит вернуть первоначальные значения функций, чтобы избежать нежелательных последствий в будущем.
- Перед внесением изменений обязательно создайте резервную копию вашего сайта.
Заключение
Следуя приведенным шагам, вы сможете корректно импортировать загружаемые вложения WooCommerce в нужную директорию. Эти оптимизации помогут в упрощении управления содержимым вашего сайта и гарантируют, что все товары будут правильно настроены при их отображении на новом сайте.