Yii2 FileInput - Trying to get property of non object - php

i am using Yii2 and Kartik's FileInput extension and I have successfully get the file uploads working(only single upload). My problem now is that, I get the error as in the title(with logs attached) if I did not choose any files(It should be optional).
After much searching over the internet, I think it has to be something to do with array, but I am not sure how to fix that, especially even with the logs pointing to the exact line!
Here is my log,
Here is my model,
namespace app\models;
use Yii;
class FormMovement extends \yii\db\ActiveRecord
{
public $file;
public static function tableName()
{
return 'form_movement';
}
public function rules()
{
return [
[['fm_date_received', 'fm_form_name', 'fm_from', 'fm_ptj'], 'required'],
[['form_id'], 'integer'],
[['fm_date_received', 'fm_date_action1', 'fm_date_action2','fm_upload'], 'safe'],
[['fm_form_name', 'fm_note'], 'string', 'max' => 500],
[['fm_from', 'fm_ptj', 'fm_action1', 'fm_action2'], 'string', 'max' => 100],
[['file'], 'file', 'skipOnEmpty' => true, 'extensions'=>'jpg,pdf,png,doc,docx,xls,xlsx, jpeg', 'maxFiles' => 3],
];
}
My controller function, the log shows that it is at the line 75, which is this one,
$model->fm_upload='uploads/'.$fileName.'.'.$model->file->extension;
Been tinkering with it, but no success.
public function actionCreate()
{
$model = new FormMovement();
if ($model->load(Yii::$app->request->post())) {
//set the file name
$fileName = $model -> fm_form_name;
//get instance
$model->file = UploadedFile :: getInstance($model, 'file');
//set the file path in the db
$model->fm_upload='uploads/'.$fileName.'.'.$model->file->extension;
//save the file to the server directory
$model->save();
$model->file->saveAs('uploads/'.$fileName.'.'.$model->file->extension);
return $this->redirect(['view', 'id' => $model->form_id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
Finally my view,
<div class="form-group kv-fieldset-inline">
<?= Html::activeLabel($model, 'file[]', [
'label'=>'MUAT NAIK FAIL',
'class'=>'col-sm-1 control-label'
]) ?>
<div class="col-sm-8">
<?= $form->field($model, 'file',[
'showLabels'=>false
])->widget(FileInput::classname(), [
'options' => ['accept' => 'file/*', 'multiple' => 'true'],
'pluginOptions'=>[
'showUpload' => false,
]
]) ?>
</div>
</div>

This part should be refactored:
//set the file name
$fileName = $model -> fm_form_name;
//get instance
$model->file = UploadedFile :: getInstance($model, 'file');
//set the file path in the db
$model->fm_upload='uploads/'.$fileName.'.'.$model->file->extension;
//save the file to the server directory
$model->save();
$model->file->saveAs('uploads/'.$fileName.'.'.$model->file->extension);
like this:
$model->file = UploadedFile::getInstance($model, 'file');
$model->save();
if ($model->file) {
$model->fm_upload = "uploads/{$model->fm_form_name}.{$model->file->extension}";
$model->file->saveAs("uploads/{$model->fm_form_name}.{$model->file->extension}");
}
Also note that you don't handle failed validation in your controller at all.
For further refactoring, this line:
$model->file = UploadedFile::getInstance($model, 'file');
can be moved to beforeValidate() event handler.
This part:
if ($model->file) {
$model->fm_upload = "uploads/{$model->fm_form_name}.{$model->file->extension}";
$model->file->saveAs("uploads/{$model->fm_form_name}.{$model->file->extension}");
}
can be moved to afterSave() event handler to keep your controller slim.
In saveAs() it's better to use alias, I desribed it in this answer.

Related

Value not updated in databases after validation and save success

Hi everyone i'm having trouble with my software developed with yii2.
I Have a model called Anagrafica and with its primary key id. With this model everything works.
I also have a model called AnagraficaOpzioniCarriera which extend the first one.
I have a view anagrafica/index that show a Kartik grid with the data of people enrolled that you can find in anagrafica. Admin user can update the data of an Anagrafica model by clicking on an the attribute "cognome" that render to anagrafica/update.
this is the command that call the controller AnagraficaController to reach anagrafica/update
'cognome'=>Grid::Labels('cognome',['anagrafica/update'],\app\helpers\Permits::allow('anagrafica','update'),'id','btn','info','10%'),
This is AnagraficaController
public function actionUpdate($id,$error=0,$message='')
{
$id = (int)$id;
$model = Anagrafica::findOne(['id' => $id]);
$model->scenario = 'update';
if ($model->load(Yii::$app->request->post())) {
if($model->validate()){
}
if($model->save(false)){
return $this->redirect(['anagrafica/update','id'=>$model->id]);
}
}
}
return $this->render('update', ['model' => $model, 'extended'=>true]);
}
i removed some portions of code to semplify it, but this is the core.
One time the view anagrafica/update is reached in this page i have an ActiveForm to modify data of the model and i have a render to a grid that show the attributes contained in AnagraficaOpzioniCarriera about the $model that i'm updating.
<?= $this->render('_opzioni_carriera',['parent'=>$model]); ?>
anagrafica/_opzioni_carriera view contain a Kartik grid that shows the column in the model AnagraficaOpzioniCarriera
<?php
use kartik\grid\GridView;
use kartik\select2\Select2;
use kartik\widgets\ActiveForm;
use kartik\editable\Editable;
use kartik\widgets\SwitchInput;
use yii\helpers\ArrayHelper;
use app\helpers\Autoconfigurazione;
use app\models\AnagraficaOpzioniCarriera;
use app\helpers\Grid;
use yii\helpers\Html;
use app\helpers\UserInfo;
/* #var $this yii\web\View */
/* #var $model app\models\AnagraficaOpzioniCarriera*/
$model = new AnagraficaOpzioniCarriera(['scenario'=>'search']);
?>
<div class="">
<?php
echo GridView::widget([
'options'=>[
'id'=>'opzioni_carriera',
],
'dataProvider'=> $model->search($parent->id,Yii::$app->request->queryParams),
'showPageSummary'=>false,
'headerRowOptions'=>['class'=>'kartik-sheet-style'],
'pjax'=>true, // pjax is set to always true for this demo
'pjaxSettings'=>[
'neverTimeout'=>true,
],
'toolbar'=> [
[
'content'=>''
],
],
'panel'=>[
'heading'=>false,
'footer'=>false,
'after'=>false,
],
'columns' => Grid::gridColumns([
'model'=>$model,
'checkbox'=>false,
'remove'=>Grid::gridRemove($model),
'extraOptions' =>[
'cashback' =>Grid::YNColumn('cashback',['anagrafica-opzioni-carriera/update', 'id' => $parent->id],'left',true,'5%'),
'compensa'=>Grid::YNColumn('compensa',['anagrafica-opzioni-carriera/update', 'id' => $parent->id],'left',true,'5%'),
'associazione'=>Grid::YNColumn('associazione',['anagrafica-opzioni-carriera/update', 'id' => $parent->id],'left',true,'5%'),
'formazione'=>Grid::YNColumn('formazione',['anagrafica-opzioni-carriera/update', 'id' => $parent->id],'left',true,'5%'),
],
]);
?>
</div>
cashback, compensa etc.. are the attributes in the model AnagraficaOpzioniCarriera.
Here when i try to update this attributes everything looks fine, the function model->validate() and model->load returns true value, but at the end of the process doesn't works.
Honestly i don't know what i have to return from the function of the controller.
public function actionUpdate($id)
{
$model = AnagraficaOpzioniCarriera::findOne(['id_anagrafica' => $id]);
if (!$model) {
// Se l'anagrafica opzioni carriera non esiste, genera un'eccezione 404
throw new \yii\web\NotFoundHttpException(Yii::t('app', 'The requested page does not exist.'));
}
$model->scenario = 'update';
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
if(Yii::$app->request->post('cashback') != null) $model->cashback = Yii::$app->request->post('cashback');
if(Yii::$app->request->post('compensa') != null) $model->cashback = Yii::$app->request->post('compensa');
if(Yii::$app->request->post('associazione') != null) $model->cashback = Yii::$app->request->post('associazione');
if(Yii::$app->request->post('formazione') != null) $model->cashback = Yii::$app->request->post('formazione');
if ($model->save()) {
return Json::encode(["success" => true, 'message' => 'Dati aggiornati']);
}
}
// Mostra il form di modifica
return $this->render('_opzioni_carriera', [
'parent' => $model,
]);
}
anyone can help me? i hope i explained my problem in a good form, but my english is not the best, i know. Anyway thanks in aadvance to everyone who want to try to help me, if you need anything other you can easily ask.
I tried every everything, also a logger but nothing worked
Like someone suggest these are the rules of the model AnagraficaOpzioni, but like i said prevously model->validate() works, for this reason i think the problem is not over there
public function rules()
{
return [
[['id_anagrafica'], 'required'],
[['id_anagrafica'], 'integer'],
[['cashback', 'compensa', 'associazione', 'formazione'], 'required', 'on'=>['update']],
[['cashback', 'compensa', 'associazione', 'formazione'], 'integer'],
[['id_anagrafica', 'cashback', 'compensa', 'associazione', 'formazione',], 'safe', 'on'=>['search']],
];
}

Unable to update file details entries in mysql db using Laminas and Doctrine

I'm able to add file details in database but not able to update it.
I am able to add file details entries, but when i try to update only the file that i am updating is moved to the storage folder. My update manager doesn't show any errors and doesn't update the file details in database.
this is my file form
protected function addElements()
{
// Add "name" field
$this->add([
'type' => 'file',
'name' => 'image',
'attributes' => [
'id' => 'image'
],
'options' => [
'label' => 'ImageFile',
],
]);
// Add the Submit button
$this->add([
'type' => 'submit',
'name' => 'submit',
'attributes' => [
'value' => 'Add Image File',
'id' => 'submit',
],
]);
// Add the CSRF field
$this->add([
'type' => 'csrf',
'name' => 'csrf',
'options' => [
'csrf_options' => [
'timeout' => 600
]
],
]);
}
public function addInputFilter()
{
$inputFilter = new InputFilter\InputFilter();
// File Input
$fileInput = new InputFilter\FileInput('image');
$fileInput->setRequired(true);
$inputFilter->add($fileInput);
$this->setInputFilter($inputFilter);
}
}
this is the update image manager
public function updateImage($name, $size)
{
$images = new Images();
$images->setName($name);
$images->setSize($size);
// Apply changes to database.
$this->entityManager->flush();
}
and this is my controller
public function editAction()
{
$id = (int)$this->params()->fromRoute('id', -1);
if ($id<1) {
$this->getResponse()->setStatusCode(404);
return;
}
$image = $this->entityManager->getRepository(Images::class)
->find($id);
if ($image == null) {
$this->getResponse()->setStatusCode(404);
return;
}
// Create form
$form = new ImageUploadForm('update', $this->entityManager);
$request = $this->getRequest();
if ($this->getRequest()->isPost()) {
$data = array_merge_recursive(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
$form->setData($data);
if($form->isValid()) {
$data = $form->getData();
$imgtmp = $data["image"]["tmp_name"];
$name = $data["image"]["name"];
$size = $data["image"]["size"];
$filepath = $this->_dir.$name;
move_uploaded_file($imgtmp, $filepath);
$this->achimotaImagesManager->updateImage($name, $size);
var_dump($name, $size);
return $this->redirect()->toRoute('images', ['action'=>'index']);
}
}
return new ViewModel([
'form' => $form,
]);
}
Do not create a new object
If you update an Images entity (consider naming it Image if it is one image), you should not create a new one. Hand over the $image you need to update:
public function updateImage($image, $name, $size){
$image->setName($name);
$image->setSize($size);
...
}
Persist before flush
You need to persist the entity before you flush.
$this->entityManager->persist($image);
$this->entityManager->flush();
Organize the code nicer
Do not inject entity manager in your controller. Inject rather a service through a factory, which handles all features of your Image entity. (ImageService.php)
Do not inject entity manager into your ImageService neither. Create a ImageMapper service, inject that into your ImageService. Create all Doctrine-related features in this Mapper. This has this advantage: Doctrin specific functionality is only in your Mapper files. Should you need to use another solution to store data, you only need to replace the Mapper files, providing the Service with the same interface.
Controller
public function editAction()
{
...
$this->serviceImage->update($image,$name,$size);
...
}
Service - ImageService.php
public function update($image,$name,$size)
{
$image->setName($name);
$image->setSize($size);
$this->mapperImage->save($image);
}
Mapper - ImageMapper.php
public function save($image)
{
$this->managerEntity->persist($image);
$this->managerEntity->flush();
}
Consider adding rich comments and typehints to the arguments and return value of the functions.
Moreover
The form should not be created in your controller. Put that code in your ImageService too. And consider inject form into the service. (Make sure you define the form for the factory in the getFormElementConfig()! This is more advance stuff, if you do not test with phpunit, you might not bother creating form as a service, hovever it leads to a very organized codebase.)
var_dump($name, $size) has no place in your controller. (If this is for debug purposes, it is OK, but use rather something like XDebug with a compatible IDE - PHPStorm is far the best one.)
This line is not so easy to understand: $filepath = $this->_dir.$name; Maybe:
$filePath = _dir . $name;
Naming convention: look for camelCase.

Yii 2 How add a custom validation check on file upload

I am building a CSV uploader and I want to add a custom validation function that will check the header row of the CSV file to ensure the correct columns are in place.
I am trying to put a custom validation rule in the model to do this but failing at the first hurdle.
I am getting
Setting unknown property: yii\validators\FileValidator::0
exception but as far as I can tell from the documentation this should work.
Model
/**
* UploadForm is the model behind the upload form.
*/
class UploadForm extends Model
{
/**
* #var UploadedFile file attribute
*/
public $file;
/**
* #return array the validation rules.
*/
public function rules()
{
return [
[['file'], 'file', 'extensions' => 'csv', 'checkExtensionByMimeType'=>false, 'headerCheck', 'skipOnEmpty' => false]
];
}
public function attributeLabels(){
return [
'file'=>'Select csv'
];
}
function headerCheck($attribute, $params, $validato){
$this->addError($attribute, "error");
}
}
Controller function:
public function actionUpload()
{
$model = new UploadForm();
if (Yii::$app->request->isPost) {
$model->file = UploadedFile::getInstance($model, 'file');
$filename = $model->file->baseName . '.' . $model->file->extension;
if ($model->file && $model->validate()) {
$upload = $model->file->saveAs('uploads/'.$filename );
if($upload){
define('CSV_PATH','uploads/');
$csv_file = CSV_PATH . $filename;
$filecsv = file($csv_file);
foreach($filecsv as $data){
$lines = explode(',',$data);
$t=1;
}
}
}
}
return $this->render('csvUpload', ['model' => $model]);
}
View
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
<?= $form->field($model, 'file')->fileInput() ?>
<button>Submit</button>
<?php ActiveForm::end() ?>
Why is headerCheck() not getting picked up as a custom validation function?
Short Answer
Your rules should be written like so:
return [
[['file'], 'file', 'extensions' => 'csv', 'checkExtensionByMimeType'=>false, 'skipOnEmpty' => false],
[["file"], "headerCheck"],
];
Note that your validation rule, "headerCheck", is a separate item in the array.
Long Answer
A rule's structure is like so:
[["attributes_to_validate"],"vaildatorCallback","param1"=>"value","param2"=>"value]
Note the first two items are the attributes and the callback respectively, and then after that you can specify params that should be assigned to the validator, or passed to your validator callback. These params are expected in a form where the key is the name of the property, and the value is the value to assign to the property.
In the example you provided, Yii sees that you want to utilize the "file" validator, so it creates an instance of yii\validators\FileValidator. It then sees that you want the parameter "extensions" set to "csv", so it does:yii\validators\FileValidator::$extensions = "csv"; But then, because you have included your custom validator in this part of the array, it thinks that "headerCheck" is actually a value of a property you want to assign to the validator. Because you have entered this "param" without a key, the key defaults to 0 and so Yii thinks the property you want to assign is called '0'. Thus, Yii attempts this: yii\validators\FileValidator::0 = "headerCheck";
Of course, there is no property '0' on FileValidator, and so that's where the error you're getting is coming from.

yii2 - Kartik file input - update

This is the situation: I'm new on Yii2 and wanted to use some file uploader widget within ActiveForm.. so far I've found this excelent one: \kartik\widget\FileInput
With this widget I can manage file upload and then, when enter in edit mode, show the previous uploaded image with the oportunite to replace it.
The problem is that if I press the "Update" button of the form without modifying the image yii says that the image "can't be empty" because I've set the 'required' rule in my model.
After an awful afternoon and a more productive night, I've encountered a solution that worked for me..
The main problem was that file input don't send its value (name of the file stored in database) when updating. It only sends the image info if browsed and selected through file input..
So, my workaround was creating another "virtual" field for managing file upload, named "upload_image". To achieve this I simple added a public property with this name to my model class: public $upload_image;
I also add the folowing validation to rules method on Model class:
public function rules()
{
return [
[['upload_image'], 'file', 'extensions' => 'png, jpg', 'skipOnEmpty' => true],
[['image'], 'required'],
];
}
Here, 'upload_image' is my virtual column. I added 'file' validation with 'skipOnEmpty' = true, and 'image' is the field on my database, that must be required in my case.
Then, in my view I configured 'upload_image' widget like follows:
echo FileInput::widget([
'model' => $model,
'attribute' => 'upload_image',
'pluginOptions' => [
'initialPreview'=>[
Html::img("/uploads/" . $model->image)
],
'overwriteInitial'=>true
]
]);
In 'initialPreview' option I asign my image name, stored in '$model->image' property returned from database.
Finally, my controller looks like follow:
public function actionUpdate($id)
{
$model = $this->findModel($id);
$model->load(Yii::$app->request->post());
if(Yii::$app->request->isPost){
//Try to get file info
$upload_image = \yii\web\UploadedFile::getInstance($model, 'upload_image');
//If received, then I get the file name and asign it to $model->image in order to store it in db
if(!empty($upload_image)){
$image_name = $upload_image->name;
$model->image = $image_name;
}
//I proceed to validate model. Notice that will validate that 'image' is required and also 'image_upload' as file, but this last is optional
if ($model->validate() && $model->save()) {
//If all went OK, then I proceed to save the image in filesystem
if(!empty($upload_image)){
$upload_image->saveAs('uploads/' . $image_name);
}
return $this->redirect(['view', 'id' => $model->id]);
}
}
return $this->render('update', [
'model' => $model,
]);
}
I have encountered another solution by creating scenarios. In your case I would modify the rules like this:
public funtion rules() {
[['image'], 'file'],
[['image'], 'required', 'on'=> 'create']
}
So the fileupload field will be required only in create action. In update action I have this code:
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post())) {
$newCover = UploadedFile::getInstance($model, 'image');
if (!empty($newCover)) {
$newCoverName = Yii::$app->security->generateRandomString();
unlink($model->cover);
$model->cover = 'uploads/covers/' . $newCoverName . '.' . $newCover->extension;
$newCover->saveAs('uploads/covers/' . $newCoverName . '.' . $newCover->extension);
}
if ($model->validate() && $model->save()) {
return $this->redirect(['view', 'id' => $model->post_id]);
} else {
// error saving model
}
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
In the update scenario the image filed is not required but the code checks if nothing was uploaded and doesn't change the previous value.
My form file:
<?= $form->field($model, 'image')->widget(FileInput::classname(), [
'options' => ['accept'=>'image/*'],
'pluginOptions'=>[
'allowedFileExtensions'=>['jpg', 'gif', 'png', 'bmp'],
'showUpload' => true,
'initialPreview' => [
$model->cover ? Html::img($model->cover) : null, // checks the models to display the preview
],
'overwriteInitial' => false,
],
]); ?>
I think is a little more easier than a virtual field. Hope it helps!
Try preloading the file input field with the contents of that field. This way, you will not lose data after submitting your form.
I looked through kartik file-input widget (nice find, btw) and I came across a way to do this
// Display an initial preview of files with caption
// (useful in UPDATE scenarios). Set overwrite `initialPreview`
// to `false` to append uploaded images to the initial preview.
echo FileInput::widget([
'name' => 'attachment_49[]',
'options' => [
'multiple' => true
],
'pluginOptions' => [
'initialPreview' => [
Html::img("/images/moon.jpg", ['class'=>'file-preview-image', 'alt'=>'The Moon', 'title'=>'The Moon']),
Html::img("/images/earth.jpg", ['class'=>'file-preview-image', 'alt'=>'The Earth', 'title'=>'The Earth']),
],
'initialCaption'=>"The Moon and the Earth",
'overwriteInitial'=>false
]
]);
You may also want to relax the required rule in your model for that field, so it does not complain on validation. You may choose to prompt the user through subtler means.
From Krajee:
http://webtips.krajee.com/advanced-upload-using-yii2-fileinput-widget
Create, delete, update: really easy, look no further.
(1) I've set the 'required' rule in my model too.
(2) To work on Wampserver:
Yii::$app->params['uploadPath'] = Yii::$app->basePath . '/web/uploads/';
Yii::$app->params['uploadUrl'] = Yii::$app->urlManager->baseUrl . '/uploads/';

How to upload a file to directory in yii2?

i have an ActiveForm, and i want to add a field where the user can upload their photos.
the problem is that i don't have an attribute for the image in the users table and every
input field in 'yii' expects a model and an attribute as follows.
<?= $form->field($model, 'attribute')->input($platforms) ?>
i don't want to assign the image to any record nor i want to insert in in the database, i want it to be uploaded to a specific folder.
i have also checked the library kartik wrote, but also requires an attribute field.
Follow the official documentation
https://github.com/yiisoft/yii2/blob/master/docs/guide/input-file-upload.md
Form Model
namespace app\models;
use yii\base\Model;
use yii\web\UploadedFile;
/**
* UploadForm is the model behind the upload form.
*/
class UploadForm extends Model
{
/**
* #var UploadedFile|Null file attribute
*/
public $file;
/**
* #return array the validation rules.
*/
public function rules()
{
return [
[['file'], 'file'],
];
}
}
?>
Form View
<?php
use yii\widgets\ActiveForm;
$form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>
<?= $form->field($model, 'file')->fileInput() ?>
<button>Submit</button>
<?php ActiveForm::end(); ?>
Controller
Now create the controller that connects form and model together:
<?php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\UploadForm;
use yii\web\UploadedFile;
class SiteController extends Controller
{
public function actionUpload()
{
$model = new UploadForm();
if (Yii::$app->request->isPost) {
$model->file = UploadedFile::getInstance($model, 'file');
if ($model->validate()) {
$model->file->saveAs('uploads/' . $model->file->baseName . '.' . $model->file->extension);
}
}
return $this->render('upload', ['model' => $model]);
}
}
?>
Instead of model->load(...) we are using UploadedFile::getInstance(...). [[\yii\web\UploadedFile|UploadedFile]] does not run the model validation. It only provides information about the uploaded file. Therefore, you need to run validation manually via $model->validate(). This triggers the [[yii\validators\FileValidator|FileValidator]] that expects a file:
$file instanceof UploadedFile || $file->error == UPLOAD_ERR_NO_FILE //in code framework
If validation is successful, then we're saving the file:
$model->file->saveAs('uploads/' . $model->file->baseName . '.' . $model->file->extension);
If you're using "basic" application template then folder uploads should be created under web.
That's it. Load the page and try uploading. Uplaods should end up in basic/web/uploads.
in your view
use kartik\widgets\ActiveForm;
use kartik\widgets\FileInput;
$form = ActiveForm::begin(['options' => ['enctype'=>'multipart/form-data']]); //important
echo FileInput::widget([
'name' => 'filename',
'showUpload' => false,
'buttonOptions' => ['label' => false],
'removeOptions' => ['label' => false],
'groupOptions' => ['class' => 'input-group-lg']
]);
echo Html::submitButton('Submit', ['class'=>'btn btn-primary']);
ActiveForm::end();
in your controller
$file = \yii\web\UploadedFile::getInstanceByName('filename');
$file->saveAs('/your/directory/'.$file->name);
Create a read only attribute for your model like public $imageand proceed like
<?= $form->field($model, 'image')->fileInput() ?>
I really like Yii2 Dropzone.
Installation:
composer require --prefer-dist perminder-klair/yii2-dropzone "dev-master"
Usage:
<?php
echo \kato\DropZone::widget([
'options' => [
'url'=> Url::to(['resource-manager/upload']),
'paramName'=>'image',
'maxFilesize' => '10',
],
'clientEvents' => [
'complete' => "function(file){console.log(file)}",
'removedfile' => "function(file){alert(file.name + ' is removed')}"
],
]);
?>
Controller:
public function actionUpload(){
$model = new ResourceManager();
$uploadPath = Yii::getAlias('#root') .'/uploads/';
if (isset($_FILES['image'])) {
$file = \yii\web\UploadedFile::getInstanceByName('image');
$original_name = $file->baseName;
$newFileName = \Yii::$app->security
->generateRandomString().'.'.$file->extension;
// you can write save code here before uploading.
if ($file->saveAs($uploadPath . '/' . $newFileName)) {
$model->image = $newFileName;
$model->original_name = $original_name;
if($model->save(false)){
echo \yii\helpers\Json::encode($file);
}
else{
echo \yii\helpers\Json::encode($model->getErrors());
}
}
}
else {
return $this->render('upload', [
'model' => $model,
]);
}
return false;
}
give this code after your uploaded code
//save the path in DB..
$model->file = 'uploads/'.$imageName.'.'.$model->file->extension;
$model->save();
If you have more than one file while uploading you must use foreach for that. And you should actual name of file in a column in table and a encrypted value of that name has to be stored to avoid duplicated in the directory.. Something like this..
$userdocs->document_name = UploadedFile::getInstances($userdocs, 'document_name');
foreach ($userdocs->document_name as $key => $file) {
$img_name = Yii::$app->security->generateRandomString();
$file->saveAs('user/business_files/' . $img_name . '.' . $file->extension);
$images = $img_name . '.' . $file->extension;
$userdocs->actual_name = $file->name;
$userdocs->user_id = $user->id;
$userdocs->document_name = $images;
$userdocs->save(false);
$userdocs = new UserDocs();
}
Here a random string is generated and it will be assign with the name of the document, and it will be stored in the table. The UserDocs is the model name.

Categories