Yii2: Upload Image Using Kartik/Fileinput Plugin
I Want to Upload an Image via Kartik Widget. After Submitting the Form, the $_File['Product'] Has the Data About the Image but getInstance($model, 'Images')...
I want to upload an image via Kartik widget. After submitting the form, the $_FILE['Product'] has the data about the image but getInstance($model, 'images') returns null. Tried with images[], also null.
This is what I'm trying to var_dump in the controller:
public function actionCreate()
{
$model = new Product();
if ($model->load(Yii::$app->request->post())) {
var_dump(UploadedFile::getInstance($model, 'images[]'));die;
And this is my model Product:
<?php
namespace app\models;
use backend\models\CActiveRecord;
use Yii;
use omgdef\multilingual\MultilingualQuery;
use omgdef\multilingual\MultilingualBehavior;
use yii\web\UploadedFile;
/**
* This is the model class for table "product".
*
* @property int $id
* @property int $category_id
* @property int $quantity
* @property double $price
* @property int $sort
*
* @property Productlang[] $productlangs
*/
class Product extends CActiveRecord
{
public $images;
public static function find()
{
return new MultilingualQuery(get_called_class());
}
public function behaviors()
{
$allLanguages = [];
foreach (Yii::$app->params['languages'] as $title => $language) {
$allLanguages[$title] = $language;
}
return [
'ml' => [
'class' => MultilingualBehavior::className(),
'languages' => $allLanguages,
//'languageField' => 'language',
//'localizedPrefix' => '',
//'requireTranslations' => false',
//'dynamicLangClass' => true',
//'langClassName' => PostLang::className(), // or namespace/for/a/class/PostLang
'defaultLanguage' => Yii::$app->params['languageDefault'],
'langForeignKey' => 'product_id',
'tableName' => "{{%productLang}}",
'attributes' => [
'title',
'description',
'meta_title',
'meta_desc',
'url'
]
],
];
}
/**
* @inheritdoc
*/
public static function tableName()
{
return 'product';
}
/**
* @inheritdoc
*/
public function rules()
{
$string = $this->multilingualFields(['description', 'url']);
$string_59 = $this->multilingualFields(['meta_title']);
$string_255 = $this->multilingualFields(['meta_desc', 'title']);
$string[] = 'description';
$string[] = 'url';
$string_59[] = 'meta_title';
$string_255[] = 'meta_desc';
$string_255[] = 'title';
return [
[['quantity', 'price', 'title', 'meta_title', 'meta_desc'], 'required'],
[['category_id', 'quantity', 'sort'], 'integer'],
[$string, 'string'],
[$string_59, 'string', 'max' => 59],
[$string_255, 'string', 'max' => 255],
[['price'], 'number'],
['images', 'file']
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'category_id' => 'Category ID',
'quantity' => 'Quantity',
'price' => 'Price',
'sort' => 'Sort',
];
}
public function upload()
{
if ($this->validate()) {
foreach ($this->image as $file) {
$file->saveAs(\Yii::getAlias("@images") . "/products/" . $this->id . "_" . $this->image->baseName . '.' . $this->image->extension);
}
return true;
} else {
return false;
}
}
}
Tried with rules ['images', 'safe'] also ['images', 'file'] ( think the second one is not right because the attribute is an array, right ? ). The form is <?php $form = ActiveForm::begin(['options' => ['multipart/form-data']]); ?>.
Finally my input:
<?= $form->field($model, 'images[]')->widget(FileInput::class, [
'showMessage' => true,
]) ?>
Full controller action:
public function actionCreate()
{
$model = new Product();
if ($model->load(Yii::$app->request->post())) {
foreach (Yii::$app->params['languages'] as $language){
if(Yii::$app->params['languageDefault'] != $language){
$title_lang = "title_$language";
$model->$title_lang = Yii::$app->request->post('Product')["title_$language"];
$description_lang = "description_$language";
$model->$description_lang = Yii::$app->request->post('Product')["description_$language"];
$meta_title_lang = "meta_title_$language";
$model->$meta_title_lang = Yii::$app->request->post('Product')["meta_title_$language"];
$meta_desc_lang = "meta_desc_$language";
$model->$meta_desc_lang = Yii::$app->request->post('Product')["meta_desc_$language"];
}
}
if($model->save()){
$model = $this->findModel($model->id, true);
//Make urls
foreach (Yii::$app->params['languages'] as $language) {
if (Yii::$app->params['languageDefault'] != $language) {
$url_lang = "url_$language";
$title_lang = "title_$language";
$model->$url_lang = $model->constructURL(
$model->$title_lang,
$model->id
);
}else{
$model->url = $model->constructURL(
$model->title,
$model->id
);
}
}
//Upload Images
$model->images = UploadedFile::getInstance($model, 'images');
if (!($model->upload())) {
Yii::$app->session->setFlash('error', Yii::t('app', 'Some problem with the image uploading occure!'));
return $this->redirect(['create']);
}
if($model->update() !== false){
return $this->redirect(['view', 'id' => $model->id]);
}else{
Yii::$app->session->setFlash('error', Yii::t('app', 'Something went wrong. Please, try again later!'));
return $this->redirect(['create']);
}
}
}
return $this->render('create', [
'model' => $model,
]);
}
1 Answer
What looks like you are trying to upload a single image you should remove the [] from the input field name from the ActiveForm field declaration, and from models rules.
Must Read
Single File
<?= $form->field($model, 'images')->widget(FileInput::class, [
'showMessage' => true,
'pluginOptions' => [
'showCaption' => false ,
'showRemove' => false ,
'showUpload' => false ,
'showPreview' => false ,
'browseClass' => 'btn btn-success btn-block' ,
'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ' ,
'browseLabel' => 'Select Profile Image'
] ,
'options' => ['accept' => 'image/*' ] ,
]) ?>
and from the following line
UploadedFile::getInstance($model, 'images');