Jump to content

Загрузка изображений по URL на хостинг во время импорта


Recommended Posts

В данном решении предусмотрена проверка на ссылки с пустым изображением, т.е. часто бывает такое, что ссылка рабочая, но изображения нет. Так же предусмотрена загрузка с серверов, которые некорректно реагируют на прямое копирование изображения, пришлось делать через curl

В файле simpla/ajax/import.php

            // Изображения товаров
            if(isset($item['images']))
            {
                 Это всё условие, вместе с телом, нужно полностью заменить!
            }

Меняем на:

            // Изображения товаров
            if(isset($item['images']))
            {
                // Изображений может быть несколько, через запятую
                $images = explode(',', $item['images']);
                foreach($images as $image)
                {
                    $image = trim($image);
                    $size_f = 0;
                    $data_x = get_headers($image, true);
                    $size_f = isset($data_x['Content-Length'])?(int) $data_x['Content-Length']:0;
                    if(!empty($image) && $size_f>0)
                    {
                        if(strpos($image, 'http') !== false) {
                            $image = $this->image->download_image_from_site($image);
                        }
                       
                        // Имя файла
                        $image_filename = pathinfo($image, PATHINFO_BASENAME);
                       
                        // Добавляем изображение только если такого еще нет в этом товаре
                        $this->db->query('SELECT filename FROM __images WHERE product_id=? AND (filename=? OR filename=?) LIMIT 1', $product_id, $image_filename, $image);
                        if(!$this->db->result('filename'))
                        {
                            $this->products->add_image($product_id, $image);
                        }
                    }
                }
            }

Далее нужно создать новую функцию в файле api/Image.php

public function download_image_from_site($url, $type = 'copy') {      
        if($type == 'copy') {
            $name = $this->correct_filename(pathinfo($url, PATHINFO_BASENAME));
            $base = pathinfo($url, PATHINFO_FILENAME);
            $ext = pathinfo($url, PATHINFO_EXTENSION);
           
            if(in_array(strtolower($ext), $this->allowed_extentions))
            {
                while(file_exists($this->config->root_dir.$this->config->original_images_dir.$name))
                {    
                    $name = pathinfo($name, PATHINFO_FILENAME);
                    if(preg_match('/_([0-9]+)$/', $name, $parts))
                        $name = $base.'_'.($parts[1]+1).'.'.$ext;
                    else
                        $name = $base.'_1.'.$ext;
                }
                $file = fopen($this->config->root_dir.$this->config->original_images_dir.$name, 'w');
                $user_agent = "Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)";
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $url);
                curl_setopt($ch, CURLOPT_FILE, $file);
                curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
                curl_setopt($ch, CURLOPT_HEADER, false);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
                curl_setopt($ch, CURLOPT_POST, 0);
                $result = curl_exec($ch);
                curl_close($ch);
                fclose($file);
                return $name;
            }
            return false;
        }
        return false;
    }

На этом все. 

Link to post
Share on other sites
3 часа назад, Noxter сказал:

И положим сервак с такими кодерами :D

Зависит от прямоты/кривизны рук. У меня в основном работает.

Некоторые недостатки есть, куда ж без них? Например, если в поле изображений стоит 'image_http.jpg', то импорт дает ошибку.

Но чтоб этой доработкой получить результат вида "положим сервак", надо немалые способности проявить...

Link to post
Share on other sites

В Simpla это сделано стандартно - реальная загрузка распределенная, каждое фото загружается отдельно в тот момент, когда оно (впервые) запрашивается.

Если хотите сразу, то решать вопрос по аналогии с тем, как перевезти 200 человек, если есть только один обычный легковой автомобиль - дополнительными ухищрениями...

Link to post
Share on other sites
  • 2 weeks later...

Корректировка

В файле simpla/ajax/import.php нужно условие чуть по другому написать. Не все удаленные серверы дают данные по прошлому условию. В общем вот так будет проще и правильнее условие

// Изображения товаров
            if(isset($item['images']))
            {
                // Изображений может быть несколько, через запятую
                $images = explode(',', $item['images']);
                foreach($images as $image)
                {
                    $image = trim($image);
                    if (@getimagesize($image))
                    {
                        if(strpos($image, 'http') !== false) {
                            $image = $this->image->download_image_from_site($image);
                        }
                       
                        // Имя файла
                        $image_filename = pathinfo($image, PATHINFO_BASENAME);
                       
                        // Добавляем изображение только если такого еще нет в этом товаре
                        $this->db->query('SELECT filename FROM __images WHERE product_id=? AND (filename=? OR filename=?) LIMIT 1', $product_id, $image_filename, $image);
                        if(!$this->db->result('filename'))
                        {
                            $this->products->add_image($product_id, $image);
                        }
                    }
                }
            }

 

Link to post
Share on other sites
В 13.12.2021 в 22:24, Noxter сказал:

Загрузи 20к товаров по 5-10 фоток в 4к разрешении, посмотрим)

Вопрос не в том, что нужен ли такой функционал. Заказчики разные, иногда странные. В данном конкретном случае грузят по чуть-чуть, предупреждены о всех минусах загрузки больших порций и все таки решили что "ну вот надо и все тут".

Тут не решается вопрос целесообразности такого механизма, тут решается вопрос реализации такого механизма

Link to post
Share on other sites
В 14.12.2021 в 15:29, phukortsin сказал:

В Simpla это сделано стандартно - реальная загрузка распределенная, каждое фото загружается отдельно в тот момент, когда оно (впервые) запрашивается.

Если хотите сразу, то решать вопрос по аналогии с тем, как перевезти 200 человек, если есть только один обычный легковой автомобиль - дополнительными ухищрениями...

Да, есть. И:

  1. По умолчанию этот механизм глючит и не все картинки прогружает, проверено.. Т.е. нужно дорабатывать
  2. Покупатель заходит на страницу товара и хочет видеть картинку, а не ждать когда она прогрузится.. А админу сайта прогружать каждую карточку товара самостоятельно на сайте - то еще занятие

В целом я соглашусь, что прямая загрузка картинок по url это так себе идея. Но тут вовсе так себе идя загрузки картинок по url такими импортами. В идеале нужен парсинг не только товаров и урлов картинок, но и самих картинок, и пускай эта нагрузка ложится на парсинг. А уже готовый прайс с физическимикартинками импортировать по человечески.

А всегда ли все получается так, как нужно или как мы хотим?

Это я к философскому вопросу о целесообразности предложенного механизма, раз была поднята тема рассуждений.

Link to post
Share on other sites
В 13.12.2021 в 21:35, phukortsin сказал:

Зависит от прямоты/кривизны рук. У меня в основном работает.

Некоторые недостатки есть, куда ж без них? Например, если в поле изображений стоит 'image_http.jpg', то импорт дает ошибку.

Но чтоб этой доработкой получить результат вида "положим сервак", надо немалые способности проявить...

Благодарю, хорошее замечание, упустил момент :(

Link to post
Share on other sites

Так, в ходе тестов еще один косяк замечен. При загрузке картинок из папки originals проверка на размер изображения (которая исключается загрузку пустых картинок, да да, такие есть, открываешь ссылку - там картинка есть, но ее длина 0, просто ничего нет, но картинка есть, 404 ошибки не выдает)

В общем, вот снова исправленный вариант, с учетом загрузки локальных файлов изображений, и с учетом замечания phukortsin про http в именах файлов

// Изображения товаров
            if(isset($item['images']))
            {
                // Изображений может быть несколько, через запятую
                $images = explode(',', $item['images']);
                foreach($images as $image)
                {
                    $image = trim($image);      
                    if(strpos($image, 'http://') !== false || strpos($image, 'https://') !== false) {
                        if (@getimagesize($image)) {
                            $image = $this->image->download_image_from_site($image);
                        }
                    }
                       
                        // Имя файла
                        $image_filename = pathinfo($image, PATHINFO_BASENAME);
                       
                        // Добавляем изображение только если такого еще нет в этом товаре
                        $this->db->query('SELECT filename FROM __images WHERE product_id=? AND (filename=? OR filename=?) LIMIT 1', $product_id, $image_filename, $image);
                        if(!$this->db->result('filename'))
                        {
                            $this->products->add_image($product_id, $image);
                        }
 
                }
            }

 

Link to post
Share on other sites
  • 1 month later...

1. проверку на ссылку изображений лучше сделать регуляркой вместо explode, ибо с ней неважно как будут разбиты ссылки, по запятой, точке запятой или переносу строки

2. не обязятельно использовать CURL, file_get_contents тоже отлично работает, а CURL это отдельная бибилиотека которая может быть не включена.

3. кто мешет проверять на размер после скачки файла через strlen? кода меньше, результат тот же. (скачать нулевой файл или же запросить заголовки - по времени одно и тоже)

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...