Загрузка файлов в динамически сформированном шаблоне настроек (бэкэнд)

Здравствуйте, уважаемые форумчане!

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


И вот какая проблема, поля типа waHtmlControl::INPUT и waHtmlControl::CHECKBOX оно сохраняет, но вот FILE - ни в какую не может. При том, не могу его никак отловить. Он не передаётся ни в $settings, ни в waRequest::file().

Грузится всё через iFrame, эта строка в шаблоне также присутствует: $.plugins.options.useIframeTransport = true;
При том, если я просто добавляю waHtmlControl::FILE в settings.php и туда передаю картинку - всё передаётся (в переменной $settings).

Подскажите, как заставить эту штуку работать. Излазил уже все форумы и документации и в движке посмотрел (хоть и не особо что понял) .

Всем заранее спасибо!

10 ответов

  • 1
    Константин Шевский 25 февраля 2018 07:58 #

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

    • +1
      info@ravencode.ru info@ravencode.ru 25 февраля 2018 14:17 #

      вообще-то должен, можно обойтись без таких усложнений тем более проверка данных должна быть комплексной.

  • 1
    info@ravencode.ru 25 февраля 2018 14:19 #

    посмотрите тег формы у нее задан атрибут enctype? и судя по тому что грузите Вы сразу много файлов поле должно называться как-то так "settings[files][]".

    • +1
      m1 abed m1 abed 26 февраля 2018 20:20 #

      Да, "enctype="multipart/form-data". Вывел через print_r() в лог переменную "$setting", но в ней только чекбокс и инпут с формы. Ключа settings[files][]" не имеется.

      • +1
        info@ravencode.ru info@ravencode.ru 27 февраля 2018 11:40 #

        в общем пиши свой код никому в угадайку играть не хочется

        • +1
          m1 abed m1 abed 1 марта 2018 15:11 #

          Спасибо за ответ!

          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;
              }
          • +1
            info@ravencode.ru info@ravencode.ru 1 марта 2018 18:08 #

            У waHtmlControl::FILE есть еще параметр $params['img_path'].

            Переопредели метод `waPlugin::saveSettings($settings = array())`, $settings уже содержат объекты waRequestFile т.ч. остается только сохранить их и обновить значение $settings.

            • +1
              m1 abed m1 abed 1 марта 2018 18:51 #

              Да, saveSettings($settings = array()) переопределён, я вывел $settings в лог, но там нет полей от FILE, а только от CHECKBOX:

              Array(
              	[custom] => Array(
              		[0] => Array(
              				[category] => 1
              			)
              		[1] => Array(
              				[category] => 2
              			)
              	)
              )

              Не совсем понял, мне нужно самому где-то добавить параметр "img_path" или он должен где-то присутствовать (я в лог выводил всё, что можно, но такого параметра нигде не встречал).

              У waHtmlControl::FILE есть еще параметр $params['img_path'].
  • 3
    ITFrogs 2 марта 2018 14:09 #

    вот рабочий пример из метода 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;
        }
    }

    где-то делал симпатичнее, но не могу вспомнить в каком плагине :)

    • +1
      m1 abed m1 abed 2 марта 2018 19:54 #

      Дело в том, что у меня ничего не пападает в $settings['image']. Если я добавляю форму для файла через settings.php, то всё работает как и у вас, но я добавляю форму в динамический шаблон и там name у инпута shop_promo[custom][0][image]. Он в $settings и в waRequestFile не передаётся.

Добавить ответ

Чтобы добавить комментарий, зарегистрируйтесь или войдите