Yii2 Kartik-v fileiput: Get uploaded images when wrapped in the array of $_FILES instead of $_POST









up vote
0
down vote

favorite












I am developing my app using the yii2-formwizard widget. I have gotten it working fine in all the other parts and even submits a single image perfectly. The problem comes when I try to submit multiple images. I get the $_POST array with form model values and the image model as an empty array inside the $_POST, but then all the image model values are wrapped in an array of $_FILES. How do I go about solving this as I have never dealt with such before? Here are the relevant codes:



_form view



<?php

use yiihelpersHtml;
use kartikwidgetsActiveForm;
use kartikbuilderForm;
use kartikdatecontrolDateControl;
use kartikwidgetsSelect2;
use buttflatteryformwizardFormWizard;
use yiihelpersArrayHelper;
use kartikfileFileInput;

/**
* @var yiiwebView $this
* @var commonmodelsListing $model
* @var yiiwidgetsActiveForm $form
*/
?>

<?php
echo FormWizard::widget([
'theme' => FormWizard::THEME_MATERIAL,
'labelFinish' => 'Submit',
// 'formOptions'=>[
// 'options'=>['enctype'=>'multipart/form-data'],
// ],
'steps' => [
[
'model'=>$listingModel,
'title'=>'Basic',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [
'created_by' => false, //hide a specific field
'updated_at' => false, //hide a specific field
'created_at' => false, //hide a specific field
'expires_on' => false, //hide a specific field
'status' => false, //hide a specific field
'listing_type_id' => false, //hide a specific field
'latitude' => false, //hide a specific field
'longitude' => false, //hide a specific field

'listing_title' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter Listing Title...', 'maxlength' => 50]],

'country' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsCountry::find()->all(), 'country_id', 'country_name'),
'options' => [
'prompt'=>'Select Country',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('listing/select-state?id=').'"+$(this).val(), function( data )
$( "select#state_id" ).html( data );
);
'
]
]
],

'states' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsStates::find()->all(), 'state_id', 'state_name'),
'options' => [
'id'=>'state_id',
'prompt'=>'Select Select the Country First',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('listing/select-area?id=').'"+$(this).val(), function( data )
$( "select#area_code" ).html( data );
);
'
]
]
],

'area_id' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsAreas::find()->all(), 'area_id', 'area_name'),
'options' => [
'prompt'=>'Please Select the State/Region First',
'id' => 'area_code'
],
]
],

'physical_address' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter The Actual Physical Address...', 'maxlength' => 50]],

'neighborhood' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter The Nearby Landmark or Neighbourhood...', 'maxlength' => 50]],

'address' => [
'widget' => kalyabinmaplocationSelectMapLocationWidget::className(),
'options' => [
'attributeLatitude' => 'latitude',
'attributeLongitude' => 'longitude',
'googleMapApiKey' => 'AIzaSyDU30XgKi1ik7wpWteHUENKVH_d09sTqRg',
'draggable' => true,
],
]
]
],
[
'model'=>$model,
'title'=>'Prices and More',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [

// 'only' => ['property_category', 'sub_category_id', 'available_from', 'desc', 'price', 'currency_id', 'price_conditions', 'deposit', 'agent_commission', 'other_payments'],

'only' => ['property_category', 'sub_category_id', 'price', 'currency_id'],

'property_category' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsPropertyCategory::find()->all(), 'category_id', 'category_name'),
'options' => [
'id'=>'state_id',
'prompt'=>'Select Property Category',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('listing/select-property-category?id=').'"+$(this).val(), function( data )
$( "select#sub_category_value" ).html( data );
);
'
]
]
],

'sub_category_id' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsPropertySubCategory::find()->all(), 'sub_category_id', 'name'),
'options' => [
'prompt'=>'Please Select the Property Category First',
'id' => 'sub_category_value'
],
]
],

'currency_id' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsCurrency::find()->all(), 'currency_id', 'title'),
]
],

'price' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter Price...']],
]
],
[
'model'=>$model,
'title'=>'Features',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [
// 'only' => ['beds', 'baths', 'rooms', 'living_area', 'living_size', 'floor', 'total_floors', 'build_year', 'car_spaces', 'fully_furnished', 'property_features'],

'only' => ['property_features'],

'property_features' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsPropertyFeatures::find()->all(), 'feature_id', 'feature_name', 'featuresType.type_name'),
'options' => ['multiple' => true, 'placeholder' => 'Select Property Features ...']
]
],
]
],
[
'model'=>$imageModel,
'title'=>'Images',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [
'only' => ['image'],
'image' => [
'multifield'=>true,
'widget' => FileInput::classname(),
'options' =>[
'options' => [
'multiple' => true,
'accept' => 'image/*',
'pluginOptions' => [
'showCaption' => false,
'showRemove' => false,
'showUpload' => false,
'browseClass' => 'btn btn-primary btn-block',
'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ',
'browseLabel' => 'Attach Listing Images',
'allowedFileExtensions' => ['jpg','gif','png'],
'overwriteInitial' => false
],
],
],
]
]
],
]
]);
?>


Controller Action



/**
* Creates a new Property model.
* If creation is successful, the browser will be redirected to the 'view' page.
* @return mixed
*/
public function actionProperty()

$listingModel = new Listing;
$imageModel = new ListingImages;
$model = new Property;

if ($listingModel->load(Yii::$app->request->post()) && $imageModel->load(Yii::$app->request->post()) && $model->load(Yii::$app->request->post()))

$transaction = Yii::$app->db->beginTransaction();
try

$listingModel->listing_type_id = $listingModel->listingType('Property');
$listingModel->created_by = Yii::$app->user->id;

if ($flag = $listingModel->save(false))

$model->listing_id = $listingModel->listing_id;
$model->physical_address = $listingModel->physical_address;
$model->neighborhood = $listingModel->neighborhood;
$model->area_id = $listingModel->area_code;
$model->address = $listingModel->physical_address;
$model->latitude = $listingModel->latitude;
$model->longitude = $listingModel->longitude;
$model->created_by = Yii::$app->user->id;

$flag = $model->save(false);

foreach ($_FILES['ListingImages']['name']['image'] as $key => $image)
$image = $imageModel->uploadImage();

$imageModel->created_by = Yii::$app->user->id;
$imageModel->listing_id = $listingModel->listing_id;
$imageModel->active = 'Y';

if ($flag = $imageModel->save())
if ($image !== false)
$path = $imageModel->getImageFile();
$image->saveAs($path);





if ($flag)
$transaction->commit();

return $this->redirect(['view', 'id' => $listingModel->listing_id]);
else
$transaction->rollBack();

catch (Exception $e)
$transaction->rollBack();

else
return $this->render('create', [
'listingModel' => $listingModel, 'model' => $model, 'form' => '_property', 'imageModel' => $imageModel,
]);




ListingImages model



<?php

namespace commonmodels;

use Yii;
use yiiwebUploadedFile;
use yiihelpersFileHelper;

/**
* This is the model class for table "listing_images".
*
* @property int $image_id
* @property int $listing_id
* @property string $image_url_link generated filename on server
* @property string $updated_at
* @property string $created_at
* @property int $created_by
* @property string $active
* @property string $filename source filename from client
*
* @property Listing $listing
*/
class ListingImages extends yiidbActiveRecord

const PERMISSIONS_PRIVATE = 10;
const PERMISSIONS_PUBLIC = 20;
public $filename;
public $image;
/**
* @inheritdoc
*/
public static function tableName()

return 'listing_images';


/**
* @inheritdoc
*/
public function rules()

return [
[['listing_id', 'image_url_link', 'created_by', 'active'], 'required'],
[['listing_id', 'created_by'], 'integer'],
[['updated_at', 'created_at', 'filename'], 'safe'],
[['active'], 'string'],
[['image_url_link'], 'string', 'max' => 80],
[['listing_id'], 'exist', 'skipOnError' => true, 'targetClass' => Listing::className(), 'targetAttribute' => ['listing_id' => 'listing_id']],
// [['image'], 'file', 'extensions'=>'jpg, gif, png'],
// [['image'], 'file', 'maxSize'=>'2048000'],
// [['image'], 'file','maxFiles' => 30],
[['image'], 'file', 'extensions' => ['png', 'jpg', 'gif'], 'maxSize' => 2048000, 'maxFiles' => 30],
];


/**
* @inheritdoc
*/
public function attributeLabels()

return [
'image_id' => Yii::t('app', 'Image ID'),
'listing_id' => Yii::t('app', 'Listing ID'),
'image_url_link' => Yii::t('app', 'Listing Image'),
'updated_at' => Yii::t('app', 'Updated At'),
'created_at' => Yii::t('app', 'Created At'),
'created_by' => Yii::t('app', 'Created By'),
'active' => Yii::t('app', 'Active'),
];


/**
* @return yiidbActiveQuery
*/
public function getListing()

return $this->hasOne(Listing::className(), ['listing_id' => 'listing_id']);


/**
* fetch stored image file name with complete path
* @return string
*/
public function getImageFile()

$directory = Yii::$app->params['uploadPath'];
if (!is_dir($directory))
FileHelper::createDirectory($directory);

return isset($this->image_url_link) ? $directory . '/' . $this->image_url_link : null;


/**
* fetch stored image url
* @return string
*/
public function getImageUrl()

$directory = Yii::$app->params['uploadUrl'];
// return a default image placeholder if your source image_url_link is not found
$image_url_link = isset($this->image_url_link) ? $this->image_url_link : 'default_user.jpg';
return $directory . $image_url_link;


/**
* Process upload of image
*
* @return mixed the uploaded image instance
*/
public function uploadImage()
// get the uploaded file instance. for multiple file uploads
// the following data will return an array (you may need to use
// getInstances method)
$image = UploadedFile::getInstance($this, 'image');

// if no image was uploaded abort the upload
if (empty($image))
return false;


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

// generate a unique file name
$this->image_url_link = Yii::$app->security->generateRandomString().".$ext";

// the uploaded image instance
return $image;


/**
* Process deletion of image
*
* @return boolean the status of deletion
*/
public function deleteImage()



Note that the other part of the code is working fine. I have only twisted some few parts to get a favourable results. Here is the submitted data via the form. The part that is really confusing me is that wrapped in the $_FILES array at the end of this code that has all the uploaded files information.



$_POST = [
'_csrf-backend' => '_ioSvkoWdYDTEG_L4AHgnyQSEe7pZOqEWwQfPANPbM2uGkbIKHo8y5ZAGriqT4XsQCBkl5sOnvweT31wUx01kg==',
'Listing' => [
'listing_title' => 'tyguhijokpl[',
'country' => '2',
'states' => '4',
'area_id' => '1537',
'physical_address' => 'yghbunjikmol,',
'neighborhood' => 'gvybhunjimko,l',
'address' => 'Dandora phase 4, Nairobi, Kenya',
'latitude' => '-1.2423923',
'longitude' => '36.90438449999999',
],
'Property' => [
'property_category' => '1',
'sub_category_id' => '2',
'currency_id' => '1',
'price' => '897465123',
'property_features' => [
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
],
],
'ListingImages' => [
'image' => [
'',
],
],
];

$_FILES = [
'ListingImages' => [
'name' => [
'image' => [
'coins-1015125_1920.jpg',
'computer-768608_1920.jpg',
'content-is-king-1132259_1920.jpg',
'content-marketing.jpg',
'contentpyramid.png',
'cup-of-coffee-1280537_1920.jpg',
'ecommerce-3546296_1920.jpg',
'email-3249062_1280.png',
],
],
'type' => [
'image' => [
'image/jpeg',
'image/jpeg',
'image/jpeg',
'image/jpeg',
'image/png',
'image/jpeg',
'image/jpeg',
'image/png',
],
],
'tmp_name' => [
'image' => [
'C:\xampp\tmp\php8AF1.tmp',
'C:\xampp\tmp\php8B02.tmp',
'C:\xampp\tmp\php8B03.tmp',
'C:\xampp\tmp\php8B23.tmp',
'C:\xampp\tmp\php8B34.tmp',
'C:\xampp\tmp\php8B35.tmp',
'C:\xampp\tmp\php8B46.tmp',
'C:\xampp\tmp\php8B47.tmp',
],
],
'error' => [
'image' => [
0,
0,
0,
0,
0,
0,
0,
0,
],
],
'size' => [
'image' => [
364796,
275881,
310313,
301511,
119458,
508911,
219479,
242737,
],
],
],
];









share|improve this question























  • refer this official tutorial github.com/yiisoft/yii2/blob/master/docs/guide/…
    – Riyas Kp
    Nov 9 at 10:21










  • hello, @japheth i created this extension, i cant see where you are calling the UploadedFile::getInstances('image') to get the images.
    – Muhammad Omer Aslam
    Nov 10 at 14:07














up vote
0
down vote

favorite












I am developing my app using the yii2-formwizard widget. I have gotten it working fine in all the other parts and even submits a single image perfectly. The problem comes when I try to submit multiple images. I get the $_POST array with form model values and the image model as an empty array inside the $_POST, but then all the image model values are wrapped in an array of $_FILES. How do I go about solving this as I have never dealt with such before? Here are the relevant codes:



_form view



<?php

use yiihelpersHtml;
use kartikwidgetsActiveForm;
use kartikbuilderForm;
use kartikdatecontrolDateControl;
use kartikwidgetsSelect2;
use buttflatteryformwizardFormWizard;
use yiihelpersArrayHelper;
use kartikfileFileInput;

/**
* @var yiiwebView $this
* @var commonmodelsListing $model
* @var yiiwidgetsActiveForm $form
*/
?>

<?php
echo FormWizard::widget([
'theme' => FormWizard::THEME_MATERIAL,
'labelFinish' => 'Submit',
// 'formOptions'=>[
// 'options'=>['enctype'=>'multipart/form-data'],
// ],
'steps' => [
[
'model'=>$listingModel,
'title'=>'Basic',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [
'created_by' => false, //hide a specific field
'updated_at' => false, //hide a specific field
'created_at' => false, //hide a specific field
'expires_on' => false, //hide a specific field
'status' => false, //hide a specific field
'listing_type_id' => false, //hide a specific field
'latitude' => false, //hide a specific field
'longitude' => false, //hide a specific field

'listing_title' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter Listing Title...', 'maxlength' => 50]],

'country' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsCountry::find()->all(), 'country_id', 'country_name'),
'options' => [
'prompt'=>'Select Country',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('listing/select-state?id=').'"+$(this).val(), function( data )
$( "select#state_id" ).html( data );
);
'
]
]
],

'states' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsStates::find()->all(), 'state_id', 'state_name'),
'options' => [
'id'=>'state_id',
'prompt'=>'Select Select the Country First',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('listing/select-area?id=').'"+$(this).val(), function( data )
$( "select#area_code" ).html( data );
);
'
]
]
],

'area_id' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsAreas::find()->all(), 'area_id', 'area_name'),
'options' => [
'prompt'=>'Please Select the State/Region First',
'id' => 'area_code'
],
]
],

'physical_address' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter The Actual Physical Address...', 'maxlength' => 50]],

'neighborhood' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter The Nearby Landmark or Neighbourhood...', 'maxlength' => 50]],

'address' => [
'widget' => kalyabinmaplocationSelectMapLocationWidget::className(),
'options' => [
'attributeLatitude' => 'latitude',
'attributeLongitude' => 'longitude',
'googleMapApiKey' => 'AIzaSyDU30XgKi1ik7wpWteHUENKVH_d09sTqRg',
'draggable' => true,
],
]
]
],
[
'model'=>$model,
'title'=>'Prices and More',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [

// 'only' => ['property_category', 'sub_category_id', 'available_from', 'desc', 'price', 'currency_id', 'price_conditions', 'deposit', 'agent_commission', 'other_payments'],

'only' => ['property_category', 'sub_category_id', 'price', 'currency_id'],

'property_category' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsPropertyCategory::find()->all(), 'category_id', 'category_name'),
'options' => [
'id'=>'state_id',
'prompt'=>'Select Property Category',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('listing/select-property-category?id=').'"+$(this).val(), function( data )
$( "select#sub_category_value" ).html( data );
);
'
]
]
],

'sub_category_id' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsPropertySubCategory::find()->all(), 'sub_category_id', 'name'),
'options' => [
'prompt'=>'Please Select the Property Category First',
'id' => 'sub_category_value'
],
]
],

'currency_id' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsCurrency::find()->all(), 'currency_id', 'title'),
]
],

'price' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter Price...']],
]
],
[
'model'=>$model,
'title'=>'Features',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [
// 'only' => ['beds', 'baths', 'rooms', 'living_area', 'living_size', 'floor', 'total_floors', 'build_year', 'car_spaces', 'fully_furnished', 'property_features'],

'only' => ['property_features'],

'property_features' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsPropertyFeatures::find()->all(), 'feature_id', 'feature_name', 'featuresType.type_name'),
'options' => ['multiple' => true, 'placeholder' => 'Select Property Features ...']
]
],
]
],
[
'model'=>$imageModel,
'title'=>'Images',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [
'only' => ['image'],
'image' => [
'multifield'=>true,
'widget' => FileInput::classname(),
'options' =>[
'options' => [
'multiple' => true,
'accept' => 'image/*',
'pluginOptions' => [
'showCaption' => false,
'showRemove' => false,
'showUpload' => false,
'browseClass' => 'btn btn-primary btn-block',
'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ',
'browseLabel' => 'Attach Listing Images',
'allowedFileExtensions' => ['jpg','gif','png'],
'overwriteInitial' => false
],
],
],
]
]
],
]
]);
?>


Controller Action



/**
* Creates a new Property model.
* If creation is successful, the browser will be redirected to the 'view' page.
* @return mixed
*/
public function actionProperty()

$listingModel = new Listing;
$imageModel = new ListingImages;
$model = new Property;

if ($listingModel->load(Yii::$app->request->post()) && $imageModel->load(Yii::$app->request->post()) && $model->load(Yii::$app->request->post()))

$transaction = Yii::$app->db->beginTransaction();
try

$listingModel->listing_type_id = $listingModel->listingType('Property');
$listingModel->created_by = Yii::$app->user->id;

if ($flag = $listingModel->save(false))

$model->listing_id = $listingModel->listing_id;
$model->physical_address = $listingModel->physical_address;
$model->neighborhood = $listingModel->neighborhood;
$model->area_id = $listingModel->area_code;
$model->address = $listingModel->physical_address;
$model->latitude = $listingModel->latitude;
$model->longitude = $listingModel->longitude;
$model->created_by = Yii::$app->user->id;

$flag = $model->save(false);

foreach ($_FILES['ListingImages']['name']['image'] as $key => $image)
$image = $imageModel->uploadImage();

$imageModel->created_by = Yii::$app->user->id;
$imageModel->listing_id = $listingModel->listing_id;
$imageModel->active = 'Y';

if ($flag = $imageModel->save())
if ($image !== false)
$path = $imageModel->getImageFile();
$image->saveAs($path);





if ($flag)
$transaction->commit();

return $this->redirect(['view', 'id' => $listingModel->listing_id]);
else
$transaction->rollBack();

catch (Exception $e)
$transaction->rollBack();

else
return $this->render('create', [
'listingModel' => $listingModel, 'model' => $model, 'form' => '_property', 'imageModel' => $imageModel,
]);




ListingImages model



<?php

namespace commonmodels;

use Yii;
use yiiwebUploadedFile;
use yiihelpersFileHelper;

/**
* This is the model class for table "listing_images".
*
* @property int $image_id
* @property int $listing_id
* @property string $image_url_link generated filename on server
* @property string $updated_at
* @property string $created_at
* @property int $created_by
* @property string $active
* @property string $filename source filename from client
*
* @property Listing $listing
*/
class ListingImages extends yiidbActiveRecord

const PERMISSIONS_PRIVATE = 10;
const PERMISSIONS_PUBLIC = 20;
public $filename;
public $image;
/**
* @inheritdoc
*/
public static function tableName()

return 'listing_images';


/**
* @inheritdoc
*/
public function rules()

return [
[['listing_id', 'image_url_link', 'created_by', 'active'], 'required'],
[['listing_id', 'created_by'], 'integer'],
[['updated_at', 'created_at', 'filename'], 'safe'],
[['active'], 'string'],
[['image_url_link'], 'string', 'max' => 80],
[['listing_id'], 'exist', 'skipOnError' => true, 'targetClass' => Listing::className(), 'targetAttribute' => ['listing_id' => 'listing_id']],
// [['image'], 'file', 'extensions'=>'jpg, gif, png'],
// [['image'], 'file', 'maxSize'=>'2048000'],
// [['image'], 'file','maxFiles' => 30],
[['image'], 'file', 'extensions' => ['png', 'jpg', 'gif'], 'maxSize' => 2048000, 'maxFiles' => 30],
];


/**
* @inheritdoc
*/
public function attributeLabels()

return [
'image_id' => Yii::t('app', 'Image ID'),
'listing_id' => Yii::t('app', 'Listing ID'),
'image_url_link' => Yii::t('app', 'Listing Image'),
'updated_at' => Yii::t('app', 'Updated At'),
'created_at' => Yii::t('app', 'Created At'),
'created_by' => Yii::t('app', 'Created By'),
'active' => Yii::t('app', 'Active'),
];


/**
* @return yiidbActiveQuery
*/
public function getListing()

return $this->hasOne(Listing::className(), ['listing_id' => 'listing_id']);


/**
* fetch stored image file name with complete path
* @return string
*/
public function getImageFile()

$directory = Yii::$app->params['uploadPath'];
if (!is_dir($directory))
FileHelper::createDirectory($directory);

return isset($this->image_url_link) ? $directory . '/' . $this->image_url_link : null;


/**
* fetch stored image url
* @return string
*/
public function getImageUrl()

$directory = Yii::$app->params['uploadUrl'];
// return a default image placeholder if your source image_url_link is not found
$image_url_link = isset($this->image_url_link) ? $this->image_url_link : 'default_user.jpg';
return $directory . $image_url_link;


/**
* Process upload of image
*
* @return mixed the uploaded image instance
*/
public function uploadImage()
// get the uploaded file instance. for multiple file uploads
// the following data will return an array (you may need to use
// getInstances method)
$image = UploadedFile::getInstance($this, 'image');

// if no image was uploaded abort the upload
if (empty($image))
return false;


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

// generate a unique file name
$this->image_url_link = Yii::$app->security->generateRandomString().".$ext";

// the uploaded image instance
return $image;


/**
* Process deletion of image
*
* @return boolean the status of deletion
*/
public function deleteImage()



Note that the other part of the code is working fine. I have only twisted some few parts to get a favourable results. Here is the submitted data via the form. The part that is really confusing me is that wrapped in the $_FILES array at the end of this code that has all the uploaded files information.



$_POST = [
'_csrf-backend' => '_ioSvkoWdYDTEG_L4AHgnyQSEe7pZOqEWwQfPANPbM2uGkbIKHo8y5ZAGriqT4XsQCBkl5sOnvweT31wUx01kg==',
'Listing' => [
'listing_title' => 'tyguhijokpl[',
'country' => '2',
'states' => '4',
'area_id' => '1537',
'physical_address' => 'yghbunjikmol,',
'neighborhood' => 'gvybhunjimko,l',
'address' => 'Dandora phase 4, Nairobi, Kenya',
'latitude' => '-1.2423923',
'longitude' => '36.90438449999999',
],
'Property' => [
'property_category' => '1',
'sub_category_id' => '2',
'currency_id' => '1',
'price' => '897465123',
'property_features' => [
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
],
],
'ListingImages' => [
'image' => [
'',
],
],
];

$_FILES = [
'ListingImages' => [
'name' => [
'image' => [
'coins-1015125_1920.jpg',
'computer-768608_1920.jpg',
'content-is-king-1132259_1920.jpg',
'content-marketing.jpg',
'contentpyramid.png',
'cup-of-coffee-1280537_1920.jpg',
'ecommerce-3546296_1920.jpg',
'email-3249062_1280.png',
],
],
'type' => [
'image' => [
'image/jpeg',
'image/jpeg',
'image/jpeg',
'image/jpeg',
'image/png',
'image/jpeg',
'image/jpeg',
'image/png',
],
],
'tmp_name' => [
'image' => [
'C:\xampp\tmp\php8AF1.tmp',
'C:\xampp\tmp\php8B02.tmp',
'C:\xampp\tmp\php8B03.tmp',
'C:\xampp\tmp\php8B23.tmp',
'C:\xampp\tmp\php8B34.tmp',
'C:\xampp\tmp\php8B35.tmp',
'C:\xampp\tmp\php8B46.tmp',
'C:\xampp\tmp\php8B47.tmp',
],
],
'error' => [
'image' => [
0,
0,
0,
0,
0,
0,
0,
0,
],
],
'size' => [
'image' => [
364796,
275881,
310313,
301511,
119458,
508911,
219479,
242737,
],
],
],
];









share|improve this question























  • refer this official tutorial github.com/yiisoft/yii2/blob/master/docs/guide/…
    – Riyas Kp
    Nov 9 at 10:21










  • hello, @japheth i created this extension, i cant see where you are calling the UploadedFile::getInstances('image') to get the images.
    – Muhammad Omer Aslam
    Nov 10 at 14:07












up vote
0
down vote

favorite









up vote
0
down vote

favorite











I am developing my app using the yii2-formwizard widget. I have gotten it working fine in all the other parts and even submits a single image perfectly. The problem comes when I try to submit multiple images. I get the $_POST array with form model values and the image model as an empty array inside the $_POST, but then all the image model values are wrapped in an array of $_FILES. How do I go about solving this as I have never dealt with such before? Here are the relevant codes:



_form view



<?php

use yiihelpersHtml;
use kartikwidgetsActiveForm;
use kartikbuilderForm;
use kartikdatecontrolDateControl;
use kartikwidgetsSelect2;
use buttflatteryformwizardFormWizard;
use yiihelpersArrayHelper;
use kartikfileFileInput;

/**
* @var yiiwebView $this
* @var commonmodelsListing $model
* @var yiiwidgetsActiveForm $form
*/
?>

<?php
echo FormWizard::widget([
'theme' => FormWizard::THEME_MATERIAL,
'labelFinish' => 'Submit',
// 'formOptions'=>[
// 'options'=>['enctype'=>'multipart/form-data'],
// ],
'steps' => [
[
'model'=>$listingModel,
'title'=>'Basic',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [
'created_by' => false, //hide a specific field
'updated_at' => false, //hide a specific field
'created_at' => false, //hide a specific field
'expires_on' => false, //hide a specific field
'status' => false, //hide a specific field
'listing_type_id' => false, //hide a specific field
'latitude' => false, //hide a specific field
'longitude' => false, //hide a specific field

'listing_title' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter Listing Title...', 'maxlength' => 50]],

'country' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsCountry::find()->all(), 'country_id', 'country_name'),
'options' => [
'prompt'=>'Select Country',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('listing/select-state?id=').'"+$(this).val(), function( data )
$( "select#state_id" ).html( data );
);
'
]
]
],

'states' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsStates::find()->all(), 'state_id', 'state_name'),
'options' => [
'id'=>'state_id',
'prompt'=>'Select Select the Country First',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('listing/select-area?id=').'"+$(this).val(), function( data )
$( "select#area_code" ).html( data );
);
'
]
]
],

'area_id' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsAreas::find()->all(), 'area_id', 'area_name'),
'options' => [
'prompt'=>'Please Select the State/Region First',
'id' => 'area_code'
],
]
],

'physical_address' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter The Actual Physical Address...', 'maxlength' => 50]],

'neighborhood' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter The Nearby Landmark or Neighbourhood...', 'maxlength' => 50]],

'address' => [
'widget' => kalyabinmaplocationSelectMapLocationWidget::className(),
'options' => [
'attributeLatitude' => 'latitude',
'attributeLongitude' => 'longitude',
'googleMapApiKey' => 'AIzaSyDU30XgKi1ik7wpWteHUENKVH_d09sTqRg',
'draggable' => true,
],
]
]
],
[
'model'=>$model,
'title'=>'Prices and More',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [

// 'only' => ['property_category', 'sub_category_id', 'available_from', 'desc', 'price', 'currency_id', 'price_conditions', 'deposit', 'agent_commission', 'other_payments'],

'only' => ['property_category', 'sub_category_id', 'price', 'currency_id'],

'property_category' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsPropertyCategory::find()->all(), 'category_id', 'category_name'),
'options' => [
'id'=>'state_id',
'prompt'=>'Select Property Category',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('listing/select-property-category?id=').'"+$(this).val(), function( data )
$( "select#sub_category_value" ).html( data );
);
'
]
]
],

'sub_category_id' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsPropertySubCategory::find()->all(), 'sub_category_id', 'name'),
'options' => [
'prompt'=>'Please Select the Property Category First',
'id' => 'sub_category_value'
],
]
],

'currency_id' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsCurrency::find()->all(), 'currency_id', 'title'),
]
],

'price' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter Price...']],
]
],
[
'model'=>$model,
'title'=>'Features',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [
// 'only' => ['beds', 'baths', 'rooms', 'living_area', 'living_size', 'floor', 'total_floors', 'build_year', 'car_spaces', 'fully_furnished', 'property_features'],

'only' => ['property_features'],

'property_features' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsPropertyFeatures::find()->all(), 'feature_id', 'feature_name', 'featuresType.type_name'),
'options' => ['multiple' => true, 'placeholder' => 'Select Property Features ...']
]
],
]
],
[
'model'=>$imageModel,
'title'=>'Images',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [
'only' => ['image'],
'image' => [
'multifield'=>true,
'widget' => FileInput::classname(),
'options' =>[
'options' => [
'multiple' => true,
'accept' => 'image/*',
'pluginOptions' => [
'showCaption' => false,
'showRemove' => false,
'showUpload' => false,
'browseClass' => 'btn btn-primary btn-block',
'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ',
'browseLabel' => 'Attach Listing Images',
'allowedFileExtensions' => ['jpg','gif','png'],
'overwriteInitial' => false
],
],
],
]
]
],
]
]);
?>


Controller Action



/**
* Creates a new Property model.
* If creation is successful, the browser will be redirected to the 'view' page.
* @return mixed
*/
public function actionProperty()

$listingModel = new Listing;
$imageModel = new ListingImages;
$model = new Property;

if ($listingModel->load(Yii::$app->request->post()) && $imageModel->load(Yii::$app->request->post()) && $model->load(Yii::$app->request->post()))

$transaction = Yii::$app->db->beginTransaction();
try

$listingModel->listing_type_id = $listingModel->listingType('Property');
$listingModel->created_by = Yii::$app->user->id;

if ($flag = $listingModel->save(false))

$model->listing_id = $listingModel->listing_id;
$model->physical_address = $listingModel->physical_address;
$model->neighborhood = $listingModel->neighborhood;
$model->area_id = $listingModel->area_code;
$model->address = $listingModel->physical_address;
$model->latitude = $listingModel->latitude;
$model->longitude = $listingModel->longitude;
$model->created_by = Yii::$app->user->id;

$flag = $model->save(false);

foreach ($_FILES['ListingImages']['name']['image'] as $key => $image)
$image = $imageModel->uploadImage();

$imageModel->created_by = Yii::$app->user->id;
$imageModel->listing_id = $listingModel->listing_id;
$imageModel->active = 'Y';

if ($flag = $imageModel->save())
if ($image !== false)
$path = $imageModel->getImageFile();
$image->saveAs($path);





if ($flag)
$transaction->commit();

return $this->redirect(['view', 'id' => $listingModel->listing_id]);
else
$transaction->rollBack();

catch (Exception $e)
$transaction->rollBack();

else
return $this->render('create', [
'listingModel' => $listingModel, 'model' => $model, 'form' => '_property', 'imageModel' => $imageModel,
]);




ListingImages model



<?php

namespace commonmodels;

use Yii;
use yiiwebUploadedFile;
use yiihelpersFileHelper;

/**
* This is the model class for table "listing_images".
*
* @property int $image_id
* @property int $listing_id
* @property string $image_url_link generated filename on server
* @property string $updated_at
* @property string $created_at
* @property int $created_by
* @property string $active
* @property string $filename source filename from client
*
* @property Listing $listing
*/
class ListingImages extends yiidbActiveRecord

const PERMISSIONS_PRIVATE = 10;
const PERMISSIONS_PUBLIC = 20;
public $filename;
public $image;
/**
* @inheritdoc
*/
public static function tableName()

return 'listing_images';


/**
* @inheritdoc
*/
public function rules()

return [
[['listing_id', 'image_url_link', 'created_by', 'active'], 'required'],
[['listing_id', 'created_by'], 'integer'],
[['updated_at', 'created_at', 'filename'], 'safe'],
[['active'], 'string'],
[['image_url_link'], 'string', 'max' => 80],
[['listing_id'], 'exist', 'skipOnError' => true, 'targetClass' => Listing::className(), 'targetAttribute' => ['listing_id' => 'listing_id']],
// [['image'], 'file', 'extensions'=>'jpg, gif, png'],
// [['image'], 'file', 'maxSize'=>'2048000'],
// [['image'], 'file','maxFiles' => 30],
[['image'], 'file', 'extensions' => ['png', 'jpg', 'gif'], 'maxSize' => 2048000, 'maxFiles' => 30],
];


/**
* @inheritdoc
*/
public function attributeLabels()

return [
'image_id' => Yii::t('app', 'Image ID'),
'listing_id' => Yii::t('app', 'Listing ID'),
'image_url_link' => Yii::t('app', 'Listing Image'),
'updated_at' => Yii::t('app', 'Updated At'),
'created_at' => Yii::t('app', 'Created At'),
'created_by' => Yii::t('app', 'Created By'),
'active' => Yii::t('app', 'Active'),
];


/**
* @return yiidbActiveQuery
*/
public function getListing()

return $this->hasOne(Listing::className(), ['listing_id' => 'listing_id']);


/**
* fetch stored image file name with complete path
* @return string
*/
public function getImageFile()

$directory = Yii::$app->params['uploadPath'];
if (!is_dir($directory))
FileHelper::createDirectory($directory);

return isset($this->image_url_link) ? $directory . '/' . $this->image_url_link : null;


/**
* fetch stored image url
* @return string
*/
public function getImageUrl()

$directory = Yii::$app->params['uploadUrl'];
// return a default image placeholder if your source image_url_link is not found
$image_url_link = isset($this->image_url_link) ? $this->image_url_link : 'default_user.jpg';
return $directory . $image_url_link;


/**
* Process upload of image
*
* @return mixed the uploaded image instance
*/
public function uploadImage()
// get the uploaded file instance. for multiple file uploads
// the following data will return an array (you may need to use
// getInstances method)
$image = UploadedFile::getInstance($this, 'image');

// if no image was uploaded abort the upload
if (empty($image))
return false;


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

// generate a unique file name
$this->image_url_link = Yii::$app->security->generateRandomString().".$ext";

// the uploaded image instance
return $image;


/**
* Process deletion of image
*
* @return boolean the status of deletion
*/
public function deleteImage()



Note that the other part of the code is working fine. I have only twisted some few parts to get a favourable results. Here is the submitted data via the form. The part that is really confusing me is that wrapped in the $_FILES array at the end of this code that has all the uploaded files information.



$_POST = [
'_csrf-backend' => '_ioSvkoWdYDTEG_L4AHgnyQSEe7pZOqEWwQfPANPbM2uGkbIKHo8y5ZAGriqT4XsQCBkl5sOnvweT31wUx01kg==',
'Listing' => [
'listing_title' => 'tyguhijokpl[',
'country' => '2',
'states' => '4',
'area_id' => '1537',
'physical_address' => 'yghbunjikmol,',
'neighborhood' => 'gvybhunjimko,l',
'address' => 'Dandora phase 4, Nairobi, Kenya',
'latitude' => '-1.2423923',
'longitude' => '36.90438449999999',
],
'Property' => [
'property_category' => '1',
'sub_category_id' => '2',
'currency_id' => '1',
'price' => '897465123',
'property_features' => [
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
],
],
'ListingImages' => [
'image' => [
'',
],
],
];

$_FILES = [
'ListingImages' => [
'name' => [
'image' => [
'coins-1015125_1920.jpg',
'computer-768608_1920.jpg',
'content-is-king-1132259_1920.jpg',
'content-marketing.jpg',
'contentpyramid.png',
'cup-of-coffee-1280537_1920.jpg',
'ecommerce-3546296_1920.jpg',
'email-3249062_1280.png',
],
],
'type' => [
'image' => [
'image/jpeg',
'image/jpeg',
'image/jpeg',
'image/jpeg',
'image/png',
'image/jpeg',
'image/jpeg',
'image/png',
],
],
'tmp_name' => [
'image' => [
'C:\xampp\tmp\php8AF1.tmp',
'C:\xampp\tmp\php8B02.tmp',
'C:\xampp\tmp\php8B03.tmp',
'C:\xampp\tmp\php8B23.tmp',
'C:\xampp\tmp\php8B34.tmp',
'C:\xampp\tmp\php8B35.tmp',
'C:\xampp\tmp\php8B46.tmp',
'C:\xampp\tmp\php8B47.tmp',
],
],
'error' => [
'image' => [
0,
0,
0,
0,
0,
0,
0,
0,
],
],
'size' => [
'image' => [
364796,
275881,
310313,
301511,
119458,
508911,
219479,
242737,
],
],
],
];









share|improve this question















I am developing my app using the yii2-formwizard widget. I have gotten it working fine in all the other parts and even submits a single image perfectly. The problem comes when I try to submit multiple images. I get the $_POST array with form model values and the image model as an empty array inside the $_POST, but then all the image model values are wrapped in an array of $_FILES. How do I go about solving this as I have never dealt with such before? Here are the relevant codes:



_form view



<?php

use yiihelpersHtml;
use kartikwidgetsActiveForm;
use kartikbuilderForm;
use kartikdatecontrolDateControl;
use kartikwidgetsSelect2;
use buttflatteryformwizardFormWizard;
use yiihelpersArrayHelper;
use kartikfileFileInput;

/**
* @var yiiwebView $this
* @var commonmodelsListing $model
* @var yiiwidgetsActiveForm $form
*/
?>

<?php
echo FormWizard::widget([
'theme' => FormWizard::THEME_MATERIAL,
'labelFinish' => 'Submit',
// 'formOptions'=>[
// 'options'=>['enctype'=>'multipart/form-data'],
// ],
'steps' => [
[
'model'=>$listingModel,
'title'=>'Basic',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [
'created_by' => false, //hide a specific field
'updated_at' => false, //hide a specific field
'created_at' => false, //hide a specific field
'expires_on' => false, //hide a specific field
'status' => false, //hide a specific field
'listing_type_id' => false, //hide a specific field
'latitude' => false, //hide a specific field
'longitude' => false, //hide a specific field

'listing_title' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter Listing Title...', 'maxlength' => 50]],

'country' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsCountry::find()->all(), 'country_id', 'country_name'),
'options' => [
'prompt'=>'Select Country',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('listing/select-state?id=').'"+$(this).val(), function( data )
$( "select#state_id" ).html( data );
);
'
]
]
],

'states' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsStates::find()->all(), 'state_id', 'state_name'),
'options' => [
'id'=>'state_id',
'prompt'=>'Select Select the Country First',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('listing/select-area?id=').'"+$(this).val(), function( data )
$( "select#area_code" ).html( data );
);
'
]
]
],

'area_id' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsAreas::find()->all(), 'area_id', 'area_name'),
'options' => [
'prompt'=>'Please Select the State/Region First',
'id' => 'area_code'
],
]
],

'physical_address' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter The Actual Physical Address...', 'maxlength' => 50]],

'neighborhood' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter The Nearby Landmark or Neighbourhood...', 'maxlength' => 50]],

'address' => [
'widget' => kalyabinmaplocationSelectMapLocationWidget::className(),
'options' => [
'attributeLatitude' => 'latitude',
'attributeLongitude' => 'longitude',
'googleMapApiKey' => 'AIzaSyDU30XgKi1ik7wpWteHUENKVH_d09sTqRg',
'draggable' => true,
],
]
]
],
[
'model'=>$model,
'title'=>'Prices and More',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [

// 'only' => ['property_category', 'sub_category_id', 'available_from', 'desc', 'price', 'currency_id', 'price_conditions', 'deposit', 'agent_commission', 'other_payments'],

'only' => ['property_category', 'sub_category_id', 'price', 'currency_id'],

'property_category' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsPropertyCategory::find()->all(), 'category_id', 'category_name'),
'options' => [
'id'=>'state_id',
'prompt'=>'Select Property Category',
'onchange'=>'
$.post( "'.Yii::$app->urlManager->createUrl('listing/select-property-category?id=').'"+$(this).val(), function( data )
$( "select#sub_category_value" ).html( data );
);
'
]
]
],

'sub_category_id' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsPropertySubCategory::find()->all(), 'sub_category_id', 'name'),
'options' => [
'prompt'=>'Please Select the Property Category First',
'id' => 'sub_category_value'
],
]
],

'currency_id' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsCurrency::find()->all(), 'currency_id', 'title'),
]
],

'price' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter Price...']],
]
],
[
'model'=>$model,
'title'=>'Features',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [
// 'only' => ['beds', 'baths', 'rooms', 'living_area', 'living_size', 'floor', 'total_floors', 'build_year', 'car_spaces', 'fully_furnished', 'property_features'],

'only' => ['property_features'],

'property_features' => [
'widget' => Select2::class, //widget class name
'options' => [
'data' => ArrayHelper::map(commonmodelsPropertyFeatures::find()->all(), 'feature_id', 'feature_name', 'featuresType.type_name'),
'options' => ['multiple' => true, 'placeholder' => 'Select Property Features ...']
]
],
]
],
[
'model'=>$imageModel,
'title'=>'Images',
'description'=>'Give us the details of the list',
'formInfoText'=>'Fill all required fields',
'fieldConfig' => [
'only' => ['image'],
'image' => [
'multifield'=>true,
'widget' => FileInput::classname(),
'options' =>[
'options' => [
'multiple' => true,
'accept' => 'image/*',
'pluginOptions' => [
'showCaption' => false,
'showRemove' => false,
'showUpload' => false,
'browseClass' => 'btn btn-primary btn-block',
'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ',
'browseLabel' => 'Attach Listing Images',
'allowedFileExtensions' => ['jpg','gif','png'],
'overwriteInitial' => false
],
],
],
]
]
],
]
]);
?>


Controller Action



/**
* Creates a new Property model.
* If creation is successful, the browser will be redirected to the 'view' page.
* @return mixed
*/
public function actionProperty()

$listingModel = new Listing;
$imageModel = new ListingImages;
$model = new Property;

if ($listingModel->load(Yii::$app->request->post()) && $imageModel->load(Yii::$app->request->post()) && $model->load(Yii::$app->request->post()))

$transaction = Yii::$app->db->beginTransaction();
try

$listingModel->listing_type_id = $listingModel->listingType('Property');
$listingModel->created_by = Yii::$app->user->id;

if ($flag = $listingModel->save(false))

$model->listing_id = $listingModel->listing_id;
$model->physical_address = $listingModel->physical_address;
$model->neighborhood = $listingModel->neighborhood;
$model->area_id = $listingModel->area_code;
$model->address = $listingModel->physical_address;
$model->latitude = $listingModel->latitude;
$model->longitude = $listingModel->longitude;
$model->created_by = Yii::$app->user->id;

$flag = $model->save(false);

foreach ($_FILES['ListingImages']['name']['image'] as $key => $image)
$image = $imageModel->uploadImage();

$imageModel->created_by = Yii::$app->user->id;
$imageModel->listing_id = $listingModel->listing_id;
$imageModel->active = 'Y';

if ($flag = $imageModel->save())
if ($image !== false)
$path = $imageModel->getImageFile();
$image->saveAs($path);





if ($flag)
$transaction->commit();

return $this->redirect(['view', 'id' => $listingModel->listing_id]);
else
$transaction->rollBack();

catch (Exception $e)
$transaction->rollBack();

else
return $this->render('create', [
'listingModel' => $listingModel, 'model' => $model, 'form' => '_property', 'imageModel' => $imageModel,
]);




ListingImages model



<?php

namespace commonmodels;

use Yii;
use yiiwebUploadedFile;
use yiihelpersFileHelper;

/**
* This is the model class for table "listing_images".
*
* @property int $image_id
* @property int $listing_id
* @property string $image_url_link generated filename on server
* @property string $updated_at
* @property string $created_at
* @property int $created_by
* @property string $active
* @property string $filename source filename from client
*
* @property Listing $listing
*/
class ListingImages extends yiidbActiveRecord

const PERMISSIONS_PRIVATE = 10;
const PERMISSIONS_PUBLIC = 20;
public $filename;
public $image;
/**
* @inheritdoc
*/
public static function tableName()

return 'listing_images';


/**
* @inheritdoc
*/
public function rules()

return [
[['listing_id', 'image_url_link', 'created_by', 'active'], 'required'],
[['listing_id', 'created_by'], 'integer'],
[['updated_at', 'created_at', 'filename'], 'safe'],
[['active'], 'string'],
[['image_url_link'], 'string', 'max' => 80],
[['listing_id'], 'exist', 'skipOnError' => true, 'targetClass' => Listing::className(), 'targetAttribute' => ['listing_id' => 'listing_id']],
// [['image'], 'file', 'extensions'=>'jpg, gif, png'],
// [['image'], 'file', 'maxSize'=>'2048000'],
// [['image'], 'file','maxFiles' => 30],
[['image'], 'file', 'extensions' => ['png', 'jpg', 'gif'], 'maxSize' => 2048000, 'maxFiles' => 30],
];


/**
* @inheritdoc
*/
public function attributeLabels()

return [
'image_id' => Yii::t('app', 'Image ID'),
'listing_id' => Yii::t('app', 'Listing ID'),
'image_url_link' => Yii::t('app', 'Listing Image'),
'updated_at' => Yii::t('app', 'Updated At'),
'created_at' => Yii::t('app', 'Created At'),
'created_by' => Yii::t('app', 'Created By'),
'active' => Yii::t('app', 'Active'),
];


/**
* @return yiidbActiveQuery
*/
public function getListing()

return $this->hasOne(Listing::className(), ['listing_id' => 'listing_id']);


/**
* fetch stored image file name with complete path
* @return string
*/
public function getImageFile()

$directory = Yii::$app->params['uploadPath'];
if (!is_dir($directory))
FileHelper::createDirectory($directory);

return isset($this->image_url_link) ? $directory . '/' . $this->image_url_link : null;


/**
* fetch stored image url
* @return string
*/
public function getImageUrl()

$directory = Yii::$app->params['uploadUrl'];
// return a default image placeholder if your source image_url_link is not found
$image_url_link = isset($this->image_url_link) ? $this->image_url_link : 'default_user.jpg';
return $directory . $image_url_link;


/**
* Process upload of image
*
* @return mixed the uploaded image instance
*/
public function uploadImage()
// get the uploaded file instance. for multiple file uploads
// the following data will return an array (you may need to use
// getInstances method)
$image = UploadedFile::getInstance($this, 'image');

// if no image was uploaded abort the upload
if (empty($image))
return false;


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

// generate a unique file name
$this->image_url_link = Yii::$app->security->generateRandomString().".$ext";

// the uploaded image instance
return $image;


/**
* Process deletion of image
*
* @return boolean the status of deletion
*/
public function deleteImage()



Note that the other part of the code is working fine. I have only twisted some few parts to get a favourable results. Here is the submitted data via the form. The part that is really confusing me is that wrapped in the $_FILES array at the end of this code that has all the uploaded files information.



$_POST = [
'_csrf-backend' => '_ioSvkoWdYDTEG_L4AHgnyQSEe7pZOqEWwQfPANPbM2uGkbIKHo8y5ZAGriqT4XsQCBkl5sOnvweT31wUx01kg==',
'Listing' => [
'listing_title' => 'tyguhijokpl[',
'country' => '2',
'states' => '4',
'area_id' => '1537',
'physical_address' => 'yghbunjikmol,',
'neighborhood' => 'gvybhunjimko,l',
'address' => 'Dandora phase 4, Nairobi, Kenya',
'latitude' => '-1.2423923',
'longitude' => '36.90438449999999',
],
'Property' => [
'property_category' => '1',
'sub_category_id' => '2',
'currency_id' => '1',
'price' => '897465123',
'property_features' => [
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
],
],
'ListingImages' => [
'image' => [
'',
],
],
];

$_FILES = [
'ListingImages' => [
'name' => [
'image' => [
'coins-1015125_1920.jpg',
'computer-768608_1920.jpg',
'content-is-king-1132259_1920.jpg',
'content-marketing.jpg',
'contentpyramid.png',
'cup-of-coffee-1280537_1920.jpg',
'ecommerce-3546296_1920.jpg',
'email-3249062_1280.png',
],
],
'type' => [
'image' => [
'image/jpeg',
'image/jpeg',
'image/jpeg',
'image/jpeg',
'image/png',
'image/jpeg',
'image/jpeg',
'image/png',
],
],
'tmp_name' => [
'image' => [
'C:\xampp\tmp\php8AF1.tmp',
'C:\xampp\tmp\php8B02.tmp',
'C:\xampp\tmp\php8B03.tmp',
'C:\xampp\tmp\php8B23.tmp',
'C:\xampp\tmp\php8B34.tmp',
'C:\xampp\tmp\php8B35.tmp',
'C:\xampp\tmp\php8B46.tmp',
'C:\xampp\tmp\php8B47.tmp',
],
],
'error' => [
'image' => [
0,
0,
0,
0,
0,
0,
0,
0,
],
],
'size' => [
'image' => [
364796,
275881,
310313,
301511,
119458,
508911,
219479,
242737,
],
],
],
];






php file-io yii2 kartik-v formwizard






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 10 at 14:06









Muhammad Omer Aslam

11.9k62344




11.9k62344










asked Nov 9 at 6:41









japheth

69110




69110











  • refer this official tutorial github.com/yiisoft/yii2/blob/master/docs/guide/…
    – Riyas Kp
    Nov 9 at 10:21










  • hello, @japheth i created this extension, i cant see where you are calling the UploadedFile::getInstances('image') to get the images.
    – Muhammad Omer Aslam
    Nov 10 at 14:07
















  • refer this official tutorial github.com/yiisoft/yii2/blob/master/docs/guide/…
    – Riyas Kp
    Nov 9 at 10:21










  • hello, @japheth i created this extension, i cant see where you are calling the UploadedFile::getInstances('image') to get the images.
    – Muhammad Omer Aslam
    Nov 10 at 14:07















refer this official tutorial github.com/yiisoft/yii2/blob/master/docs/guide/…
– Riyas Kp
Nov 9 at 10:21




refer this official tutorial github.com/yiisoft/yii2/blob/master/docs/guide/…
– Riyas Kp
Nov 9 at 10:21












hello, @japheth i created this extension, i cant see where you are calling the UploadedFile::getInstances('image') to get the images.
– Muhammad Omer Aslam
Nov 10 at 14:07




hello, @japheth i created this extension, i cant see where you are calling the UploadedFile::getInstances('image') to get the images.
– Muhammad Omer Aslam
Nov 10 at 14:07












1 Answer
1






active

oldest

votes

















up vote
0
down vote













i created this extension a few months back. The files that you submitted will be in the $_FILES array and not the $_POST and you need to call the UploadedFile::getInstances('image') to get all the images you selected to upload and then iterate on them to upload, you can access all the properties listed here for every image.



And you are not creating the new object every time you are inserting the image inside the foreach ($_FILES['ListingImages']['name']['image'] as $key => $image) { which will show only the last image inserted , your $imageModel is initialized in the start of the action whereas you should have it inside the foreach too



$imageInstances=UploadedFile::getInstances('image');
foreach ($imageInstances as $instance)
$imageModel=new ListingImages();
$image = $imageModel->uploadImage($instance);
$imageModel->created_by = Yii::$app->user->id;
$imageModel->listing_id = $listingModel->listing_id;
$imageModel->active = 'Y';

if ($flag = $imageModel->save())
if ($image !== false)
$path = $imageModel->getImageFile();
$image->saveAs($path);





and inside you uploadImage() use this instance to access the name , type, size and extension of the image to assign to the specific fields



 /**
* Process upload of image
*
* @return mixed the uploaded image instance
*/
public function uploadImage($image)
// get the uploaded file instance. for multiple file uploads
// the following data will return an array (you may need to use
// getInstances method)

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

// generate a unique file name
$this->image_url_link = Yii::$app->security->generateRandomString().".$ext";

// the uploaded image instance
return $image;






share|improve this answer




















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53220980%2fyii2-kartik-v-fileiput-get-uploaded-images-when-wrapped-in-the-array-of-files%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    i created this extension a few months back. The files that you submitted will be in the $_FILES array and not the $_POST and you need to call the UploadedFile::getInstances('image') to get all the images you selected to upload and then iterate on them to upload, you can access all the properties listed here for every image.



    And you are not creating the new object every time you are inserting the image inside the foreach ($_FILES['ListingImages']['name']['image'] as $key => $image) { which will show only the last image inserted , your $imageModel is initialized in the start of the action whereas you should have it inside the foreach too



    $imageInstances=UploadedFile::getInstances('image');
    foreach ($imageInstances as $instance)
    $imageModel=new ListingImages();
    $image = $imageModel->uploadImage($instance);
    $imageModel->created_by = Yii::$app->user->id;
    $imageModel->listing_id = $listingModel->listing_id;
    $imageModel->active = 'Y';

    if ($flag = $imageModel->save())
    if ($image !== false)
    $path = $imageModel->getImageFile();
    $image->saveAs($path);





    and inside you uploadImage() use this instance to access the name , type, size and extension of the image to assign to the specific fields



     /**
    * Process upload of image
    *
    * @return mixed the uploaded image instance
    */
    public function uploadImage($image)
    // get the uploaded file instance. for multiple file uploads
    // the following data will return an array (you may need to use
    // getInstances method)

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

    // generate a unique file name
    $this->image_url_link = Yii::$app->security->generateRandomString().".$ext";

    // the uploaded image instance
    return $image;






    share|improve this answer
























      up vote
      0
      down vote













      i created this extension a few months back. The files that you submitted will be in the $_FILES array and not the $_POST and you need to call the UploadedFile::getInstances('image') to get all the images you selected to upload and then iterate on them to upload, you can access all the properties listed here for every image.



      And you are not creating the new object every time you are inserting the image inside the foreach ($_FILES['ListingImages']['name']['image'] as $key => $image) { which will show only the last image inserted , your $imageModel is initialized in the start of the action whereas you should have it inside the foreach too



      $imageInstances=UploadedFile::getInstances('image');
      foreach ($imageInstances as $instance)
      $imageModel=new ListingImages();
      $image = $imageModel->uploadImage($instance);
      $imageModel->created_by = Yii::$app->user->id;
      $imageModel->listing_id = $listingModel->listing_id;
      $imageModel->active = 'Y';

      if ($flag = $imageModel->save())
      if ($image !== false)
      $path = $imageModel->getImageFile();
      $image->saveAs($path);





      and inside you uploadImage() use this instance to access the name , type, size and extension of the image to assign to the specific fields



       /**
      * Process upload of image
      *
      * @return mixed the uploaded image instance
      */
      public function uploadImage($image)
      // get the uploaded file instance. for multiple file uploads
      // the following data will return an array (you may need to use
      // getInstances method)

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

      // generate a unique file name
      $this->image_url_link = Yii::$app->security->generateRandomString().".$ext";

      // the uploaded image instance
      return $image;






      share|improve this answer






















        up vote
        0
        down vote










        up vote
        0
        down vote









        i created this extension a few months back. The files that you submitted will be in the $_FILES array and not the $_POST and you need to call the UploadedFile::getInstances('image') to get all the images you selected to upload and then iterate on them to upload, you can access all the properties listed here for every image.



        And you are not creating the new object every time you are inserting the image inside the foreach ($_FILES['ListingImages']['name']['image'] as $key => $image) { which will show only the last image inserted , your $imageModel is initialized in the start of the action whereas you should have it inside the foreach too



        $imageInstances=UploadedFile::getInstances('image');
        foreach ($imageInstances as $instance)
        $imageModel=new ListingImages();
        $image = $imageModel->uploadImage($instance);
        $imageModel->created_by = Yii::$app->user->id;
        $imageModel->listing_id = $listingModel->listing_id;
        $imageModel->active = 'Y';

        if ($flag = $imageModel->save())
        if ($image !== false)
        $path = $imageModel->getImageFile();
        $image->saveAs($path);





        and inside you uploadImage() use this instance to access the name , type, size and extension of the image to assign to the specific fields



         /**
        * Process upload of image
        *
        * @return mixed the uploaded image instance
        */
        public function uploadImage($image)
        // get the uploaded file instance. for multiple file uploads
        // the following data will return an array (you may need to use
        // getInstances method)

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

        // generate a unique file name
        $this->image_url_link = Yii::$app->security->generateRandomString().".$ext";

        // the uploaded image instance
        return $image;






        share|improve this answer












        i created this extension a few months back. The files that you submitted will be in the $_FILES array and not the $_POST and you need to call the UploadedFile::getInstances('image') to get all the images you selected to upload and then iterate on them to upload, you can access all the properties listed here for every image.



        And you are not creating the new object every time you are inserting the image inside the foreach ($_FILES['ListingImages']['name']['image'] as $key => $image) { which will show only the last image inserted , your $imageModel is initialized in the start of the action whereas you should have it inside the foreach too



        $imageInstances=UploadedFile::getInstances('image');
        foreach ($imageInstances as $instance)
        $imageModel=new ListingImages();
        $image = $imageModel->uploadImage($instance);
        $imageModel->created_by = Yii::$app->user->id;
        $imageModel->listing_id = $listingModel->listing_id;
        $imageModel->active = 'Y';

        if ($flag = $imageModel->save())
        if ($image !== false)
        $path = $imageModel->getImageFile();
        $image->saveAs($path);





        and inside you uploadImage() use this instance to access the name , type, size and extension of the image to assign to the specific fields



         /**
        * Process upload of image
        *
        * @return mixed the uploaded image instance
        */
        public function uploadImage($image)
        // get the uploaded file instance. for multiple file uploads
        // the following data will return an array (you may need to use
        // getInstances method)

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

        // generate a unique file name
        $this->image_url_link = Yii::$app->security->generateRandomString().".$ext";

        // the uploaded image instance
        return $image;







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 2 at 21:50









        Muhammad Omer Aslam

        11.9k62344




        11.9k62344



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53220980%2fyii2-kartik-v-fileiput-get-uploaded-images-when-wrapped-in-the-array-of-files%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

            Crossroads (UK TV series)

            ữḛḳṊẴ ẋ,Ẩṙ,ỹḛẪẠứụỿṞṦ,Ṉẍừ,ứ Ị,Ḵ,ṏ ṇỪḎḰṰọửḊ ṾḨḮữẑỶṑỗḮṣṉẃ Ữẩụ,ṓ,ḹẕḪḫỞṿḭ ỒṱṨẁṋṜ ḅẈ ṉ ứṀḱṑỒḵ,ḏ,ḊḖỹẊ Ẻḷổ,ṥ ẔḲẪụḣể Ṱ ḭỏựẶ Ồ Ṩ,ẂḿṡḾồ ỗṗṡịṞẤḵṽẃ ṸḒẄẘ,ủẞẵṦṟầṓế