2

I have followed different implementation of file/image upload in Yii 2. One of which is from Kartik's widgets, which is in here: http://demos.krajee.com/widget-details/fileinput

In my view, _form.php:

<div class="col-sm-8">
   <?php
      // A block file picker button with custom icon and label
      echo FileInput::widget([
                    'model' => $model,
                    'attribute' => 'image',
                    'options' => ['multiple' => true],
                    'pluginOptions' => [
                        'showCaption' => false,
                        'showRemove' => false,
                        'showUpload' => false,
                        'browseClass' => 'btn btn-primary btn-block',
                        'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ',
                        'browseLabel' =>  'Upload Receipt'
                    ],
                    'options' => ['accept' => 'image/*']
                ]);
   ?>
</div>

I only showed you a part of my view. That image upload block is accompanied with other fields like Customer Name, Date From and To, Product Name, etc and a Submit button.

I also have models and controllers generated already.

Part of my controller is this:

   public function actionCreate()
   {
      $model = new Invoice();
      if ($model->load(Yii::$app->request->post()) && $model->save()) {
         return $this->redirect(['view', 'id' => $model->inv_id]);
      } 
      else {
         return $this->render('create', [
             'model' => $model,
         ]);
      }
   }

I have not added anything yet in my actionCreate because I still don't have any idea. And in Kartik's file upload demo, there are no controllers involved or shown.

How do I save the URL/path of the image I chose to upload in my database, and save that image locally?

Edit:

Regarding @arogachev's answer, here's what my afterSave looks like in my model, but still the image path is not saved in my db:

    public function afterSave($insert, $changedAttributes)
    {
        if(isset($this->image)){
            $this->image = UploadedFile::getInstance($this,'image');
        if(is_object($this->image)){
            $name = Yii::$app->basePath . 'C:\wamp3\www\basicaccounting\web\uploads';  //set directory path to save image
            $this->image->saveAs($name.$this->inv_id."_".$this->image);   
            $this->image = $this->inv_id."_".$this->image;    //appending id to image name            
        Yii::$app->db->createCommand()
                  ->update('invoice', ['image' => $this->image], 'inv_id = "'.$this->inv_id.'"')
                  ->execute(); //manually update image name to db
            }
        }
    }
1
  • you misunderstood my variable $name its just a path to a folder where we store img. Edited my ans.. print the output of each variable and see where u did mistake. Commented Feb 10, 2015 at 10:38

3 Answers 3

1

Use the below aftersave in your model

public function afterSave($insert, $changedAttributes)
{
    if(isset($this->logo)){
        $this->logo=UploadedFile::getInstance($this,'logo');
    if(is_object($this->logo)){
        $path=Yii::$app->basePath . '/images/';  //set directory path to save image
        $this->logo->saveAs($path.$this->id."_".$this->logo);   //saving img in folder
        $this->logo = $this->id."_".$this->logo;    //appending id to image name            
    \Yii::$app->db->createCommand()
              ->update('organization', ['logo' => $this->logo], 'id = "'.$this->id.'"')
              ->execute(); //manually update image name to db
        }
    }
}

replace the above logo with your own attribute. ie. image

Sign up to request clarification or add additional context in comments.

2 Comments

hi. thanks for this but it's not working. I edited my question, I put the afterSave in my model.
Why do you want to save the full path of image to db? Saving image name is enough.. If you save full path it wud b an headache for you while uploading it to server.
0

Try given below -

In your Controller

if($model->image = UploadedFile::getInstance($model, 'image'))
{
    if ($model->upload())
    {
    // file is uploaded successfully
    }
}    

In your Model

public function upload()
{
    $path = \Yii::$app->params['basepath'];
    if (!is_dir($path)) {
    $image_path = BaseFileHelper::createDirectory($path,0777,true);
    }
    $this->image->saveAs($path . date('Y').'/'.date('m').'/'.date('d').'/'.$this->image->baseName . '.' . $this->image->extension);
    $this->image = date('Y').'/'.date('m').'/'.date('d').'/'.$this->image->baseName . '.' . $this->image->extension; // Assign image path to store in Database column (image).
    return true;
}

Your image will be save on server as "$path . date('Y').'/'.date('m').'/'.date('d').'/'.$this->image->baseName . '.' . $this->image->extension". and in the database it will be save as "date('Y').'/'.date('m').'/'.date('d').'/'.$this->image->baseName . '.' . $this->image->extension".

Comments

0

In form

<?= $form->field($model, 'images[]')->widget(FileInput::classname(), [
       'options' => ['accept' => 'image/*', 'multiple' => true],
       'pluginOptions' => [
           'previewFileType' => 'image',
           'allowedFileExtensions' => ['jpg', 'gif', 'png', 'bmp','jpeg'],
           'showUpload' => true,

           'overwriteInitial' => true,

       ],
   ]);
?>

In Model

public $images;
 public function rules()
{
    return [
        [['name', 'price'], 'required'],
        [['price'], 'integer'],
        [['images'],'file', 'maxFiles' => 4],
        [['name'], 'string', 'max' => 100],
    ];
}

In Controller

public function actionCreate()
{
    $model = new Product();
         if ($model->load(Yii::$app->request->post())) {
            $model->save();

                $file = UploadedFile::getInstances($model, 'images');
                       foreach ($file as $file) {
                        $path =Yii::getAlias('@frontend').'/uploads/'.$file->name;
                          $file->saveAs($path);

            }

        return $this->redirect(['view', 'id' => $model->id]);
    }

    return $this->render('create', [
        'model' => $model,
    ]);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.