Yii form builder - file-upload

I've been working on Yii-based application. And I've faced with weird thing...
What I'm trying to do is to add input(type=file) into form. Form is created via form builder(CForm class). But input is not going to appear.
My code. Controller/action:
$model=MyModel::model()->findByPk(700);
$model->scenario='my-scenario';
$form=new CForm('path.to.forms.my-form', $model);
$this->render('view', array('form'=>$form));
View:
echo $form
Form config:
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',
),
),
);
Model:
//.....
public $image;
// ....
public function rules()
{
return array(
//...
array('image', 'file', 'types'=>'png', 'on'=>'my-scenario'),
);
}
With code above I expected to see two fields - text and file. But only text one appears.
If I change file validator to, say, required - it works, but I need file validator.
I'm using Yii version 1.1.13.
The most intresting that code above works as expected with earlier Yii(1.1.9). Is this a known bug in new version? If yes - is there a solution? or do I have to rollback to previous version?
Thanks in advance.
UPDATE:
If you add a second validator (one for file and one for required) does it work?
No, it doesn't. I believe I found why. See bellow.
It seems to be caused by this line in CForm..
Yes, correct. Yesterday, armed with debugger I went deeper:)
CFormElement::getVisible() eventually calls CModel::isAttributeSafe() and CModel::getSafeAttributeNames().
CForm::getSafeAttributeNames() gets all model validators and leaves only safe ones. As we can see CFileValidator is not safe.
So, it doesn't matter how many safe validators(required or any other) have attribute assigned. CForm::getSafeAttributeNames() removes it from whitelist if there is at least one unsafe(file).
File validator is unsafe since 1.1.12 version. That is why it worked perfectly for me in 1.1.9 :)
Hence the problem is in CFileValidator(or at least connected with it) and not in CForm.
The only one solution I can see so far is creating own validator extended from CFileValidator marked safe and using it instead of built in. But I can't even imagine what problems it may cause(I believe Yii developers had a good reason for making it unsafe).
I hope this will be helpful for somebody.
UPDATE 2
array('image', 'file', 'safe'=>true, 'types'=>'png', 'on'=>'my-scenario')
this validation rule(explicit safe=true) also works.

If you add a second validator (one for file and one for required) does it work? I ran into this recently myself.
It seems to be caused by this line in CForm:
if($element->getVisible())
{
...
}
The getVisible checks the active validators for this current model scenario and leaves out any inputs that aren't used in the current validator rules. I've ended up commenting things out in our custom CForm model for our system, but if let me know if you find something that works better for you.

Issue has been posted on github
https://github.com/yiisoft/yii/issues/2089

Related

Making a dynamic Form in Prestashop

What I want to achieve Image! Hi I am working on a module in prestashop. What I want is that there should be a button (any-name: Add new field) in the backoffice-(Module Configuration page the first page that comes when you configure your module) that the user presses and it should add a new input field in the form. This all should be done using the helper classes. How can I achieve that? Some code would be grateful! I have uploaded an image. I have tried it using jQuery and it works but I need this done using helperForms in prestashop! In jQuery if I press the add new field button it adds an input field dynamically but the helper-classes are not used in that case.
Here is a link to the documentation :
http://doc.prestashop.com/display/PS16/Using+the+Helper+classes
the documentation is for PS 1.6 but it should also work with PS 1.7
Here is an example of code that generate a form with Helper Classes :
$this->fields_form = array(
'legend' => array(
'title' => $this->l('Edit carrier'),
'image' => '../img/admin/icon_to_display.gif'
),
'input' => array(
array(
'type' => 'text',
'name' => 'shipping_method',
),
),
'submit' => array(
'title' => $this->l('Save'),
'class' => 'btn btn-default pull-right'
)
);
I don’t know if you can use Helper class for custom forms that update custom datas. I’m sure you can use them to update module configuration and prestashop object (customer, etc.)
Helper classes enable you to generate standard HTML elements for the
back office as well as for module configuration pages.

Yii The view file does not exist - where do mail layouts go

I am using basic template but have adapted the advanced user password reset functionality, for some reason I can't get it to find the mail layouts.
So in \mail\layouts I have
- passwordResetToken-html.php
- passwordResteToken-text.php
In web.php I have
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'viewPath' => 'app\mail\layouts',
...
The advanced template uses
'viewPath' => '#common/mail',
But as i'm using basic template, its not in the common/mail folder.
In sendMail function in PasswordResetRequestForm.php i have
return \Yii::$app->mailer->compose(['html' => 'passwordResetToken-html', 'text' => 'passwordResetToken-text'], ['user' => $user])
...
However getting error
The view file does not exist: app\mail\layouts\passwordResetToken-html.php
I know this is going to be something small but for the life of me i cannot see it
Removed the 'viewPath' of config, as the doc don't use it.
So it works.

Prevent Yii from loading JS out of assets

Is there a way to configure Yii such that it will no longer load any Javascript out of the Assets folder?
Make your own AssetManager or extend current
protected/components/DummyAssetManager.php:
class DummyAssetManager extends CApplicationComponent {
public function publish(){}
}
add into components array in
protected/config/main.php:
'assetManager'=>array(
'class'=>'DummyAssetManager',
),
You should consult the manual for a detailed description of
the assetManager options
I think you can try following option in your config/main.php
'components' => array(
'assetManager' => array(
'linkAssets' => true,
),
),
This will make asset files symbolic links to your original js/css sources. See linkAssets for more details on it.
If your PHP<5.3, or the OS it's running on doesn't support symbolic links, you won't be able to use 'linkAssets' option, in this case you can try:
'components' => array(
'assetManager' => array(
'forceCopy' => true,
),
),
This should update asset folder on every request. These two options are usually used during development process (btw, you can't use both) and should be removed from production.
PS: if you're sure that you haven't explicitly enabled ckeditor somewhere in your code and you're confident about your assetmanager calls throughout the code, check your layout and page for widgets that require this CKeditor, as Yii can't preload 'stuff' just randomly, it can be triggered by some preloaded component/extension or yii widget.

enabling layout disables cjuidatepicker yii

I have a small view which renders cjuidatepicker widget.
$this->widget('zii.widgets.jui.CJuiDatePicker', array(
'flat'=>FALSE,
// 'model' => $model,
'attribute' => 'start_date',
// 'value' => $model->start_date,
'name'=>'dateSelect',
'options' => array(
'showButtonPanel' => true,
'changeYear' => true,
'dateFormat' => 'yy-mm-dd',
),
));?>
while this renders nicely without using a layout, but when I put this view in my project layout, the datepicker refuses to show up.
I have no ideas where to look for this, all the css and js are loading similarly in layout and without layout.
Any help would be greatly appreciated.
Thanks
Having dealt my fair share with the datepicker, I'm willing to bet money on that the root to your problem is an error in your javascript. Try to comment out all included javascript in your layout and see what happens. For example, maybe you have jQuery included twice, or some code section missing a closing bracket. Basically any js error will throw datepicker off it's game. Just check the js console in your favorite browser.
I had multiple versions of jquery being loaded and that created quite a mess. Yii jquery was different from the template jquery version being used. Brought both of them to an agreement and boom!!

Using Elfinder extension in Yii

I need to use a file manager in pop up which comes on a button click. I am using Yii extension elfinder. I am finding it hard to understand the way of using it. I downloaded the code from bitbucket, put it inside my application in the folder extension. I try to test it using new controller, named it elfcontroller and put the following code (got from the website)
class ElfinderController extends CController
{
public function actions()
{
return array(
'connector' => array(
'class' => 'ext.elFinder.ElFinderConnectorAction',
'settings' => array(
'root' => Yii::getPathOfAlias('webroot') . '/uploads/',
'URL' => Yii::app()->baseUrl . '/uploads/',
'rootAlias' => 'Home',
'mimeDetect' => 'none'
)
),
);
}
}
and i created one more function for rendering the index page(i want the file manager to be in this page)
in the view i wrote the following code
$model = new xxxmodel();
$this->widget('ext.elFinder.ElFinderWidget', array(
'model' => $model,
'attribute' => 'serverFile',
'connectorRoute' => 'admin/elfinder/connector',
)
);
and i included a div for containing it
But i am getting the following error
Alias "ext.elFinder.ElFinderWidget" is invalid. Make sure it points to an existing PHP file and the file is readable.
i tried to include alias in config/main.php
I know i am messing some where with the folder structure
here is the path i am using the extension
C:\xampp\htdocs\project\protected\extensions\ext.elfinder
I returned empty after google searches, can any one please explain me how to use this extension to place the code exactly where it is needed to be?
In general the extensions folder already has the ext alias, so you don't need to set an alias for it.
Then the extension itself should be placed in the extensions folder, somewhat like : project/extensions/extension-name/ . In your case it should be: project\extensions\elFinder , and keep the rest of your code same, i.e continue referring to extension like:
ext.elFinder.ElFinderWidget