Загрузка файлов в динамически сформированном шаблоне настроек (бэкэнд)
Здравствуйте, уважаемые форумчане!
Пишу плагин для элемента страницы на фронтэнде с категориями (со ссылкой) и их картинками. Каждый элемент списка добавляется динамечески (брал с плагина 301 Redirect). Для отображения опции для каждой категории используется " Динамическое формирование списка значений".

И вот какая проблема, поля типа waHtmlControl::INPUT и waHtmlControl::CHECKBOX оно сохраняет, но вот FILE - ни в какую не может. При том, не могу его никак отловить. Он не передаётся ни в $settings, ни в waRequest::file().
Грузится всё через iFrame, эта строка в шаблоне также присутствует: $.plugins.options.useIframeTransport = true;
При том, если я просто добавляю waHtmlControl::FILE в settings.php и туда передаю картинку - всё передаётся (в переменной $settings).
Подскажите, как заставить эту штуку работать. Излазил уже все форумы и документации и в движке посмотрел (хоть и не особо что понял) .
Всем заранее спасибо!
Эта тема в архиве. Добавление комментариев к ней отключено.










10 ответов
Он и не должен передаваться, вы должны самостоятельно отлавливать файлы через клиент, а не сервер. Пользователь выбрал файл - сразу грузите его, проверяя форматы и размеры, сохраняете в скрытом поле ссылку, а по нажатию "Сохранить" уже готовую ссылку куда-то в базу пихаете.
вообще-то должен, можно обойтись без таких усложнений тем более проверка данных должна быть комплексной.
посмотрите тег формы у нее задан атрибут enctype? и судя по тому что грузите Вы сразу много файлов поле должно называться как-то так "settings[files][]".
Да, "enctype="multipart/form-data". Вывел через print_r() в лог переменную "$setting", но в ней только чекбокс и инпут с формы. Ключа settings[files][]" не имеется.
в общем пиши свой код никому в угадайку играть не хочется
Спасибо за ответ!
name'ы у инпутов в админке: shop_promo[custom][0][image], shop_promo[custom][1][image] и так далее. Вот реализация самого блока (брал из плагина 301 Redirect):
public function settingPromoControl($name, $params = array()) { $control = ''; $default_rule = array( 'category' => '', 'status' => false, 'image' => array(), ); if (!isset($params['value']) || !is_array($params['value'])) { $params['value'] = array(); } $params['value'][] = $default_rule; unset($params['options']); foreach ($params as $field => $param) { if (strpos($field, 'wrapper')) { unset($params[$field]); } } waHtmlControl::addNamespace($params, $name); $template = <<<HTML <tr> <td>%s</td> <td><span class="hint">%s</span></td> <td>%s</td> <td>→</td> <td>%s</td> <td><a href="#/promo/delete/" class="inline-link js-action"><i class="icon16 delete"></i></a></td> </tr> HTML; $params = array_merge( $params, array( 'description' => null, 'title_wrapper' => false, 'title' => null, ) ); $control .= "<table class = \"zebra\">"; $control .= "<tfoot>"; $control_row = <<<HTML <tr> <td colspan="6"><a href="#/promo/add/" class="inline-link js-action"><i class="icon16 add"></i> %s</a></td> </tr> HTML; $control .= sprintf($control_row, _wp('Add rule')); $control .= "</tfoot>"; $control .= "<tbody>"; $redirect_template = '<span class="hint">%s</span>'; $categories = $this-> categoryModel()-> getAll(); $category_list = array(); // Add select placeholder array_push($category_list, array( 'value' => 0, 'title' => _wp("Select..."), )); foreach ($categories as $category => $value) { array_push($category_list, array( 'value' => $value['id'], 'title' => $value['name'], )); } foreach ($params['value'] as $id => $rule) { $rule_params = $params; waHtmlControl::addNamespace($rule_params, $id); $value = isset($params['value'][$id]) ? $params['value'][$id] : $default_rule; $category = waHtmlControl::getControl(waHtmlControl::SELECT, 'category', array_merge( $rule_params, array( 'description' => sprintf('<span class="hint">%s</span>', 'Choose category'), 'value' => ifset($value['category'], ''), 'title' => 'category', 'options' => $category_list, ) )); $status = waHtmlControl::getControl(waHtmlControl::CHECKBOX, 'status', array_merge( $rule_params, array( 'title' => 'status', 'value' => ifset($value['status']), ) )); $image = waHtmlControl::getControl(waHtmlControl::FILE, 'image', array_merge( $rule_params, array( 'title' => 'image', 'value' => ifset($value['image']), 'description' => sprintf($redirect_template, _wp('Image for category')), ) )); $control .= sprintf($template, '<i class="icon16 sort"></i>', $status, $category, $image); } $control .= "</tbody>"; $control .= "</table><script type='text/javascript'>"; $control .= <<<JS $('table.zebra ').sortable({ distance: 5, opacity: 0.75, items: '>tbody>tr', axis: 'y', containment: 'parent', handle:'i.sort', tolerance: 'pointer' }); JS; $control .= '</script>'; return $control; }У waHtmlControl::FILE есть еще параметр $params['img_path'].
Переопредели метод `waPlugin::saveSettings($settings = array())`, $settings уже содержат объекты waRequestFile т.ч. остается только сохранить их и обновить значение $settings.
Да, saveSettings($settings = array()) переопределён, я вывел $settings в лог, но там нет полей от FILE, а только от CHECKBOX:
Не совсем понял, мне нужно самому где-то добавить параметр "img_path" или он должен где-то присутствовать (я в лог выводил всё, что можно, но такого параметра нигде не встречал).
вот рабочий пример из метода saveSettings:
if (isset($settings['image']) && $settings['image'] instanceof waRequestFile) { /** * @var waRequestFile $file */ $file = $settings['image']; $oldFile = $path . $oldSettings['image']; if ($file->uploaded()) { // check that file is image try { // create waImage $file->waImage(); } catch(Exception $e) { throw new Exception(_w("File isn't an image")); } $path = wa()->getDataPath('data/coffer/', true); if (!empty($oldSettings['image'])) { waFiles::delete($oldFile); } $file_name = 'cofferstamp.' . $file->waImage()->getExt(); if (!file_exists($path) || !is_writable($path)) { throw new waException('Не могу сохранить файл. Проверьте права на запись.'); } elseif (!$file->moveTo($path, $file_name)) { throw new waException(_wp('Failed to upload file.')); } $settings['image'] = $file_name; } }где-то делал симпатичнее, но не могу вспомнить в каком плагине :)
Дело в том, что у меня ничего не пападает в $settings['image']. Если я добавляю форму для файла через settings.php, то всё работает как и у вас, но я добавляю форму в динамический шаблон и там name у инпута shop_promo[custom][0][image]. Он в $settings и в waRequestFile не передаётся.