Quantcast
Viewing all articles
Browse latest Browse all 5

Upload file in Yii 2 using FileInput widget

Are you planning to upload files in your webapp using the enhanced \kartik\widgets\FileInput widget, and not sure how to proceed further? Then read on.

Note

For advanced usage of using the FileInput widget for upload preview, update, and delete, read this follow-up web tip.

About FileInput

The FileInput widget is based on the bootstrap-fileinput plugin by Krajee. Let’s begin, but before we do that, do understand that the FileInput widget will only work with Yii Framework 2.0. This article extends and enhances a similar wiki for Yii 1.x for Yii 2.0 with usage of the FileInput widget. Here are the simple steps for you to configure the widget for upload:

Model

You must have an attribute declared to store the file name in the model class. The model class can extend either yii\base\Model or yii\db\ActiveRecord). Usually, it is good to declare a file validation rule for this attribute to ensure a file is uploaded with specific extension name. You can store the model class in any of these places for the Yii2 advanced app: app\models, backend\models, frontend\models, or common\models. Let’s say you have a model call Person as shown below, and you wish to upload an image file in an attribute named avatar and you have another field filename to store the source file name. Create a temporary attribute named image to get the uploaded file.

namespace common\models;

use yii\db\ActiveRecord;

/**
* Class Person
* @package common\models
* @package common\models
* @property int $id unique person identifier
* @property string $name person / user name
* @property array $avatar generated filename on server
* @property string $filename source filename from client
*/
class Person extends ActiveRecord
{
    /**
    * @var mixed image the attribute for rendering the file input
    * widget for upload on the form
    */
    public $image;

    public function rules()
    {
        return [
            [['image'], 'safe'],
            [['image'], 'file', 'extensions'=>'jpg, gif, png'],
        ];
    }
}

You can add others validation parameters as described in FileValidator. For instance, one can add a maxSize restriction (the PHP ini settings will of course prevail).

Controller

The upload path for your files is important. Its recommended you save it in a global parameter like Yii::$app->params['uploadPath']. For example:

Yii::$app->params['uploadPath'] = Yii::$app->basePath . '/uploads/';

Next setup your controller action for upload.

use Yii;
use common\models\Person;
use yii\web\UploadedFile;

class PersonController extends \yii\web\Controller
{
    public function actionCreate()
    {
        $model = new Person;
        if ($model->load(Yii::$app->request->post())) {
            // get the uploaded file instance. for multiple file uploads
            // the following data will return an array
            $image = UploadedFile::getInstance($model, 'image');

            // store the source file name
            $model->filename = $image->name;
            $ext = end((explode(".", $image->name)));

            // generate a unique file name
            $model->avatar = Yii::$app->security->generateRandomString().".{$ext}";

            // the path to save file, you can set an uploadPath
            // in Yii::$app->params (as used in example below)
            $path = Yii::$app->params['uploadPath'] . $model->avatar;

            if($model->save()){
                $image->saveAs($path);
                return $this->redirect(['view', 'id'=>$model->_id]);
            } else {
                // error in saving model
            }
        }
        return $this->render('create', [
            'model'=>$model,
        ]);
    }
}

View

Edit your _form.php or your other view file where you are rendering the create and image upload form.

use kartik\widgets\ActiveForm; // or yii\widgets\ActiveForm
use kartik\widgets\FileInput;
// or 'use kartik\file\FileInput' if you have only installed 
// yii2-widget-fileinput in isolation

$form = ActiveForm::begin([
    'options'=>['enctype'=>'multipart/form-data'] // important
]);
echo $form->field($model, 'filename');

// your fileinput widget for single file upload
echo $form->field($model, 'image')->widget(FileInput::classname(), [
    'options'=>['accept'=>'image/*'],
    'pluginOptions'=>['allowedFileExtensions'=>['jpg','gif','png']
]);

/**
* uncomment for multiple file upload
*
echo $form->field($model, 'image[]')->widget(FileInput::classname(), [
    'options'=>['accept'=>'image/*', 'multiple'=>true],
    'pluginOptions'=>['allowedFileExtensions'=>['jpg','gif','png']
]);
*
*/
echo Html::submitButton($model->isNewRecord ? 'Upload' : 'Update', [
    'class'=>$model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']
);
ActiveForm::end();

And thus, you should now be able to check your uploaded files in the path as set in Yii::$app->params['uploadPath']. In case you are using multiple file input, the $image variable in controller will return an array of files, which you must loop through. Its important for multiple file uploads to follow an array naming convention as mentioned in this web tip.

The post Upload file in Yii 2 using FileInput widget appeared first on Krajee Web Tips.


Viewing all articles
Browse latest Browse all 5

Trending Articles