| @@ -337,9 +337,9 @@ | ||
| 337 | 337 | // own file when the extension pattern doesn't match (e.g. the attached file is |
| 338 | 338 | // already .webp/.avif and preg_replace returns the path unchanged). |
| 339 | 339 | $converted_path = preg_replace(self::ORIGINAL_EXT_PATTERN, $ext, $file); |
| 340 | 340 | if ($converted_path && $converted_path !== $file && file_exists($converted_path)) { |
| 341 | - @unlink($converted_path); | |
| 341 | + @wp_delete_file($converted_path); | |
| 342 | 342 | } |
| 343 | 343 | |
| 344 | 344 | // Delete converted sub-sizes |
| 345 | 345 | $metadata = wp_get_attachment_metadata($attachment_id); |
| @@ -348,9 +348,9 @@ | ||
| 348 | 348 | foreach ($metadata['sizes'] as $size_data) { |
| 349 | 349 | $size_path = $upload_dir . '/' . $size_data['file']; |
| 350 | 350 | $size_converted = preg_replace(self::ORIGINAL_EXT_PATTERN, $ext, $size_path); |
| 351 | 351 | if ($size_converted && $size_converted !== $size_path && file_exists($size_converted)) { |
| 352 | - @unlink($size_converted); | |
| 352 | + @wp_delete_file($size_converted); | |
| 353 | 353 | } |
| 354 | 354 | } |
| 355 | 355 | } |
| 356 | 356 | |
| @@ -409,9 +409,9 @@ | ||
| 409 | 409 | foreach ($paths as $path) { |
| 410 | 410 | foreach ($exts as $ext) { |
| 411 | 411 | $converted = preg_replace(self::ORIGINAL_EXT_PATTERN, $ext, $path); |
| 412 | 412 | if ($converted && $converted !== $path && file_exists($converted)) { |
| 413 | - @unlink($converted); | |
| 413 | + @wp_delete_file($converted); | |
| 414 | 414 | } |
| 415 | 415 | } |
| 416 | 416 | } |
| 417 | 417 | } |
| @@ -454,9 +454,9 @@ | ||
| 454 | 454 | * reset; false on hosts where set_time_limit() is disabled, in which |
| 455 | 455 | * case callers must rely on get_remaining_time() to bail out early. |
| 456 | 456 | */ |
| 457 | 457 | protected static function reset_time_limit(): bool { |
| 458 | - if (function_exists('set_time_limit') && @set_time_limit(self::UPLOAD_TIME_LIMIT)) { | |
| 458 | + if (function_exists('set_time_limit') && @set_time_limit(self::UPLOAD_TIME_LIMIT)) { // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- long-running batch job; WordPress has no equivalent API | |
| 459 | 459 | self::$timer_started_at = microtime(true); |
| 460 | 460 | return true; |
| 461 | 461 | } |
| 462 | 462 | return false; |
| @@ -520,9 +520,9 @@ | ||
| 520 | 520 | // Cap the total synchronous sub-size pass so the |
| 521 | 521 | // per-iteration timer resets below cannot keep one request busy |
| 522 | 522 | // indefinitely. |
| 523 | 523 | if ((microtime(true) - $pass_started) >= self::UPLOAD_TIME_LIMIT) { |
| 524 | - error_log('[MetaSync Media Opt] Sub-size time budget exceeded, skipping remaining sub-sizes from: ' . $size_name); | |
| 524 | + error_log('[MetaSync Media Opt] Sub-size time budget exceeded, skipping remaining sub-sizes from: ' . $size_name); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 525 | 525 | break; |
| 526 | 526 | } |
| 527 | 527 | |
| 528 | 528 | // Refresh the execution timer between encodes; when the host |
| @@ -528,9 +528,9 @@ | ||
| 528 | 528 | // Refresh the execution timer between encodes; when the host |
| 529 | 529 | // disables set_time_limit(), bail out before PHP's limit kills |
| 530 | 530 | // the request. |
| 531 | 531 | if (!static::reset_time_limit() && static::get_remaining_time() <= 0) { |
| 532 | - error_log('[MetaSync Media Opt] Execution time nearly exhausted, skipping remaining sub-sizes from: ' . $size_name); | |
| 532 | + error_log('[MetaSync Media Opt] Execution time nearly exhausted, skipping remaining sub-sizes from: ' . $size_name); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 533 | 533 | break; |
| 534 | 534 | } |
| 535 | 535 | |
| 536 | 536 | // Check available memory before each sub-size conversion |
| @@ -535,9 +535,9 @@ | ||
| 535 | 535 | |
| 536 | 536 | // Check available memory before each sub-size conversion |
| 537 | 537 | $available = static::get_available_memory(); |
| 538 | 538 | if ($available < self::MIN_MEMORY_FOR_SUBSIZE) { |
| 539 | - error_log('[MetaSync Media Opt] Low memory (' . size_format($available) . '), skipping remaining sub-sizes from: ' . $size_name); | |
| 539 | + error_log('[MetaSync Media Opt] Low memory (' . size_format($available) . '), skipping remaining sub-sizes from: ' . $size_name); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 540 | 540 | break; |
| 541 | 541 | } |
| 542 | 542 | |
| 543 | 543 | $size_file = $upload_dir . '/' . $size_data['file']; |
| @@ -558,13 +558,13 @@ | ||
| 558 | 558 | // widgets and hardcoded <img> tags point at sub-size URLs |
| 559 | 559 | // (photo-1024x768.jpg), and the original is unrecoverable |
| 560 | 560 | // once deleted. |
| 561 | 561 | self::rewrite_content_paths($size_file, $size_converted); |
| 562 | - @unlink($size_file); | |
| 562 | + @wp_delete_file($size_file); | |
| 563 | 563 | $size_data['file'] = basename($size_converted); |
| 564 | 564 | $size_data['mime-type'] = "image/{$format}"; |
| 565 | 565 | } elseif ($size_converted && $strategy === 'replace') { |
| 566 | - error_log('[MetaSync Media Opt] Sub-size conversion produced invalid output, original preserved: ' . self::redact_path($size_file)); | |
| 566 | + error_log('[MetaSync Media Opt] Sub-size conversion produced invalid output, original preserved: ' . self::redact_path($size_file)); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 567 | 567 | } |
| 568 | 568 | |
| 569 | 569 | // Release cyclic references between sub-size conversions |
| 570 | 570 | gc_collect_cycles(); |
| @@ -613,9 +613,9 @@ | ||
| 613 | 613 | return null; |
| 614 | 614 | } |
| 615 | 615 | |
| 616 | 616 | if (filesize($source) > self::MAX_CONVERT_BYTES) { |
| 617 | - error_log('[MetaSync Media Opt] Source file exceeds MAX_CONVERT_BYTES limit, skipping: ' . self::redact_path($source)); | |
| 617 | + error_log('[MetaSync Media Opt] Source file exceeds MAX_CONVERT_BYTES limit, skipping: ' . self::redact_path($source)); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 618 | 618 | return null; |
| 619 | 619 | } |
| 620 | 620 | |
| 621 | 621 | // Bail out instead of starting an encode PHP may kill mid-write |
| @@ -621,9 +621,9 @@ | ||
| 621 | 621 | // Bail out instead of starting an encode PHP may kill mid-write |
| 622 | 622 | // On hosts where set_time_limit() is disabled the request |
| 623 | 623 | // keeps its original cap, and the fatal reported by Sentry fired here. |
| 624 | 624 | if (static::get_remaining_time() <= 0) { |
| 625 | - error_log('[MetaSync Media Opt] Execution time nearly exhausted, skipping conversion: ' . basename($source)); | |
| 625 | + error_log('[MetaSync Media Opt] Execution time nearly exhausted, skipping conversion: ' . basename($source)); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 626 | 626 | return null; |
| 627 | 627 | } |
| 628 | 628 | |
| 629 | 629 | // Request WordPress's image processing memory limit |
| @@ -641,9 +641,9 @@ | ||
| 641 | 641 | $estimated = filesize($source) * 3; |
| 642 | 642 | } |
| 643 | 643 | $available = self::get_available_memory(); |
| 644 | 644 | if ($estimated > $available * 0.8) { |
| 645 | - error_log('[MetaSync Media Opt] Skipping ' . basename($source) . ': estimated memory (' . size_format($estimated) . ') exceeds 80% of available (' . size_format($available) . ')'); | |
| 645 | + error_log('[MetaSync Media Opt] Skipping ' . basename($source) . ': estimated memory (' . size_format($estimated) . ') exceeds 80% of available (' . size_format($available) . ')'); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 646 | 646 | return null; |
| 647 | 647 | } |
| 648 | 648 | |
| 649 | 649 | // Determine target dimensions when the source exceeds the configured cap. |
| @@ -661,9 +661,9 @@ | ||
| 661 | 661 | if ($result) { |
| 662 | 662 | return $result; |
| 663 | 663 | } |
| 664 | 664 | } catch (\Exception $e) { |
| 665 | - error_log('[MetaSync Media Opt] Imagick conversion failed, trying GD: ' . $e->getMessage()); | |
| 665 | + error_log('[MetaSync Media Opt] Imagick conversion failed, trying GD: ' . $e->getMessage()); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 666 | 666 | } |
| 667 | 667 | } |
| 668 | 668 | |
| 669 | 669 | if (extension_loaded('gd')) { |
| @@ -669,9 +669,9 @@ | ||
| 669 | 669 | if (extension_loaded('gd')) { |
| 670 | 670 | try { |
| 671 | 671 | return self::do_convert_with_gd($source, $dest, $format, $quality, $target_dimensions); |
| 672 | 672 | } catch (\Exception $e) { |
| 673 | - error_log('[MetaSync Media Opt] GD conversion failed: ' . $e->getMessage()); | |
| 673 | + error_log('[MetaSync Media Opt] GD conversion failed: ' . $e->getMessage()); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 674 | 674 | } |
| 675 | 675 | } |
| 676 | 676 | |
| 677 | 677 | return null; |
| @@ -694,10 +694,10 @@ | ||
| 694 | 694 | $img->stripImage(); |
| 695 | 695 | |
| 696 | 696 | if ($img->writeImage($dest)) { |
| 697 | 697 | if (!file_exists($dest) || !filesize($dest)) { |
| 698 | - @unlink($dest); | |
| 699 | - error_log('[MetaSync Media Opt] Imagick wrote 0-byte or missing output, discarding: ' . self::redact_path($dest)); | |
| 698 | + @wp_delete_file($dest); | |
| 699 | + error_log('[MetaSync Media Opt] Imagick wrote 0-byte or missing output, discarding: ' . self::redact_path($dest)); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 700 | 700 | $img->destroy(); |
| 701 | 701 | return null; |
| 702 | 702 | } |
| 703 | 703 | $img->destroy(); |
| @@ -763,10 +763,10 @@ | ||
| 763 | 763 | |
| 764 | 764 | imagedestroy($gd_img); |
| 765 | 765 | |
| 766 | 766 | if (!$success || !file_exists($dest) || !filesize($dest)) { |
| 767 | - @unlink($dest); | |
| 768 | - error_log('[MetaSync Media Opt] GD produced empty or missing output, discarding: ' . self::redact_path($dest)); | |
| 767 | + @wp_delete_file($dest); | |
| 768 | + error_log('[MetaSync Media Opt] GD produced empty or missing output, discarding: ' . self::redact_path($dest)); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 769 | 769 | return null; |
| 770 | 770 | } |
| 771 | 771 | |
| 772 | 772 | return $dest; |
| @@ -776,9 +776,9 @@ | ||
| 776 | 776 | * Replace original file with converted version. |
| 777 | 777 | */ |
| 778 | 778 | private static function do_replace_original(int $id, string $old_path, string $new_path, array &$meta, string $fmt): void { |
| 779 | 779 | if (!file_exists($new_path) || !filesize($new_path)) { |
| 780 | - error_log('[MetaSync Media Opt] Converted file is missing or empty, original preserved: ' . self::redact_path($old_path)); | |
| 780 | + error_log('[MetaSync Media Opt] Converted file is missing or empty, original preserved: ' . self::redact_path($old_path)); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 781 | 781 | return; |
| 782 | 782 | } |
| 783 | 783 | |
| 784 | 784 | // Update the DB pointers and rewrite post content FIRST — only once |
| @@ -806,9 +806,9 @@ | ||
| 806 | 806 | // Path-based, so it matches regardless of the hostname in the stored URL. |
| 807 | 807 | self::rewrite_content_paths($old_path, $new_path); |
| 808 | 808 | |
| 809 | 809 | // Content now points at the converted file — the original is redundant. |
| 810 | - @unlink($old_path); | |
| 810 | + @wp_delete_file($old_path); | |
| 811 | 811 | } |
| 812 | 812 | |
| 813 | 813 | /** |
| 814 | 814 | * Rewrite image references in all post content from one upload file to |
| @@ -884,9 +884,9 @@ | ||
| 884 | 884 | $like = '%' . $wpdb->esc_like($old_path) . '%'; |
| 885 | 885 | $max_batches = 100000; |
| 886 | 886 | |
| 887 | 887 | for ($batch = 0; $batch < $max_batches; $batch++) { |
| 888 | - $affected = $wpdb->query($wpdb->prepare( | |
| 888 | + $affected = $wpdb->query($wpdb->prepare( // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- batched bulk post_content rewrite — no bulk WordPress API; chunked by LIMIT to bound lock time | |
| 889 | 889 | "UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s) |
| 890 | 890 | WHERE post_content LIKE %s ORDER BY ID LIMIT %d", |
| 891 | 891 | $old_path, |
| 892 | 892 | $new_path, |