Перейти к содержанию
Официальный форум поддержки Simpla

Рекомендуемые сообщения

1. Переименование загружаемого файла по урл (чтобы не заменялись файлы)

2. Корректная загрузка изображения при указании ссылки как исчтоника

3. Проверка на изображение

Всем кому не нужны эти фиксы проходим мимо.

 

1 и 3. заменить метод upload_image в классе Image.php на этот. изменений тут минимум, просто местами кое что поменял, добавил копирование через copy для п.2, и добавил не обязательный 3-ий аргумент - новое имя файла.

    public function upload_image($filename, $name, $nn = false)
    {
        //проверяем изображение на содержимое и получаем расширение файла
        $type = $this->image_check($filename);
        if(!$type)
            return false;

        // Имя оригинального файла
        $name = $this->correct_filename($name);
        $uploaded_file = pathinfo($name, PATHINFO_BASENAME);

        //если третий аргумент не указан, то берем название файла пользовательское, иначе третий аргумент
        $base = (!$nn ? pathinfo($uploaded_file, PATHINFO_FILENAME) : $nn);
        $ext = pathinfo($uploaded_file, PATHINFO_EXTENSION);
        //если файл закачивается по ссылке и в ссылке нет конечного расширения файла
        //то берем из метода выше
        if(!$ext)
            $ext = $type;
        $new_name = (!$nn ? $uploaded_file : $nn).".".$ext;

        if(in_array(strtolower($ext), $this->allowed_extentions)){
            while(file_exists($this->config->root_dir.$this->config->original_images_dir.$new_name)){
                $new_base = pathinfo($new_name, PATHINFO_FILENAME);
                if(preg_match('/_(\d+)$/', $new_base, $parts))
                    $new_name = $base."_".($parts[1]+1).".".$ext;
                else
                    $new_name = $base."_1.".$ext;
            }
            $destfile = $this->config->root_dir.$this->config->original_images_dir.$new_name;
            is_uploaded_file($filename) ? move_uploaded_file($filename, $destfile) : copy($filename, $destfile);
            return $new_name;
        }
        return false;
    }
 

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

 

    public function image_check($file){
        $handle = fopen($file, 'r');                //открываем файл
        $contents = fread($handle, 10);                //читаем 10 байт
        fclose($handle);                            //закрываем файл
        $pos["jpg"] = strpos($contents, "Exif");    //1-ая проверка: на jpeg формат
        $pos["jpeg"] = strpos($contents, "JFIF");    //2-ья проверка: на jpeg формат
        $pos["png"] = strpos($contents, "PNG");        //3-ая проверка: на PNG формат
        $pos["gif"] = strpos($contents, "GIF89");    //4-ая проверка: на GIF формат
        foreach($pos AS $type=>$check)
            if($check !== false)                    //если хотя бы 1 проверка сработала
                return $type;                        //то всё ОК
        return false;
    }

Далее в файле /simpla/ProductAdmin.php найти строку

 

if ($image_name = $this->image->upload_image($images['tmp_name'][$i], $images['name'][$i]))

и в неё дописать третий аргумент - новое имя для файла, а именно $product->url

 

if ($image_name = $this->image->upload_image($images['tmp_name'][$i], $images['name'][$i], $product->url))

Теперь имена новых закачиваемых файлов будут создаваться по урлу товара.

 

2. Чуть ниже кода что описан выше (/simpla/ProductAdmin.php) найти

 

    if(!empty($url) && $url != 'http://' && strstr($url,'/')!==false)
        $this->products->add_image($product->id, $url); 

и заменить его на

if(!empty($url))
{
    $namearr = explode("/", $url);
    $name = end($namearr);
    $ext = pathinfo($name, PATHINFO_EXTENSION);
    $data = @file_get_contents($url);
    if(strlen($data) > 0)
    {
        $tmpfname = tempnam(sys_get_temp_dir(), "img");
        file_put_contents($tmpfname, $data);
        $filename = $this->image->upload_image($tmpfname, $name, $product->url);
        unlink($tmpfname);
        $this->products->add_image($product->id, $filename);
    }
} 
Изменено пользователем a13x
Ссылка на сообщение
Поделиться на другие сайты

я правильно понимаю, что вы решили проблему с https и с русскими названиями?

А что была за проблема с https ? Если указание ссылки через https то это роли не сыграет, скрипт забирает данные через file_get_contents.

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

Можете дать пару ссылок я протестирую.

Изменено пользователем a13x
Ссылка на сообщение
Поделиться на другие сайты

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

Fixed

Изменено пользователем a13x
Ссылка на сообщение
Поделиться на другие сайты

Проверку на дропнутые изображения (через drag n drop), лучше внести в проверку на пустой урл.

Вобщем должно получиться вот так (просмотрел я этот фрагмент):

 

// Загрузка изображений из интернета и drag-n-drop файлов
if($images = $this->request->post('images_urls')){
    foreach($images as $url){
        // Если не пустой адрес и файл не локальный
        if(!empty($url)){
            if($dropped_images = $this->request->files('dropped_images')){
                $key = array_search($url, $dropped_images['name']);
                if ($key!==false && $image_name = $this->image->upload_image($dropped_images['tmp_name'][$key], $dropped_images['name'][$key], $product->url))
                     $this->products->add_image($product->id, $image_name);
            }
            $namearr = explode("/", $url);
            $name = end($namearr);
            $ext = pathinfo($name, PATHINFO_EXTENSION);
            $data = @file_get_contents($url);
            if(strlen($data) > 0){
                $tmpfname = tempnam(sys_get_temp_dir(), "img");
                file_put_contents($tmpfname, $data);
                $filename = $this->image->upload_image($tmpfname, $name, $product->url);
                unlink($tmpfname);
                $this->products->add_image($product->id, $filename);
            }
        }
    }
} 

p.s. ну и в проверке на изображения драгндроп тоже надо дописать новое имя файла в метод upload_image (в этом посте уже добавлено)

Изменено пользователем a13x
Ссылка на сообщение
Поделиться на другие сайты

Вы упустили один момент, функция resize_modifier (api/Design.php) не работает с https, её тоже нужно расширить, и ещё в функции resize (api/Image.php) тот же самый момент.

Ссылка на сообщение
Поделиться на другие сайты
доработка изменяет в  simpla/ProductAdmin.php  строки
 
							if(!empty($url) && $url != 'http://' && strstr($url,'/')!==false)
					 			$this->products->add_image($product->id, $url);

 

А чуть ниже  есть подобный фрагмент
 
                             elseif($dropped_images = $this->request->files('dropped_images'))
                              {
.........
                                                 $this->products->add_image($product->id, $image_name);
                            }

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

Ссылка на сообщение
Поделиться на другие сайты

Вы упустили один момент, функция resize_modifier (api/Design.php) не работает с https, её тоже нужно расширить, и ещё в функции resize (api/Image.php) тот же самый момент.

Изображение копируется к вам на сервер. Мне кажется неправильным брать

ссылки на другой источник и вставлять к себе в базу. А если изображение

удалится? Изменится путь? Что тогда?

 

 

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

хмм... у меня там другой фрагмент

 

                       // Загрузка изображений из интернета и drag-n-drop файлов
                      if($images = $this->request->post('images_urls'))
                      {
                        foreach($images as $url)
                        {
                            // Если не пустой адрес и файл не локальный
                            if(!empty($url) && $url != 'http://' && strstr($url,'/')!==false)
                                 $this->products->add_image($product->id, $url);
                             elseif($dropped_images = $this->request->files('dropped_images'))
                              {
                                 $key = array_search($url, $dropped_images['name']);
                                 if ($key!==false && $image_name = $this->image->upload_image($dropped_images['tmp_name'][$key], $dropped_images['name'][$key]))
                                                 $this->products->add_image($product->id, $image_name);
                            }
                        }
                    }
 

симпла, посл. версия.

Изменено пользователем a13x
Ссылка на сообщение
Поделиться на другие сайты

Изображение копируется к вам на сервер. Мне кажется неправильным брать

ссылки на другой источник и вставлять к себе в базу. А если изображение

удалится? Изменится путь? Что тогда?

 

Это неправильно лишь теоретически. А практически, если вставляете изображение в админке на странице товара, то при сохранении чужой URL картинки сразу же перепишется на свой. Проблемы такого плана возникают лишь после импорта, обмена с 1С и подобных объемных операций, например:

http://forum.simplacms.ru/topic/7321-%D0%BF%D1%80%D0%BE%D0%BF%D0%B0%D0%BB-%D0%B2%D0%BE%D0%B4%D1%8F%D0%BD%D0%BE%D0%B9-%D0%B7%D0%BD%D0%B0%D0%BA-%D0%BF%D1%80%D0%B8-%D1%83%D0%B2%D0%B5%D0%BB%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B8-%D0%BA%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B8-%D1%82%D0%BE/

Ссылка на сообщение
Поделиться на другие сайты

Изображение копируется к вам на сервер. Мне кажется неправильным брать

ссылки на другой источник и вставлять к себе в базу. А если изображение

удалится? Изменится путь? Что тогда?

Это здесь не при чем, в image.php есть доп. функция которая грузит удаленный файл на ваш сервер, а не тупо копирует путь к файлу в БД.
Ссылка на сообщение
Поделиться на другие сайты

Не проще ли загружать изображение на сервер при СОХРАНЕНИИ товара, ане при РЕСАЙЗЕ?

Вроде ничем не сложнее? Может, я не прав?

Недавно столкнуся с этим... Зачем именно так сделано?

Ссылка на сообщение
Поделиться на другие сайты

 

Это неправильно лишь теоретически. А практически, если вставляете

изображение в админке на странице товара, то при сохранении чужой URL

картинки сразу же перепишется на свой.

А картинка тоже сразу к вам в папку запишется или останется удаленно? А если её удалят / изменят название что будет у вас? Это уже неправильный подход.

 

 

Это здесь не при чем, в image.php есть доп. функция которая грузит

удаленный файл на ваш сервер, а не тупо копирует путь к файлу в БД.

Эта функция вызывается когда человек указал урл? нет. Значит и толку от этой функции ноль.

+ эта функция почти дублирует весь функционал upload_image, проще было

добавить 1 необязательный аргумент и всё бы заработало без доп. метода

download_image.

 

 

 

Не проще ли загружать изображение на сервер при СОХРАНЕНИИ товара, ане при РЕСАЙЗЕ?

Вроде ничем не сложнее? Может, я не прав?

Недавно столкнуся с этим... Зачем именно так сделано?

Я реализовал именно при сохранении товара.

Изменено пользователем a13x
Ссылка на сообщение
Поделиться на другие сайты

А картинка тоже сразу к вам в папку запишется или останется удаленно? А если её удалят / изменят название что будет у вас? Это уже неправильный подход.

 

На странице товара после сохранения страница перезагрузится с новыми данными. При этом отработает ресайз новой картинки. А при ресайзе уже сам файл изображения перепишется в свою папку со стороннего сайта, сторонний URL в базе заменится на локальный.  Следов стороннего URL на сайте совсем не останется. Это все - в течение считанных секунд. И бюрократизм типа "А если её удалят" тут не уместен...

Ссылка на сообщение
Поделиться на другие сайты

 

На странице товара после сохранения страница перезагрузится с новыми данными. При этом отработает ресайз новой картинки. А при ресайзе уже сам файл изображения перепишется в свою папку со стороннего сайта, сторонний URL в базе заменится на локальный.  Следов стороннего URL на сайте совсем не останется. Это все - в течение считанных секунд. И бюрократизм типа "А если её удалят" тут не уместен...

Это всё с ваших слов, по факту при попытке загрузить изображение я получал на странице товара битую картинку, при наводе на которую был битый путь http://simplacms.ru/http://targetsite.com что-то типа такого. Особо разбираться что там и когда произойдёт у меня желания небыло. То что я увидел было уже неправильно. Если вас устраивает некорректная работа скрипта - ваше дело.

 

p.s. тестировал на посл. версии симпла.

 

p.p.s

http://simpla-url-rewrite.webtask.pro/catalog/mobilnye-telefony/apple-iphone-4s-16gb

вот, загрузил изображение по ссылке, когда ожидать подхват изображение и копирование в нужные папки?

Изменено пользователем a13x
Ссылка на сообщение
Поделиться на другие сайты

 

На странице товара после сохранения страница перезагрузится с новыми данными. При этом отработает ресайз новой картинки.

Кто вам это сказал? :lol: метод add_image просто добавляет имя файла в БД, не более того, а метод upload_image работает только с загружаемыми файлами.

Изменено пользователем a13x
Ссылка на сообщение
Поделиться на другие сайты

p.p.s

http://simpla-url-rewrite.webtask.pro/catalog/mobilnye-telefony/apple-iphone-4s-16gb

вот, загрузил изображение по ссылке, когда ожидать подхват изображение и копирование в нужные папки?

 

Попробовал расшифровать Ваш сумбур.

Если на стандартном демо сайте загружаю на странице товара через "загрузить из интернета" по ссылке

http://soft-soft.ws/uploads/posts/2015-02/1424806182_gcyfvtztn824jnd.jpeg

то картинка сразу же появляется...

 

Если б Вы догадались открыть отдельно ссылку картинки

http://simpla-url-rewrite.webtask.pro/files/products/http%253A%252F%252Fsoft-soft.ws%252Fuploads%252Fposts%252F2015-02%252F1424806182_gcyfvtztn824jnd.800x600w.jpeg?98450ab150a685bf8164dbb6567a68c9

то увидели бы там сообщение: bad token

Должно быть, Вы на своем сайте сами что-то наворочали...

 

Если хотите сказать, что в стандартной Simpla c этим что-то неверно, то надо давать точный конкретный пример, который можно повторить на демо-сайте Simpla http://demo.simplacms.ru/....

 

 

 

Ссылка на сообщение
Поделиться на другие сайты

Кто вам это сказал? :lol: метод add_image просто добавляет имя файла в БД, не более того, а метод upload_image работает только с загружаемыми файлами.

 

Неужто Вы несогласны с высказанным утверждением, что "На странице товара после сохранения страница перезагрузится с новыми данными. При этом отработает ресайз новой картинки." ? 

Ссылка на сообщение
Поделиться на другие сайты

Я видел сообщение про bad token, только вот с токеном я ничего не делал. В админке, при добавлении ссылки, изображение сразу становится битым. По поводу всего остального - пустой звон. Для чего вам это я не понимаю. Не нравится - проходите мимо. Не нравится как и что написано - проходите мимо. Есть что сказать по делу - говорите, но прежде чем сказать проверьте.

Ссылка на сообщение
Поделиться на другие сайты

Я видел сообщение про bad token, только вот с токеном я ничего не делал. В админке, при добавлении ссылки, изображение сразу становится битым. По поводу всего остального - пустой звон. Для чего вам это я не понимаю. Не нравится - проходите мимо. Не нравится как и что написано - проходите мимо. Есть что сказать по делу - говорите, но прежде чем сказать проверьте.

 

В какой админке? Если на Вашем сайте, то зависит от того, что Вы там меняли.

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

 

Если Вы читали написанное внимательно, то должны были понять, что я именно проверил перед написанием на демо-сайте Simpla. Если Вы продолжаете утверждать что-то про СВОЙ сайт, могу проверить и там, если Вы захотите дать доступы...

Ссылка на сообщение
Поделиться на другие сайты

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

Для закгрузки изображений есть код:

 

                       // Загрузка изображений из интернета и drag-n-drop файлов
                      if($images = $this->request->post('images_urls'))
                      {
                        foreach($images as $url)
                        {
                            // Если не пустой адрес и файл не локальный
                            if(!empty($url) && $url != 'http://' && strstr($url,'/')!==false)
                                 $this->products->add_image($product->id, $url);
                             elseif($dropped_images = $this->request->files('dropped_images'))
                              {
                                 $key = array_search($url, $dropped_images['name']);
                                 if ($key!==false && $image_name = $this->image->upload_image($dropped_images['tmp_name'][$key], $dropped_images['name'][$key]))
                                                 $this->products->add_image($product->id, $image_name);
                            }
                        }
                    }

В нем есть только одно условие которое отвечает за загрузку фото по ссылке:

 

                            if(!empty($url) && $url != 'http://' && strstr($url,'/')!==false)
                                 $this->products->add_image($product->id, $url);

Оно никаким боком не закачивает изображение, а просто добавляет урл в базу. ВСЁ!

Следующий код

 

                             elseif($dropped_images = $this->request->files('dropped_images'))
                              {
                                 $key = array_search($url, $dropped_images['name']);
  
                              if ($key!==false && $image_name =
$this->image->upload_image($dropped_images['tmp_name'][$key],
$dropped_images['name'][$key]))
                                                 $this->products->add_image($product->id, $image_name);
                            }

относится к блоку драг н дроп изображений и никак не влияет на ссылку. Следовательно это два разных блока и ни о каком ресайзе нет речи. Как я писал выше, метод add_image просто добавляет вашу ссылку в базу. Работает это криво т.к. при выводе изображения должна отрабатывать функция resize на УДАЛЕННОМ (другом сервере) файле. Как это должно работать я не знаю. Может ресайз умеет так работать, но у меня нет. Может проблема в том что у меня на nginx установлена симпла, но кривой урл который отображается в админке даёт понять что проблема скорее в шаблоне или где то ещё (токен и тп). Почему работает на демо сайте? Автор мог исправить это как и многое другое. У меня нет желания поднимать локальную версию и проверять там. Если у вас работает - отлично, значит вам это не надо.

Ссылка на сообщение
Поделиться на другие сайты

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

....

Как это должно работать я не знаю.

 

Интересное соотношение...

 

Работает это криво т.к. при выводе изображения должна отрабатывать функция resize на УДАЛЕННОМ (другом сервере) файле.

 

Что работает криво и где? Если в стандартной Simpla, то все нормально. А если на ВАШЕМ сайте, то по Вашим индивидуальным причинам - скорее всего, что-то нестандартное или в измененном коде или в настройках сервера...

 

У меня нет желания поднимать локальную версию и проверять там.

 

Так проверяйте в другом месте, где Вам удобно...

 

Ссылка на сообщение
Поделиться на другие сайты
  • 1 месяц спустя...

Метод check_image стоит немного переписать и сделать более строгую проверку:

Вместо этого

    public function image_check($file){
        $handle = fopen($file, 'r');                //открываем файл
        $contents = fread($handle, 10);                //читаем 10 байт
        fclose($handle);                            //закрываем файл
        $pos["jpg"] = strpos($contents, "Exif");    //1-ая проверка: на jpeg формат
        $pos["jpeg"] = strpos($contents, "JFIF");    //2-ья проверка: на jpeg формат
        $pos["png"] = strpos($contents, "PNG");        //3-ая проверка: на PNG формат
        $pos["gif"] = strpos($contents, "GIF89");    //4-ая проверка: на GIF формат
        foreach($pos AS $type=>$check)
            if($check !== false)                    //если хотя бы 1 проверка сработала
                return $type;                        //то всё ОК
        return false;
    }

 

Написать так:

    public function image_check($file){
        $handle = fopen($file, 'r');                //открываем файл
        $contents = fread($handle, 3);                //читаем 3 байта
        fclose($handle);                            //закрываем файл
        $check = unpack('H*', $contents);            //берем 16-ти ричное значение прочитанных данных
        $mimes = array("ffd8ff"=>"jpg", "474946"=>"gif", "89504e"=>"png");
        if(isset($mimes[$check[1]])){
            return $mimes[$check[1]];
        }
        return false;
    }

Новая проверка ведется не по первым 10 байтам как было ранее, а по первым 3-ём. В первые 10 байте можно прописать фальшивую проверку и она сработает, пример:

<?
$JFIF = 'OK';
Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
×
×
  • Создать...