Я работаю над приложением на основе Yii. И я столкнулся со странной вещью ...
Я пытаюсь добавить в форму input (type = file). Форма создается с помощью конструктора форм (класс CForm
). Но ввода не будет.
Мой код. Контроллер / действие:
$model=MyModel::model()->findByPk(700);
$model->scenario='my-scenario';
$form=new CForm('path.to.forms.my-form', $model);
$this->render('view', array('form'=>$form));
Вид:
echo $form
Конфигурация формы:
return array(
'attributes' => array(
'enctype' => 'multipart/form-data',
),
'elements' => array(
'name' => array(
'type' => 'text',
),
'image' => array(
'type' => 'file',
),
),
'buttons' => array(
'save' => array(
'type' => 'submit',
'label' => 'Save',
),
),
);
Модель:
//.....
public $image;
// ....
public function rules()
{
return array(
//...
array('image', 'file', 'types'=>'png', 'on'=>'my-scenario'),
);
}
С кодом выше я ожидал увидеть два поля - текст и файл. Но появляется только текст.
Если я поменяю валидатор file
на, скажем, required
- он работает, но мне нужен валидатор файлов.
Я использую Yii версии 1.1.13.
Самое интересное, что приведенный выше код работает, как и ожидалось, с более ранней версией Yii (1.1.9). Это известная ошибка в новой версии? Если да - есть ли решение? или мне нужно откатиться на предыдущую версию?
Заранее спасибо.
ОБНОВЛЕНИЕ:
Если вы добавите второй валидатор (один для файла и один для обязательного), он будет работать?
Нет, это не так. Думаю, я понял, почему. Смотрите ниже.
Похоже, это вызвано этой строкой в CForm ..
Да исправить. Вчера вооружившись отладчиком углубился :)
CFormElement::getVisible()
в конце концов вызывает CModel::isAttributeSafe()
и CModel::getSafeAttributeNames()
.
CForm::getSafeAttributeNames()
получает все валидаторы модели и оставляет только безопасные. Как мы видим, CFileValidator небезопасен.
Итак, не имеет значения, скольким безопасным валидаторам (required
или любым другим) назначен атрибут. CForm::getSafeAttributeNames()
удаляет его из белого списка, если есть хотя бы один небезопасный (file
). Валидатор файлов небезопасен с версии 1.1.12. Поэтому в 1.1.9 у меня он отлично работал :)
Следовательно, проблема в CFileValidator (или, по крайней мере, связана с ним), а не в CForm.
Единственное решение, которое я вижу до сих пор, - это создание собственного валидатора, расширенного из CFileValidator, помеченного как безопасный, и его использование вместо встроенного. Но я даже не могу представить, какие проблемы это может вызвать (я считаю, что у разработчиков Yii была веская причина сделать его небезопасно).
Надеюсь, это будет кому-нибудь полезно.
ОБНОВЛЕНИЕ 2
array('image', 'file', 'safe'=>true, 'types'=>'png', 'on'=>'my-scenario')
это правило проверки (явное safe=true
) также работает.