PluginProbe ʕ •ᴥ•ʔ
Import from YML / 4.6.0
Import from YML v4.6.0
trunk 1.0.0 2.0.0 2.2.2 3.0.0 3.0.1 3.1.0 3.1.1 3.1.10 3.1.11 3.1.12 3.1.13 3.1.14 3.1.15 3.1.16 3.1.17 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.2.0 4.3.0 4.4.0 4.5.0 4.6.0 4.6.1 4.6.2 4.6.3
import-from-yml / functions.php
import-from-yml Last commit date
admin 3 months ago includes 3 months ago languages 3 months ago public 3 months ago LICENSE.txt 3 months ago functions.php 3 months ago import-from-yml.php 3 months ago index.php 3 months ago readme.txt 3 months ago sandbox.php 3 months ago screenshot-1.png 3 months ago screenshot-2.png 3 months ago uninstall.php 3 months ago
functions.php
752 lines
1 <?php
2 if ( ! function_exists( 'ipytw_get_html_options' ) ) {
3 /**
4 * Get `option` tags for HTML form.
5 *
6 * @since 4.0.0 (24-04-2025)
7 *
8 * @param string|array $opt_value option name
9 * @param array $params_arr example: `['key_value_arr'=>array, 'woo_attr'=>bool]`
10 * @param bool $multiple
11 *
12 * @return string
13 */
14 function ipytw_get_html_options( $opt_value, $params_arr = [], $multiple = false ) {
15
16 $result = '';
17
18 // ключ-значение из настроек плагина
19 if ( ! empty( $params_arr['key_value_arr'] ) ) {
20 for ( $i = 0; $i < count( $params_arr['key_value_arr'] ); $i++ ) {
21 if ( true === $multiple && is_array( $opt_value ) ) {
22 // массивы �
23 ранятся в отдельны�
24 опция�
25 и выводятся тоже иначе
26 $selected = '';
27 for ( $y = 0; $y < count( $opt_value ); $y++ ) {
28 if ( $opt_value[ $y ] == $params_arr['key_value_arr'][ $i ]['value'] ) {
29 $selected = 'selected';
30 break;
31 }
32 }
33 } else {
34 $selected = selected( $opt_value, $params_arr['key_value_arr'][ $i ]['value'], false );
35 }
36 $result .= sprintf( '<option value="%1$s" %2$s>%3$s</option>',
37 esc_attr( $params_arr['key_value_arr'][ $i ]['value'] ),
38 esc_attr( $selected ),
39 esc_attr( $params_arr['key_value_arr'][ $i ]['text'] ),
40 PHP_EOL
41 );
42 }
43 }
44
45 // ? поддерживаемые плагины
46 // for ( $i = 0; $i < count( self::SUPPORTED_PLUGINS_ARR ); $i++ ) {
47 // if ( is_plugin_active( self::SUPPORTED_PLUGINS_ARR[ $i ]['plugins'] ) ) {
48 // $result .= sprintf( '<option value="%1$s" %2$s>%3$s</option>%4$s',
49 // esc_attr( self::SUPPORTED_PLUGINS_ARR[ $i ]['plugins'] ),
50 // selected( $opt_value, self::SUPPORTED_PLUGINS_ARR[ $i ]['value'], false ),
51 // sprintf( '%s "%s"',
52 // __( 'Substitute from', 'import-from-yml' ),
53 // self::SUPPORTED_PLUGINS_ARR[ $i ]['text']
54 // ),
55 // PHP_EOL
56 // );
57 // }
58 // }
59
60 // атрибуты woocommerce
61 if ( true === $params_arr['woo_attr'] ) {
62 $woo_attributes_arr = get_woo_attributes();
63 if ( ! empty( $woo_attributes_arr ) ) {
64 for ( $i = 0; $i < count( $woo_attributes_arr ); $i++ ) {
65 if ( true === $multiple && is_array( $opt_value ) ) {
66 // массивы �
67 ранятся в отдельны�
68 опция�
69 и выводятся тоже иначе
70 $selected = '';
71 for ( $y = 0; $y < count( $opt_value ); $y++ ) {
72 if ( $opt_value[ $y ] == $woo_attributes_arr[ $i ]['id'] ) {
73 $selected = 'selected';
74 break;
75 }
76 }
77 } else {
78 $selected = selected( $opt_value, $woo_attributes_arr[ $i ]['id'], false );
79 }
80 $result .= sprintf( '<option value="%1$s" %2$s>%3$s</option>%4$s',
81 esc_attr( $woo_attributes_arr[ $i ]['id'] ),
82 esc_attr( $selected ),
83 esc_attr( $woo_attributes_arr[ $i ]['name'] ),
84 PHP_EOL
85 );
86 }
87 unset( $woo_attributes_arr );
88 }
89 }
90
91 // категории и теги
92 if ( isset( $params_arr['categories_arr'] ) && true === $params_arr['categories_arr'] ) {
93 // категории
94 $terms = get_terms( [ 'taxonomy' => [ 'product_cat' ], 'hide_empty' => 0, 'parent' => 0 ] );
95 if ( $terms && ! is_wp_error( $terms ) ) {
96 $result .= sprintf( '<optgroup label="%s">', __( 'Categories', 'import-from-yml' ) );
97 foreach ( $terms as $term ) {
98 $result .= the_cat_tree( $term->taxonomy, $term->term_id, $opt_value );
99 }
100 $result .= '</optgroup>';
101 }
102 }
103
104 if ( isset( $params_arr['tags_arr'] ) && true === $params_arr['tags_arr'] ) {
105 // теги
106 $terms = get_terms( [ 'taxonomy' => [ 'product_tag' ], 'hide_empty' => 0, 'parent' => 0 ] );
107 if ( $terms && ! is_wp_error( $terms ) ) {
108 $result .= sprintf( '<optgroup label="%s">', __( 'Tags', 'import-from-yml' ) );
109 foreach ( $terms as $term ) {
110 $result .= the_cat_tree( $term->taxonomy, $term->term_id, $opt_value );
111 }
112 $result .= '</optgroup>';
113 }
114 }
115
116 return $result;
117
118 }
119 }
120
121 // select2 - place 5 from 5 (with woocommerce serch)
122 if ( ! function_exists( 'ipytw_get_html_options_for_select2' ) ) {
123 /**
124 * @since 1.0.4
125 * @see https://rudrastyh.com/wordpress/select2-for-metaboxes-with-ajax.html
126 *
127 * @param array $opt_value_arr Selected Posts IDs
128 * @dependence lib select2, select2.js, https://github.com/woocommerce/selectWoo
129 *
130 * @return string of multiselect options tags with ajax
131 */
132 function ipytw_get_html_options_for_select2( $opt_value_arr ) {
133
134 $result = '';
135 // always array because we have added [] to our <select> name attribute
136 if ( $opt_value_arr ) {
137 foreach ( $opt_value_arr as $post_id ) {
138 $title = get_the_title( $post_id );
139 // if the post title is too long, truncate it and add "..." at the end
140 $title = ( mb_strlen( $title ) > 50 ) ? mb_substr( $title, 0, 49 ) . '...' : $title;
141 $result .= '<option value="' . $post_id . '" selected="selected">' . $title . '</option>';
142 }
143 }
144 return $result;
145
146 }
147 }
148
149 if ( ! function_exists( 'ipytw_get_dir_files' ) ) {
150 /**
151 * Получает пути все�
152 файлов и папок в указанной папке.
153 *
154 * @param string $dir Путь до папки (на конце со слэшем или без).
155 * @param bool $recursive Включить вложенные папки или нет?
156 * @param bool $include_folders Включить ли в список пути на папки?
157 *
158 * @return array Вернет массив путей до файлов/папок.
159 */
160 function ipytw_get_dir_files( $dir, $recursive = true, $include_folders = false ) {
161
162 if ( ! is_dir( $dir ) )
163 return [];
164
165 $files = [];
166
167 $dir = rtrim( $dir, '/\\' ); // удалим слэш на конце
168
169 foreach ( glob( "$dir/{,.}[!.,!..]*", GLOB_BRACE ) as $file ) {
170
171 if ( is_dir( $file ) ) {
172 if ( $include_folders )
173 $files[] = $file;
174 if ( $recursive )
175 $files = array_merge( $files, call_user_func( __FUNCTION__, $file, $recursive, $include_folders ) );
176 } else
177 $files[] = $file;
178 }
179
180 return $files;
181
182 // $files = ipytw_get_dir_files( plugin_dir_path( dirname( __FILE__ ) ) . 'includes/feeds/' );
183 // for ( $i = 0; $i < count( $files ); $i++ ) {
184 // $ext = pathinfo( $files[ $i ], PATHINFO_EXTENSION );
185 // if ( $ext === 'php' ) {
186 // require_once $files[ $i ];
187 // }
188 // }
189
190 }
191 }
192
193 if ( ! function_exists( 'ipytw_strip_tags' ) ) {
194 /**
195 * Wrapper for the `strip_tags` function.
196 *
197 * @since 4.4.1
198 *
199 * @param mixed $tag_value
200 * @param string $enable_tags Example: `<p><a>`
201 *
202 * @return string
203 */
204 function ipytw_strip_tags( $tag_value, $enable_tags = '' ) {
205
206 if ( null === $tag_value || $tag_value === '' ) {
207 return (string) $tag_value;
208 }
209 $tag_value = strip_tags( $tag_value, $enable_tags );
210 return $tag_value;
211
212 }
213 }
214
215 if ( ! function_exists( 'get_nested_tag' ) ) {
216 /**
217 *
218 * Splits the tag value into nested parts using the ` | ` separator.
219 *
220 * @since 4.7.2
221 *
222 * @param string $name_wrapper_tag
223 * @param string $name_nested_tag
224 * @param string $tag_value
225 * @param string $result_xml
226 *
227 * @return string
228 */
229 function get_nested_tag( $name_wrapper_tag, $name_nested_tag, $tag_value, $result_xml = '' ) {
230
231 $elements = explode( "|", $tag_value );
232 if ( count( $elements ) > 1 ) {
233 $result_xml .= new IPYTW_Get_Open_Tag( $name_wrapper_tag );
234 foreach ( $elements as $element ) {
235 $result_xml .= new IPYTW_Get_Paired_Tag( $name_nested_tag, $element );
236 }
237 $result_xml .= new IPYTW_Get_Closed_Tag( $name_wrapper_tag );
238 } else if ( count( $elements ) === (int) 1 ) {
239 $result_xml .= new IPYTW_Get_Paired_Tag( $name_wrapper_tag, $elements[0] );
240 }
241 return $result_xml;
242
243 }
244 }
245
246 if ( ! function_exists( 'ipytw_replace_decode' ) ) {
247 /**
248 * @since 3.3.16
249 *
250 * @return string
251 */
252 function ipytw_replace_decode( $string, $feed_id = '1' ) {
253
254 $string = str_replace( "+", 'ipytw', $string );
255 $string = urldecode( $string );
256 $string = str_replace( "ipytw", '+', $string );
257 $string = apply_filters( 'ipytw_replace_decode_filter', $string, $feed_id );
258 return $string;
259
260 }
261 }
262
263 if ( ! function_exists( 'ipytw_remove_special_characters' ) ) {
264 /**
265 * Remove hex and control characters from PHP string.
266 *
267 * @since 4.0.0 (24-04-2025)
268 *
269 * @param string $result_xml
270 *
271 * @return string
272 */
273 function ipytw_remove_special_characters( $result_xml ) {
274
275 if ( ! empty( $result_xml ) ) {
276 $result_xml = str_replace( PHP_EOL, '\n', $result_xml );
277 $result_xml = preg_replace( '/0x[0-9a-fA-F]{6}/', '', $result_xml );
278 $result_xml = preg_replace( '/[\x00-\x1F\x7F]/', '', $result_xml );
279 $result_xml = str_replace( '\n', PHP_EOL, $result_xml );
280 }
281 return $result_xml;
282
283 }
284 }
285
286 /**
287 * Вместо file_get_contents используем curl.
288 *
289 * @since 1.3.0
290 *
291 * @param string $url
292 * @param string $feed_id
293 */
294 function ipytw_file_get_contents_curl( $url, $feed_id ) {
295
296 $ch = curl_init(); // Инициализируем curl
297
298 if ( $feed_id !== false ) {
299 $ipytw_feed_login = common_option_get(
300 'ipytw_feed_login',
301 '',
302 $feed_id,
303 'ipytw'
304 );
305
306 $ipytw_feed_pwd = common_option_get(
307 'ipytw_feed_pwd',
308 '',
309 $feed_id,
310 'ipytw'
311 );
312 if ( ! empty( $ipytw_feed_login ) && ! empty( $ipytw_feed_pwd ) ) {
313 $userpwd = $ipytw_feed_login . ':' . $ipytw_feed_pwd; // 'логин:пароль'
314 curl_setopt( $ch, CURLOPT_USERPWD, $userpwd );
315 }
316 }
317
318 curl_setopt( $ch, CURLOPT_URL, $url ); // Указываем ссылку
319 curl_setopt( $ch, CURLOPT_AUTOREFERER, TRUE ); // подставляем Referer при перенаправлении
320 curl_setopt( $ch, CURLOPT_HEADER, 0 ); // Не выводим заголовки
321 curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 ); // Со�
322 раним полученный результат в переменную
323 curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, TRUE ); // Идем по перенаправлению
324 curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); // Не проверяем SSL сертификат
325 // Установим Useragent
326 curl_setopt( $ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0' );
327
328 $get_data = curl_exec( $ch ); // Выполняем запрос на сайт
329
330 // Обработка результата выполнения запроса
331 if ( ! $get_data ) {
332 return false;
333 } else {
334 $http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
335 if ( $http_code !== 200 ) {
336 return false;
337 }
338 }
339 curl_close( $ch ); // Закрываем curl
340
341 return $get_data; // Возвращаем из функции полученные данные
342
343 }
344
345 /**
346 * Отправка запросов курлом.
347 *
348 * @version 2.1.4
349 * @see https://snipp.ru/php/curl
350 *
351 * @param string $request_url - Rrequired
352 * @param mixed $feed_id - Optional
353 * @param array $postfields_arr - Optional
354 * @param array $headers_arr - Optional
355 * @param string $request_type - Optional
356 * @param array $pwd_arr - Optional
357 * @param string $encode_type - Optional
358 * @param int $timeout - Optional
359 * @param string $proxy - Optional // example: '165.22.115.179:8080'
360 * @param bool $debug - Optional
361 * @param string $sep - Optional
362 * @param string $useragent - Optional
363 *
364 * @return array keys: errors, status, http_code, body, header_request, header_answer
365 *
366 */
367 function ipytw_curl( $request_url,
368 $feed_id = false,
369 $postfields_arr = [],
370 $headers_arr = [],
371 $request_type = 'GET',
372 $pwd_arr = [],
373 $encode_type = 'json_encode',
374 $timeout = 30,
375 $proxy = '',
376 $debug = false,
377 $sep = PHP_EOL,
378 $useragent = 'PHP Bot'
379 ) {
380
381 $curl = curl_init(); // инициализация cURL
382
383 if ( $feed_id !== false ) {
384 $ipytw_feed_login = common_option_get(
385 'ipytw_feed_login',
386 '',
387 $feed_id,
388 'ipytw'
389 );
390
391 $ipytw_feed_pwd = common_option_get(
392 'ipytw_feed_pwd',
393 '',
394 $feed_id,
395 'ipytw'
396 );
397 if ( ! empty( $ipytw_feed_login ) && ! empty( $ipytw_feed_pwd ) ) {
398 $userpwd = $ipytw_feed_login . ':' . $ipytw_feed_pwd; // 'логин:пароль'
399 curl_setopt( $curl, CURLOPT_USERPWD, $userpwd );
400 }
401 }
402
403 if ( ! empty( $pwd_arr ) ) {
404 if ( isset( $pwd_arr['login'] ) && isset( $pwd_arr['pwd'] ) ) {
405 $userpwd = $pwd_arr['login'] . ':' . $pwd_arr['pwd']; // 'логин:пароль'
406 curl_setopt( $curl, CURLOPT_USERPWD, $userpwd );
407 }
408 }
409
410 curl_setopt( $curl, CURLOPT_URL, $request_url );
411 curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, false ); // проверять ли подлинность присланного сертификата сервера
412
413 // задает проверку имени, указанного в сертификате удаленного сервера, при установлении SSL соединения.
414 // Значение 0 - без проверки,
415 // значение 1 означает проверку существования имени,
416 // значение 2 - кроме того, и проверку соответствия имени �
417 оста. Рекомендуется 2.
418 curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, 0 );
419 curl_setopt( $curl, CURLOPT_USERAGENT, $useragent );
420 // количество секунд ожидания при попытке соединения. Используйте 0 для бесконечного ожидания
421 curl_setopt( $curl, CURLOPT_CONNECTTIMEOUT, $timeout );
422
423 curl_setopt( $curl, CURLOPT_HTTPHEADER, $headers_arr );
424
425 $answer_arr = [];
426 $answer_arr['body_request'] = null;
427 if ( $request_type !== 'GET' ) {
428 switch ( $encode_type ) {
429 case 'json_encode':
430 $answer_arr['body_request'] = json_encode( $postfields_arr );
431 break;
432 case 'http_build_query':
433 $answer_arr['body_request'] = http_build_query( $postfields_arr );
434 break;
435 case 'dont_encode':
436 $answer_arr['body_request'] = $postfields_arr;
437 break;
438 default:
439 $answer_arr['body_request'] = json_encode( $postfields_arr );
440 }
441 }
442
443 if ( $request_type === 'POST' ) { // отправляется POST запрос
444 curl_setopt( $curl, CURLOPT_POST, true );
445 curl_setopt( $curl, CURLOPT_POSTFIELDS, $answer_arr['body_request'] );
446 // $postfields_arr - массив с передаваемыми параметрами POST
447 }
448
449 if ( $request_type === 'DELETE' ) { // отправляется DELETE запрос
450 curl_setopt( $curl, CURLOPT_CUSTOMREQUEST, 'DELETE' );
451 curl_setopt( $curl, CURLOPT_POSTFIELDS, $answer_arr['body_request'] );
452 }
453
454 if ( $request_type === 'PUT' ) { // отправляется PUT запрос
455 curl_setopt( $curl, CURLOPT_CUSTOMREQUEST, 'PUT' );
456 curl_setopt( $curl, CURLOPT_POSTFIELDS, $answer_arr['body_request'] );
457 // http_build_query($postfields_arr, '', '&') // $postfields_arr - массив с передаваемыми параметрами POST
458 }
459
460 if ( ! empty( $proxy ) ) {
461 curl_setopt( $curl, CURLOPT_TIMEOUT, 400 ); // зададим максимальное кол-во секунд для выполнения cURL-функций
462 curl_setopt( $curl, CURLOPT_PROXY, $proxy ); // HTTP-прокси, через который будут направляться запросы
463 }
464
465 curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true ); // вернуть результат запроса, а не выводить в браузер
466 curl_setopt( $curl, CURLOPT_HEADER, true ); // опция позволяет включать в ответ от сервера его HTTP - заголовки
467 curl_setopt( $curl, CURLINFO_HEADER_OUT, true ); // true - для отслеживания строки запроса дескриптора
468
469 $result = curl_exec( $curl ); // выполняем cURL
470
471 // Обработка результата выполнения запроса
472 if ( ! $result ) {
473 $answer_arr['errors'] = 'Ошибка cURL: ' . curl_errno( $curl ) . ' - ' . curl_error( $curl );
474 $answer_arr['body_answer'] = null;
475 } else {
476 $answer_arr['status'] = true; // true - получили ответ
477 // Разделение полученны�
478 HTTP-заголовков и тела ответа
479 $response_headers_size = curl_getinfo( $curl, CURLINFO_HEADER_SIZE );
480 $response_headers = substr( $result, 0, $response_headers_size );
481 $response_body = substr( $result, $response_headers_size );
482 $http_code = curl_getinfo( $curl, CURLINFO_HTTP_CODE );
483 $answer_arr['http_code'] = $http_code;
484
485 if ( $http_code == 200 ) {
486 // Если HTTP-код ответа равен 200, то возвращаем отформатированное тело ответа в формате JSON
487 $decoded_body = json_decode( $response_body );
488 $answer_arr['body_answer'] = $decoded_body;
489 } else {
490 // Если тело ответа не пустое, то производится попытка декодирования JSON-кода
491 if ( ! empty( $response_body ) ) {
492 $decoded_body = json_decode( $response_body );
493 if ( $decoded_body != null ) {
494 // Если ответ содержит тело в формате JSON,
495 // то возвращаем отформатированное тело в формате JSON
496 $answer_arr['body_answer'] = $decoded_body;
497 } else {
498 // Если не удалось декодировать JSON либо тело имеет другой формат,
499 // то возвращаем преобразованное тело ответа
500 $answer_arr['body_answer'] = htmlspecialchars( $response_body );
501 }
502 } else {
503 $answer_arr['body_answer'] = null;
504 }
505 }
506 // Вывод необработанны�
507 HTTP-заголовков запроса и ответа
508 $answer_arr['header_request'] = curl_getinfo( $curl, CURLINFO_HEADER_OUT ); // Заголовки запроса
509 $answer_arr['header_answer'] = $response_headers; // Заголовки ответа
510 }
511
512 curl_close( $curl );
513 return $answer_arr;
514
515 }
516
517 /**
518 * Проверяет, есть ли товар с таким SKU.
519 *
520 * @since 1.2.2
521 * @see https://woocommerce.github.io/code-reference/files/woocommerce-includes-wc-product-functions.html
522 *
523 * @param string $sku
524 *
525 * @return bool
526 */
527 function ipytw_is_uniq_sku( $sku ) {
528
529 if ( false === $sku || $sku === '' ) {
530 return false;
531 }
532 if ( wc_get_product_id_by_sku( $sku ) > 0 ) {
533 return true;
534 } else {
535 return false;
536 }
537
538 }
539
540 /**
541 * Проверяет, син�
542 ронили ли мы товар/картинку.
543 *
544 * @since 1.0.0
545 *
546 * @param string $meta_value
547 * @param int $feed_id
548 * @param string $meta_key
549 * @param string $post_type Maybe: `product`, `product_variation`, `attachment`
550 * @param bool $product_sku
551 *
552 * @return int|false `int` - ID товара/картинки на нашем сайте или `false` - если син�
553 ронизация не делалась
554 */
555 function ipytw_check_sync( $meta_value, $feed_id, $post_type = 'attachment', $meta_key = '_ipytw_import_feed_picture_url', $product_sku = false ) {
556
557 switch ( $post_type ) {
558 case 'product':
559
560 $meta_key = '_ipytw_feed_product_id';
561 $args = [
562 'post_type' => $post_type,
563 'post_status' => [ 'publish', 'pending', 'draft', 'future', 'trash' ],
564 'fields' => 'ids',
565 'relation' => 'AND',
566 'meta_query' => [
567 'relation' => 'AND',
568 [
569 'key' => $meta_key,
570 'value' => $meta_value
571 ],
572 [
573 'key' => '_ipytw_feed_id',
574 'value' => $feed_id
575 ]
576 ]
577 ];
578
579 break;
580 case 'product_variation':
581
582 $meta_key = '_ipytw_feed_var_id';
583 $args = [
584 'post_type' => $post_type,
585 'post_status' => [ 'publish', 'pending', 'draft', 'future', 'trash' ],
586 'fields' => 'ids',
587 'relation' => 'AND',
588 'meta_query' => [
589 'relation' => 'AND',
590 [
591 'key' => $meta_key,
592 'value' => $meta_value
593 ],
594 [
595 'key' => '_ipytw_feed_id',
596 'value' => $feed_id
597 ]
598 ]
599 ];
600
601 break;
602 case 'attachment':
603 default:
604
605 $args = [
606 'post_type' => $post_type,
607 'fields' => 'ids',
608 'relation' => 'AND',
609 'meta_query' => [
610 [
611 'key' => $meta_key,
612 'value' => $meta_value
613 ]
614 ]
615 ];
616
617 }
618
619 if ( $ids = get_posts( $args ) ) {
620 $id_on_our_site = array_pop( $ids );
621 $checking_photos = common_option_get(
622 'ipytw_checking_photos',
623 'enabled',
624 $feed_id,
625 'ipytw'
626 );
627 if ( 'enabled' === $checking_photos ) {
628 // если включена проверка фото после загрузки на наш сервер на наличие и размер
629 $pic_url = wp_get_attachment_url( $id_on_our_site );
630 if ( $post_type === 'attachment' ) {
631 $local_file_path = get_attached_file( $id_on_our_site );
632
633 if ( file_exists( $local_file_path ) ) {
634 // Файл локальный — проверяем его размер напрямую
635 $file_size = filesize( $local_file_path );
636 if ( false === $file_size || $file_size <= 0 ) {
637 // Удаляем вложение с нашего сервера, если файл повреждён или пуст
638 wp_delete_attachment( $id_on_our_site, true );
639 $result = false;
640 } else {
641 $result = $id_on_our_site;
642 }
643 } else {
644 // Файл не найден локально — проверяем через get_remote_fsize
645 $result_remote_fsize = IPYTW_Download_Pictures::get_remote_fsize( $pic_url, 2, $feed_id, 'ipytw_check_sync' );
646 if ( 0 == $result_remote_fsize || -1 == $result_remote_fsize ) {
647 wp_delete_attachment( $id_on_our_site, true );
648 $result = false;
649 } else {
650 $result = $id_on_our_site;
651 }
652 }
653 } else {
654 $result = $id_on_our_site;
655 }
656 } else {
657 $result = $id_on_our_site;
658 }
659 } else {
660 $result = false;
661 }
662
663 return $result;
664
665 }
666
667 /**
668 * Удаление все�
669 постов.
670 *
671 * @since 1.9.3
672 *
673 * @param string $feed_id
674 *
675 * @return bool
676 */
677 function ipytw_delete_all_imported_products( $feed_id ) {
678
679 $args = [
680 'post_type' => 'product',
681 'post_status' => [ 'publish', 'pending', 'draft', 'future' ],
682 'posts_per_page' => -1,
683 'relation' => 'AND',
684 'fields' => 'ids',
685 'meta_query' => [
686 [
687 'key' => '_ipytw_feed_id',
688 'value' => (string) $feed_id
689 ]
690 ]
691 ];
692
693 $query = new \WP_Query( $args );
694 $old_ids_arr = [];
695 if ( $query->have_posts() ) {
696 $old_ids_arr = $query->posts; // id товаров, которые импортированы
697 } else {
698 return false;
699 }
700 foreach ( $old_ids_arr as $id ) {
701 wooс_delete_product( $id );
702 }
703 return true;
704
705 }
706
707 /**
708 * Remove non-empty directories.
709 *
710 * @since 4.0.4 (05-10-2025)
711 *
712 * @param string $path
713 *
714 * @return bool
715 */
716 function ipytw_remove_directory( $path ) {
717
718 global $wp_filesystem;
719
720 // Подключаем необ�
721 одимые файлы
722 require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
723
724 // Инициализация файловой системы
725 if ( ! is_object( $wp_filesystem ) ) {
726 WP_Filesystem();
727 }
728
729 try {
730 // Проверяем существование каталога
731 if ( $wp_filesystem->exists( $path ) ) {
732 // Удаляем каталог рекурсивно
733 $result = $wp_filesystem->delete( $path, true );
734
735 if ( false === $result ) {
736 throw new Exception(
737 __( 'Error when deleting a folder', 'import-from-yml' )
738 );
739 }
740
741 return true;
742 } else {
743 throw new Exception( __( 'The folder does not exist', 'import-from-yml' ) );
744 }
745 } catch (Exception $e) {
746 error_log(
747 __( 'Error when deleting a folder', 'import-from-yml' ) . $e->getMessage()
748 );
749 return false;
750 }
751
752 }