В последнее время, частенько попадаются импорты с битыми ссылками на картинки, например есть 5 картинок, а из них 3 битые и не грузятся.
Картинки - это самый медленный элемент импорта. Процесс больно замороченный. Сначала грузится картинка по линку во временные файлы, потом сделать массу проверок на тип и тд. Потом загрузить в медиабиблиотеку, проверить на дубликаты, и в финале еще миниатюр нарезать.
В общем, очень долго.
А если еще и ссылки битые, то время импорта увеличивается на порядки. Примерно замерял: 50 товаров с нормальными ссылками заезжает за 1 минуту, те же товары с битыми уже 40 минут...
Какое решение? Первое что приходит в голову - как то отсортировать передаваемые ссылки перед загрузкой. Но фиг там. Ожидаемо от WPAI, никаких фильтров не нашел. Хотя может и плохо искал. Но что то делать надо.
Нет фильтров, будем фильтровать настройки. Написал функцию, которая фильтрует передаваемую строку с линками
/**
* Удаление битых ссылок на изображения.
*
* @param string $url_option
*
* @return string
*/
function sanitize_images_url( string $url_option ): string {
if ( ! $url_option ) {
return '';
}
$urls = parse_strings( $url_option );
if ( empty( $urls ) ) {
return '';
}
$urls = array_unique( $urls );
$urls = array_filter($urls, function($url) {
return str_starts_with($url, 'http://') || str_starts_with($url, 'https://');
});
$valid_urls = [];
foreach ( $urls as $url ) {
if ( ! check_url_fast( $url ) ) {
continue;
}
$valid_urls[] = $url;
}
return implode( ',', $valid_urls );
}
/**
* Парсинг строки с разделителями
*
* @param $string
*
* @return array
*/
function parse_strings( $string ): array {
if ( empty( $string ) ) {
return [];
}
if ( strpos( $string, ',' ) !== false ) {
$items = str_getcsv( $string, ',', '"' );
} else {
$items = explode( ' ', $string );
}
$items = array_filter( array_map( 'trim', $items ) );
return array_values( $items );
}
/**
* Проверка ссылки на доступность
*
* @param $url
*
* @return bool
*/
function check_url_fast( $url ): bool {
static $local_cache = [];
if ( isset( $local_cache[ $url ] ) ) {
return $local_cache[ $url ];
}
$response = wp_remote_head( $url, [
'timeout' => 1.5,
'sslverify' => false,
'headers' => [ 'Connection' => 'close' ],
] );
$is_ok = ! is_wp_error( $response )
&& wp_remote_retrieve_response_code( $response ) === 200;
$local_cache[ $url ] = $is_ok;
return $is_ok;
}
Используем в поле, где указываются ссылки на картинки:
[sanitize_images_url( {images[1]}, {images-2[1]}, {images-3[1]})]или если ссылки собираются через XPath
[sanitize_images_url( {./*[starts-with(local-name(), 'picture')]} )]То есть на вход подаем строку ссылок через запятую, на выходе получаем такую же строку, но уже с рабочими ссылками.
Как то так. В комментариях пишем свои решения


