woocommerce 导入商品时图片处理逻辑

在 woocommerce 导入商品时,如果你的 csv 中的商品有 images 字段,如果图片是外部连接,他会一个一个下载到本地,然后再重新上传,因为我导入的商品一次会导入几百个,造成 cdn 认为流量异常,直接给拒绝了,特意看了 woocommerce 处理图片的逻辑,总结如下:

  1. 只要是 images 字段里面的图片,如果是外部图片(在 media libaray 中不存在),就会先通过 curl 下载到本地,然后再上传,最后在 gallery 中展示用的是这个 media id.
 /**
         * Get attachment ID.
         *
         * @param  string $url        Attachment URL.
         * @param  int    $product_id Product ID.
         * @return int
         * @throws Exception If attachment cannot be loaded.
         */
        public function get_attachment_id_from_url( $url, $product_id ) {
                if ( empty( $url ) ) {
                        return 0;
                }

                $id         = 0;
                $upload_dir = wp_upload_dir( null, false );
                $base_url   = $upload_dir['baseurl'] . '/';

                // Check first if attachment is inside the WordPress uploads directory, or we're given a filename only.
                if ( false !== strpos( $url, $base_url ) || false === strpos( $url, '://' ) ) {
                        // Search for yyyy/mm/slug.extension or slug.extension - remove the base URL.
                        $file = str_replace( $base_url, '', $url );
                        $args = array(
                                'post_type'   => 'attachment',
                                'post_status' => 'any',
                                'fields'      => 'ids',
                                'meta_query'  => array( // @codingStandardsIgnoreLine.
                                        'relation' => 'OR',
                                        array(
                                                'key'     => '_wp_attached_file',
                                                'value'   => '^' . $file,
                                                'compare' => 'REGEXP',
                                        ),
                                        array(
                                                'key'     => '_wp_attached_file',
                                                'value'   => '/' . $file,
                                                'compare' => 'LIKE',
                                        ),
                                        array(
                                                'key'     => '_wc_attachment_source',
                                                'value'   => '/' . $file,
                                                'compare' => 'LIKE',
                                        ),
                                ),
                        );
                } else {
                        // This is an external URL, so compare to source.
                        $args = array(
                                'post_type'   => 'attachment',
                                'post_status' => 'any',
                                'fields'      => 'ids',
                                'meta_query'  => array( // @codingStandardsIgnoreLine.
                                        array(
                                                'value' => $url,
                                                'key'   => '_wc_attachment_source',
                                        ),
                                ),
                        );
                }

                $ids = get_posts( $args ); // @codingStandardsIgnoreLine.

                if ( $ids ) {
                        $id = current( $ids );
                }

                // Upload if attachment does not exists.
                if ( ! $id && stristr( $url, '://' ) ) {
                        $upload = wc_rest_upload_image_from_url( $url );

                        if ( is_wp_error( $upload ) ) {
                                throw new Exception( $upload->get_error_message(), 400 );
                        }

                        $id = wc_rest_set_uploaded_image_as_attachment( $upload, $product_id );

                        if ( ! wp_attachment_is_image( $id ) ) {
                          /* translators: %s: image URL */
                                throw new Exception( sprintf( __( 'Not able to attach "%s".', 'woocommerce' ), $url ), 400 );
                        }

                        // Save attachment source for future reference.
                        update_post_meta( $id, '_wc_attachment_source', $url );
                }

                if ( ! $id ) {
                        /* translators: %s: image URL */
                        throw new Exception( sprintf( __( 'Unable to use image "%s".', 'woocommerce' ), $url ), 400 );
                }

                return $id;
        }

代码的实现在 wp-content/plugins/woocommerce/includes/import/abstract-wc-product-importer.php 中。

发表评论