wp_basename( $path ), 'contents' => (string) file_get_contents( $path ), // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- локальный файл медиатеки, не адрес. ) ); } } if ( $found_on_disk ) { Logger::warning( 'Product photo skipped: neither the original nor the WordPress copy is accepted by aiModelka', array( 'attachment_id' => $attachment_id ) ); return null; } return self::download_remote( $attachment_id ); } /** * Скачивает изображение по адресу, если медиатека лежит не на диске сайта. * * Сначала оригинал, потом копия — по тому же правилу, что для файлов на диске. * * @param int $attachment_id Id вложения. * @return array{name: string, mime: string, contents: string, bytes: int, width: int, height: int}|null */ private static function download_remote( int $attachment_id ): ?array { require_once ABSPATH . 'wp-admin/includes/file.php'; $urls = array_unique( array_filter( array( wp_get_original_image_url( $attachment_id ), wp_get_attachment_url( $attachment_id ), ) ) ); foreach ( $urls as $url ) { $tmp = download_url( $url, self::DOWNLOAD_TIMEOUT ); if ( is_wp_error( $tmp ) ) { Logger::warning( 'Product photo download failed', array( 'attachment_id' => $attachment_id, 'url' => $url, 'error' => $tmp->get_error_message(), ) ); continue; } $checked = self::acceptable( $tmp ); $contents = null === $checked ? '' : (string) file_get_contents( $tmp ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- временный файл, только что скачанный download_url(). wp_delete_file( $tmp ); if ( null !== $checked ) { return array_merge( $checked, array( 'name' => wp_basename( (string) wp_parse_url( $url, PHP_URL_PATH ) ), 'contents' => $contents, ) ); } } Logger::warning( 'Product photo skipped: no usable file found by its address', array( 'attachment_id' => $attachment_id ) ); return null; } /** * Тип, вес и размеры файла, если aiModelka его примет; иначе null. * * Тип определяется по содержимому файла, а не по расширению — так же, как на сервере. * * @param string $path Путь к файлу. * @return array{mime: string, bytes: int, width: int, height: int}|null */ private static function acceptable( string $path ): ?array { $size = filesize( $path ); if ( false === $size || $size <= 0 || $size > self::MAX_BYTES ) { return null; } $mime = wp_get_image_mime( $path ); if ( ! is_string( $mime ) || ! in_array( $mime, self::ACCEPTED_TYPES, true ) ) { return null; } $dimensions = wp_getimagesize( $path ); $width = is_array( $dimensions ) ? (int) $dimensions[0] : 0; $height = is_array( $dimensions ) ? (int) $dimensions[1] : 0; if ( $width * $height > self::MAX_PIXELS ) { return null; } return array( 'mime' => $mime, 'bytes' => (int) $size, 'width' => $width, 'height' => $height, ); } }