Как я могу загрузить изображения с помощью PHP с помощью Prestashop? - PullRequest
1 голос
/ 21 июня 2019

Я пытаюсь выполнить автоматическую загрузку продуктов, используя API-интерфейс SOAP с PHP-кодированием Prestashop.

Кажется, что продукт загружен правильно, но изображения не правильно отображаются в frontoffice (backoffice делает).Я пробовал несколько фрагментов кода, которые нашел в Интернете, но ни один из них не удовлетворил то, что мне было нужно.

У меня есть класс с именем Jubaconfig.php, где я выполняю код для импорта продуктов.Каждый продукт создается следующим образом:

$product = new Product();
                $product->name[1] = $productInfo->name;
                $product->reference = $productInfo->product_id;
                $product->description[1] = $productInfo->description;
                $product->description_short[1] = $productInfo->short_description;
                $product->active = 1;
                $product->condition = "new";
                $product->id_tax_rules_group = 1;
                $product->id_manufacturer = 3;
                $product->id_category_default = 49;
                $product->add();
                $product->save();

                $product->addToCategories(array(49));
                StockAvailable::setQuantity((int)$product->id, 0, $product->quantity);
                // Añadimos la imagen al producto

                $cover = true;
                $image_url = ($productInfo->additional_attributes[0]->value);

                var_dump($image_url);
                echo "<br>";

                $image = new Image();
                $image->id_product = $product->id;
                $image->position = Image::getHighestPosition($product->id) + 1;
                $image->cover = $cover;
                if (($image->validateFields(false, true)) === true &&
                    ($image->validateFieldsLang(false, true)) === true && $image->add())
                {
                    $image->associateTo($product->id_shop_default);
                    if (!Jubaconfig::copyImg($product->id, $image->id, $image_url, 'products', false))
                    {
                        $image->delete();
                    }
                }

Функция copyImg выглядит следующим образом:

public function copyImg($id_entity, $id_image = null, $url = '', $entity = 'products', $regenerate = true)
    {
        $tmpfile = tempnam(_PS_TMP_IMG_DIR_, 'ps_import');
        $watermark_types = explode(',', Configuration::get('WATERMARK_TYPES'));

        switch ($entity) {
            default:
            case 'products':
                $image_obj = new Image($id_image);
                $path = $image_obj->getPathForCreation();
                break;
            case 'categories':
                $path = _PS_CAT_IMG_DIR_ . (int) $id_entity;
                break;
            case 'manufacturers':
                $path = _PS_MANU_IMG_DIR_ . (int) $id_entity;
                break;
            case 'suppliers':
                $path = _PS_SUPP_IMG_DIR_ . (int) $id_entity;
                break;
            case 'stores':
                $path = _PS_STORE_IMG_DIR_ . (int) $id_entity;
                break;
        }

        $url = urldecode(trim($url));
        $parced_url = parse_url($url);

        if (isset($parced_url['path'])) {
            $uri = ltrim($parced_url['path'], '/');
            $parts = explode('/', $uri);
            foreach ($parts as &$part) {
                $part = rawurlencode($part);
            }
            unset($part);
            $parced_url['path'] = '/' . implode('/', $parts);
        }

        if (isset($parced_url['query'])) {
            $query_parts = array();
            parse_str($parced_url['query'], $query_parts);
            $parced_url['query'] = http_build_query($query_parts);
        }

        if (!function_exists('http_build_url')) {
            require_once _PS_TOOL_DIR_ . 'http_build_url/http_build_url.php';
        }

        $url = http_build_url('', $parced_url);

        $orig_tmpfile = $tmpfile;

        if (Tools::copy($url, $tmpfile)) {
            // Evaluate the memory required to resize the image: if it's too much, you can't resize it.
            if (!ImageManager::checkImageMemoryLimit($tmpfile)) {
                @unlink($tmpfile);

                return false;
            }

            $tgt_width = $tgt_height = 0;
            $src_width = $src_height = 0;
            $error = 0;
            ImageManager::resize($tmpfile, $path . '.jpg', null, null, 'jpg', false, $error, $tgt_width, $tgt_height, 5, $src_width, $src_height);
            $images_types = ImageType::getImagesTypes($entity, true);

            if ($regenerate) {
                $previous_path = null;
                $path_infos = array();
                $path_infos[] = array($tgt_width, $tgt_height, $path . '.jpg');
                foreach ($images_types as $image_type) {
                    $tmpfile = self::get_best_path($image_type['width'], $image_type['height'], $path_infos);

                    if (ImageManager::resize(
                        $tmpfile,
                        $path . '-' . stripslashes($image_type['name']) . '.jpg',
                        $image_type['width'],
                        $image_type['height'],
                        'jpg',
                        false,
                        $error,
                        $tgt_width,
                        $tgt_height,
                        5,
                        $src_width,
                        $src_height
                    )) {
                        // the last image should not be added in the candidate list if it's bigger than the original image
                        if ($tgt_width <= $src_width && $tgt_height <= $src_height) {
                            $path_infos[] = array($tgt_width, $tgt_height, $path . '-' . stripslashes($image_type['name']) . '.jpg');
                        }
                        if ($entity == 'products') {
                            if (is_file(_PS_TMP_IMG_DIR_ . 'product_mini_' . (int) $id_entity . '.jpg')) {
                                unlink(_PS_TMP_IMG_DIR_ . 'product_mini_' . (int) $id_entity . '.jpg');
                            }
                            if (is_file(_PS_TMP_IMG_DIR_ . 'product_mini_' . (int) $id_entity . '_' . (int) Context::getContext()->shop->id . '.jpg')) {
                                unlink(_PS_TMP_IMG_DIR_ . 'product_mini_' . (int) $id_entity . '_' . (int) Context::getContext()->shop->id . '.jpg');
                            }
                        }
                    }
                    if (in_array($image_type['id_image_type'], $watermark_types)) {
                        Hook::exec('actionWatermark', array('id_image' => $id_image, 'id_product' => $id_entity));
                    }
                }
            }
        } else {
            @unlink($orig_tmpfile);

            return false;
        }
        unlink($orig_tmpfile);

        return true;
    }

Когда я иду в раздел «Продукты» в бэк-офисе, продуктыправильно загружены, даже картинки.Однако во фронт-офисе продукты по-прежнему отображаются, но изображения не отображаются, поскольку источник изображения не является правильным.

Совет. Если я отредактирую недавно добавленный продукт и сохраню его, изображение запустится.отображение во фронт-офисе.Но мне нужно отобразить все импортированные изображения без необходимости сохранять каждый продукт по одному.

1 Ответ

0 голосов
/ 23 июня 2019

Это то, что я использую в подобных случаях (пример для изображений продуктов, но вы поняли).

**
     * Creates/updates product images
     * @param int    $id_product
     * @param string $img_name
     * @return bool
     */
    private function createImage($id_product, $img_name)
    {
        $url = Configuration::get('My_KEY') . "v1/images/" . $img_name . ".jpg";
        $shops = Shop::getShops(true, null, true);
        $image = new Image();
        $image->id_product = $id_product;
        $image->position = Image::getHighestPosition($id_product) + 1;
        $image->cover = true;
        if(($image->validateFields(false, true)) === true && ($image->validateFieldsLang(false, true)) === true
            && $image->add()) {
            $image->associateTo($shops);
            if(!AdminImportController::copyImg($id_product, $image->id, $url, 'products', true)) {
                file_put_contents($this->log, $this->date . " createImage error creating image" . PHP_EOL, FILE_APPEND);
                $image->delete();

            }
        }
        return true;
    }

Использование существующего контроллера ядра PS (начиная с версии 1.6+) кажется мне самым простым способом.

...