Finar.ru
web.finar.ru
video.finar.ru
Темы для BootstrapNew!

Как в NetCat научиться записывать в поле типа файл картинку с внешнего URL?

или простыми словами, как работает загрузка файлов в NetCat

Автор: Филипп Казаков, дата: 2014-04-28, просмотров 5444
Тэги

Поступила задача: сделать так, чтобы в NetCat 4.72 в поле типа "файл" научиться записывать картинку не только со своего компьютера, но и с URL. Чтобы выработать архитектурно правильный подход, пришлось немного копнуть исходники и разобраться с тем, как же работает механизм хранения файлов в Netcat. Хотя эксперименты я проводил на NetCat 4.72, предполагаю, что и в пятой версии все работает примерно также. Пост публикую из гуманистических соображений, а также чтобы самому не забыть результаты. Да, и чтобы не слишком разочаровывать, ответ на вопрос в заголовке: в полном смысле никак.

Как устроен штатный механизм загрузки хранения файлов в NetCat? А вот как:

Шаг 0: \netcat\message.php

При редактировании объекта, форма изменения объекта в целом обрабатывается файлом message.php Там много всякого кода, но собственно обработка полей происходит в двух других файлах, вызываемых из этого.

Шаг 1: \netcat\message_fields.php

Этот файл подключается примерно в районе 476 строчки message.php и в нем обрабатываются значения форм для режимов добавления/изменения.

Обработка input'ов с файлами начинается кодом case NC_FIELDTYPE_FILE: и далее NetCat делает примерно следующее (точность не гарантирую, писал по интуиции):

  • запоминает старое значение на случай ошибки;
  • проверяет, что мы выбрали именно файл для закачки с компьютера, а не что-то другое;
  • проверяет, что если выбрано что-то непонятное, то может быть уже существует такой файл и такое поле?
  • проверяет, что файл передан, и передан именно через POST;
  • узнает параметры поля (тип файловой системы, закачиваемый ли файл);
  • сверяет размер файла с допустимыми настройками;
  • сверяет тип файла с допустимыми настройками.

Шаг 2: \netcat\message_put.php

Этот файл подключается примерно в районе 646 строчки message.php и он отвечает за отправку значений полей в Базу Данных.

Обработка input'ов с файлами начинается кодом if ($fldType[$i] == NC_FIELDTYPE_FILE) и далее NetCat делает примерно следующее:

  • еще разок проверяет, что файл передан, и передан именно через POST;
  • вырезает спецсимволы из имени файла;
  • определяет имя, тип, размер, расширение файла;
  • готовит запись о файле вот в таком виде: $fldValue[$i] = $filename.":".$filetype.":".$filesize; ;
  • проверяет права пользователя;
  • генерит путь к файлу:
    • в зависимости от типа файловой системы
    • делая транслитерацию при необходимости
    • добавляя автоматом к имени число, если такой файл уже существует
  • удаляет старый файл, если он есть;
  • создает необходимые директории;
  • наконец, помещает файл туда, куда нужно.

Вот так это работает. Чтобы внедриться сюда, нужно... я не имею ни малейшего понятия, что именно, поскольку файл, переданный методом POST обрабатывается на низком уровне веб-сервером (то есть автоматически, и на эту автоматику опирается NetCat). Как заставить сервер что-то скачать с другого сервера и посчитать, что это что-то передано через POST? Думаю, никак.

Поэтому чтобы внедриться придется полностью разобраться с этим кодом и целиком переписать его, что крайне, крайне трудозатратно, сложно, рискованно и неразумно, поскольку NetCat же живет своей жизнью, а эти изменения касаются ядра системы.

Поэтому думаем дальше.

Придется сделать стороннее решение, ограничив задачу.

Посмотрим, как NetCat хранит данные о картинке в поле image в MySQL: netcat.txt:text/plain:2588:1/32/netcat.txt При обработке этой информации при рендеринге страницы, она превращается в:

$f_image ссылка на файл
$f_image_type MIME-тип файла
$f_image_size размер файла

Кстати (только при Защищенной Файловой Системе, не мой случай):
$f_image_url прямая ссылка на файл
$f_image_name оригинальное имя файла
$f_image_download количество запросов на скачивание

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

Нет проблем загрузить файл ajax-ом с другого сервера, но что делать, если мы хотим сохранить оба инструмента (и загрузку с компьютера)?

  • либо в режиме редактирования на jQuery регулировать дефолтное поле (то есть отключать его, если выбрана загрузка с URL)
    • но это приведет к проблемам с удалением и, кстати, а как удалять-то загруженные файлы?
  • либо вообще забить на весь дефолтный механизм работы с файлами, и добавить наряду с возможностью закачки картинки с URL также и возможность налету загружать с компьютера через html5
    • что даст такие приятные плюшки, как мультизагрузка фото + выбор "ведущей" заявочной фотографии, которая и будет в итоге попадать в поле NetCat

Очевидно, второй вариант предпочтительней.

Картинки будем хранить в директории, жестко привязанной к ID-шнику текущего объекта (кстати, дефолтную адресацию вида netcat_files/sub/cc/ можно было бы изменить (если бы мы не отказались от всего механизма), определив в Условиях Добавления элемент массива: $f_image['folder'] = 'ИмяДиректории';)

Предложенное решение решит поставленную задач, однако полностью обходит механизм работы NetCat, поэтому обладают рядом ограничений:

  • картинки заливают только благонадежные администраторы, вся система проверки безопасности NetCat неактивна, проверка ограничений на тип и размер файлов тоже;
  • картинки будут храниться в заранее известной директории;
  • картинки никак не будут преобразовываться | для этого у нас есть Кэшатор?, и да, я подумал об этом еще когда мы разрабатывали его :)
  • все это работает только в режиме изменения объекта, режим добавления купируется | вообще, я склоняюсь к тому, что это поведение стоило бы сделать дефолтным для всех случаев сложных нестандартных функционалов режимов редактирования объекта.

Есть комментарии? Может быть я что-то упустил? Комментируйте!


Илья — 2014-04-29, 09:39

Нажимаем "Выбрать файл" в форме добавления/редактирования. Открывается стандартное окно проводника Windows, где можно потыкаться и выбрать нужный файл. Вместо этого берем URL нужной картинки со стороннего сервера, копируем и вставляем в проводнике в текстовое поле, в котором обычно хранится путь к файлу. Файл загружается вnetcat_files/sub/cc/. Не знаю, ужимается он, кэшируется или еще что, но заливается - факт. И потом доступен на сайте для просмотра.

Все гениальное - просто! Отличное решение для администраторов, о котором я, действительно, не знал. :) ОС семейства Windows при такой операции скачивают файл на компьютер во временную директорию и после этого отдают через POST как ни в чем не бывало:

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

Finar.

Адольф Гитлер — 2014-06-23, 11:32

Полезно! Спасибо

Оставить комментарий 


Ваше имя:
->