Commit beca637d by Alexander Makarov

Adjusted file upload guide wording

parent 63fb997c
...@@ -3,8 +3,14 @@ Uploading Files ...@@ -3,8 +3,14 @@ Uploading Files
> Note: This section is under development. > Note: This section is under development.
First you need to create a model that will handle the form of download the file Uploading files in Yii is done via form model, its validation rules and some controller code. Let's review what's needed
------------------------------------------------------------------------------- to handle uploads properly.
Form model
----------
First of all, you need to create a model that will handle file upload. Create `models/UploadForm.php` with the following
content:
```php ```php
namespace app\models; namespace app\models;
...@@ -34,11 +40,13 @@ class UploadForm extends Model ...@@ -34,11 +40,13 @@ class UploadForm extends Model
} }
``` ```
In this code, we created a model `UploadForm` with an attribute `$file` that will be is `<input type="file">` in upload In the code above, we created a model `UploadForm` with an attribute `$file` that will become `<input type="file">` in
form and pointed out to him validation rule `file`. This rule is [[yii\validators\FileValidator|FileValidator]]. the HTML form. The attribute has the validation rule named `file` that uses [[yii\validators\FileValidator|FileValidator]].
Form view
---------
Secondly create a view for our model Next create a view that will render the form.
------------------------------------
```php ```php
<?php <?php
...@@ -53,11 +61,13 @@ $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ...@@ -53,11 +61,13 @@ $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]);
<?php ActiveForm::end(); ?> <?php ActiveForm::end(); ?>
``` ```
It is different attribute `'enctype' => 'multipart/form-data'` from the standard form. This value is required when you The `'enctype' => 'multipart/form-data'` is important since it allows file uploads. `fileInput()` represents a form
are using forms that have a file upload control. `fileInput()` represents a form input field. input field.
Thirdly, that create the controller that will connect our form and model Controller
------------------------------------------------------------------------ ----------
Now create the controller that connects form and model together:
```php ```php
namespace app\controllers; namespace app\controllers;
...@@ -86,32 +96,31 @@ class SiteController extends Controller ...@@ -86,32 +96,31 @@ class SiteController extends Controller
} }
``` ```
The difference here from the standard crud action, so use `UploadedFile::getInstance(...)` instead `model->load(...)`. Instead of `model->load(...)` we are using `UploadedFile::getInstance(...)`. [[\yii\web\UploadedFile|UploadedFile]]
[[\yii\web\UploadedFile|UploadedFile]] does not run the model validation, it only provides information about the uploaded does not run the model validation. It only provides information about the uploaded file. Therefore, you need to run
file. Therefore, you need to run validation manually `$model->validate()`. This triggers the validation manually via `$model->validate()`. This triggers the [[yii\validators\FileValidator|FileValidator]] that
[[yii\validators\FileValidator|FileValidator]] that expects a file expects a file:
```php ```php
$file instanceof UploadedFile || $file->error == UPLOAD_ERR_NO_FILE //in code framework $file instanceof UploadedFile || $file->error == UPLOAD_ERR_NO_FILE //in code framework
``` ```
If validation done without errors, then save the file If validation is successful, then we're saving the file:
```php ```php
$model->file->saveAs('uploads/' . $model->file->baseName . '.' . $model->file->extension); $model->file->saveAs('uploads/' . $model->file->baseName . '.' . $model->file->extension);
``` ```
If you use "basic" application then forlder `uploads` should be create inside `web` folder. If you're using "basic" application template then folder `uploads` should be created under `web`.
Everything is ready, now run the page and download the file. Check the folder `basic/web/uploads` to make sure that That's it. Load the page and try uploading. Uplaods should end up in `basic/web/uploads`.
you have downloaded.
Additional information Additional information
---------------------- ----------------------
### Required rule ### Required rule
If you need to check the mandatory download the file, then use `skipOnEmpty`. If you need to make file upload mandatory use `skipOnEmpty` like the following:
```php ```php
public function rules() public function rules()
...@@ -122,14 +131,9 @@ public function rules() ...@@ -122,14 +131,9 @@ public function rules()
} }
``` ```
### Path upload folder
Folder to download the file can be installed using `Yii::getAlias('@app/uploads')`. This base path of currently running
application and folder `uploads`.
### MIME type ### MIME type
FileValidator has property `$types` It is wise to validate type of the file uploaded. FileValidator has property `$types` for the purpose:
```php ```php
public function rules() public function rules()
...@@ -140,19 +144,8 @@ public function rules() ...@@ -140,19 +144,8 @@ public function rules()
} }
``` ```
it pulls The thing is that it validates only file extension and not the file content. In order to validate content as well use
`mimeTypes` property of `ImageValidator`:
```php
in_array(strtolower(pathinfo($file->name, PATHINFO_EXTENSION)), $this->types, true))
```
As you can see, the name of the expansion may be one and the file type - other, actually.
`UploadedFile::getInstance()->type` also do not take this value for granted. Instead, use
[[\yii\helpers\BaseFileHelper|FileHelper]] and his [[FileHelper::getMimeType()]] to determine the exact MIME type.
If allowed to **load only the images**, using [[\yii\validators\ImageValidator|ImageValidator]] instead
[[yii\validators\FileValidator|FileValidator]].
```php ```php
public function rules() public function rules()
...@@ -163,12 +156,9 @@ public function rules() ...@@ -163,12 +156,9 @@ public function rules()
} }
``` ```
`ImageValidator` use use `yii\helpers\FileHelper;` for check mime types. ### Uploading multiple files
[List Mime types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)
### Multiple files uploader
If you need download multiple files, you will need to alter slightly the controller and view. At first view: If you need download multiple files at once some adjustments are required. View:
```php ```php
<?php <?php
...@@ -190,22 +180,13 @@ if ($model->hasErrors()) { //it is necessary to see all the errors for all the f ...@@ -190,22 +180,13 @@ if ($model->hasErrors()) { //it is necessary to see all the errors for all the f
<?php ActiveForm::end(); ?> <?php ActiveForm::end(); ?>
``` ```
In fact the only difference is in the one row. The difference is the following line:
```php ```php
<?= $form->field($model, 'file[]')->fileInput(['multiple' => '']) ?> <?= $form->field($model, 'file[]')->fileInput(['multiple' => '']) ?>
``` ```
instead Controller:
```php
<?= $form->field($model, 'file')->fileInput() ?>
```
* `['multiple' => '']` - HTML <input> multiple Attribute
* `file[]` vs `file` - need, otherwise UploadedFile sees only one file
We now turn to the controller
```php ```php
namespace app\controllers; namespace app\controllers;
...@@ -254,8 +235,5 @@ class SiteController extends Controller ...@@ -254,8 +235,5 @@ class SiteController extends Controller
} }
``` ```
Here the differences in: The difference is `UploadedFile::getInstances($model, 'file');` instead of `UploadedFile::getInstance($model, 'file');`.
Former returns instances for **all** uploaded files while the latter gives you only a single instance.
* `UploadedFile::getInstances($model, 'file');` instead `UploadedFile::getInstance($model, 'file');`. First returns
**all** uploaded files for the given model attribute, second - one.
* All other differences follow from the first.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment