I am new to Yii. I am using this code
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>
<?= $form->field($model, 'description')->textarea(['rows' => 6]) ?>
<?= $form->field($model, 'image')->fileInput(['type' => 'file']) ?>
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
When i try to print post data in my controller then image field is going blank;
If i print through $_FILES then file data is showing.
Please let me know how to get image in post method.
Step 1 :
In your model file define one variable.
public $uploadedImage;
Step 2 :
In your controller,
$model->uploadedImage = UploadedFile::getInstance($model, 'image');
$model->image = $model->uploadedImage->name;
After save() method write this to store image
$model->uploadedImage->saveAs('YOUR_WEBDIR_IMAGES_FOLDER/' . $model->uploadedImage->baseName . '.' . $model->uploadedImage->extension);
[If the above solution doesn't work then try this. :
Define another variable.
public $tempVarforImage;
In your controller
$model->tempVarforImage = $model->uploadedImage->name;
$model->image = $model->tempVarforImage;
(Because once I faced the issue in confliction of 'image' field from database and yii2 based 'image' variable)]
Create UploadForm model
namespace app\models;
use yii\base\Model;
use yii\web\UploadedFile;
class UploadForm extends Model{
public $image;// Image name
public function rules()
{
return [
[['image'], 'file'/* , 'skipOnEmpty' => false *//* , 'extensions' => 'png, jpg' */],
];
}
public function upload($fileName)
{
if ($this->validate()) {
$this->image->saveAs($fileName);
return true;
} else {
return false;
}
}
}
Controller code
Add at top of your file
use app\models\UploadForm;
use yii\web\UploadedFile;
Add this in your function
$model = User();
if ($model->load(Yii::$app->request->post())) {
$model1 = new UploadForm();
$model1->image = UploadedFile::getInstance($model, 'image');
$fileName = $model1->image->baseName.'_'.time();
$extension = $model1->image->extension;
$fileName = $fileName.'.'.$extension;
$filePath = WEBSITE_SLIDER_ROOT_PATH.$fileName;
if ($model1->upload($filePath)) {
//Save in database
}
}
Related
I'm trying to learn how to upload an image file in Yii. I'm using this code
<?php
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
<?= $form->field($model, 'imageFile')->fileInput() ?>
<button>Submit</button>
<?php ActiveForm::end() ?>
in ProjectFile/views/site/upload.php file.
The problem is in
<?= $form->field($model, 'imageFile')->fileInput() ?>
$model gives me a red underline. I have looked many examples and all of them wrote the like this.
What I need to do stop this problem?
Edit:
Is inside the controller/SiteController.php
// function for upload
public function actionUploadImage()
{
$model = new UploadImageForm();
if (Yii::$app->request->isPost) {
$model->imageFile = UploadedFile::getInstance($model, 'imageFile');
if ($model->upload()) {
// file is uploaded successfully
return;
}
}
return $this->render('upload', ['model' => $model]);
}
Is inside of models/UploadImageForm.php
<?php
namespace app\models;
use yii\base\Model;
use yii\web\UploadedFile;
class UploadImageForm extends \yii\base\Model
{
public $imageFile;
// gives rules of how to upload picture
public function rules(){
return [
[['imageFile'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg'],
];
}
// uploads picture
public function upload(){
if($this->validate()){
$this->imageFile->saveAs('uploads/' . $this->imageFile->baseName . '.' . $this->imageFile->extension);
}
}
}
Please make sure that model has attribute/field called "imageFile"
Check your editor do you get red line on your editor then its your editor related issue
The same happened to me, your view code is pretty fine. Mine was also the same, I made it work by using these lines in model function:
$imageFile= UploadedFile::getInstances($model, 'imageFile')[0];
$imageFile->saveAs('uploads/' . $imageFile->baseName . '.' . $imageFile->extension);
and in controller action:
$model->imageFile= UploadedFile::getInstances($model, 'imageFile')[0];
In views\upload.php the red underline is shown because the system can't find the $model. While running, program will connect $model to controller. So the red underline is not a problem for php files.
When I click on the Signup button I receive the following error: Array to string conversion.
I think that the error occurs when I call fileInput() method but i don't know how to solve it.
This is the partial code of the view
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<?= $form->field($model, 'email') ?>
<?= $form->field($modelUpload, 'imageFile')->fileInput() ?>
<div class="form-group">
<?= Html::submitButton('Signup', ['class' => 'btn', 'name' => 'signup-button']) ?>
</div>
<?php ActiveForm::end(); ?>
While this is the code for the controller:
<?php
class SiteController extends Controller {
/**
* Signs user up.
*
* #return mixed
*/
public function actionSignup() {
$model = new SignupForm();
$modelUpload = new UploadForm();
if ($model->load(Yii::$app->request->post()) && $modelUpload->load(Yii::$app->request->post())) {
$modelUpload->imageFile = UploadedFile::getInstances($modelUpload, 'imageFile');
if ($user = $model->signup()) {
if (Yii::$app->getUser()->login($user) && $modelUpload->upload()) {
return $this->goHome();
}
}
}
return $this->render('signup', [
'model' => $model,
'modelUpload' => $modelUpload,
]);
}
}
This is the code of the model. It's the same of the official documentation.
<?php
class UploadForm extends Model {
/**
* #var UploadedFile
*/
public $imageFile;
public function rules() {
return [
[['imageFile'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg'],
];
}
public function upload() {
if ($this->validate()) {
$this->imageFile->saveAs('uploads/' . $this->imageFile->baseName . '.' . $this->imageFile->extension);
return true;
} else {
return false;
}
}
}
?>
Errors:
Instant Solution
Change your line inside the actionSignup() from below
UploadedFile::getInstances($modelUpload, 'imageFile');
to
UploadedFile::getInstance($modelUpload, 'imageFile');
Reason
It's only a single file you are uploading not multiple files so getInstances() should be getInstance()
About
getInstance : Returns an uploaded file for the given model
attribute. The file should be uploaded using
[[\yii\widgets\ActiveField::fileInput()]]
getInstances: Returns all uploaded files for the given model
attribute.
if you want to upload multiple files - having'maxFiles' > 1 in your model's FileValidator rules - change your attribute name from:
<?= $form->field($modelUpload, 'imageFile')->fileInput() ?>
to
<?= $form->field($modelUpload, 'imageFile[]')->fileInput() ?>
read this:
https://www.yiiframework.com/doc/guide/2.0/en/input-file-upload#uploading-multiple-files
I have two model A and B , In Model A form append Model B from dynamically,but when am click create button ,I am not getting model B data in POST.where I am doing wrong please help..
Model A Form(view)
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\Url;
use yii\web\View;
$script = <<< JS
$.ajax({
type :'POST',
data: {total_form:1},
cache : true,
url : '/stag_str/web/index.php/activities/create',
success : function(data) {
$('.p_scents').append(data);
},
});
JS;
$this->registerJs($script);
?>
<div class="currency-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'currency_name')->textInput(['maxlength' => true,'style'=>'width:150px']) ?>
<div class="p_scents"></div>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
Model A controller
public function actionCreate(){
$model = new Currency();
if ($model->load(Yii::$app->request->post())) {
print_r($_POST);exit;
return $this->redirect(['view', 'id' => $model->currency_id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
Model B Form which I am rendering through Ajax call
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* #var $this yii\web\View */
/* #var $model app\models\Activities */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="activities-form">
<?php $form = ActiveForm::begin(['id' => 'activity' ]); ?>
<?= $form->field($model, 'activity_name')->textInput(['maxlength' => true]) ?>
<?php ActiveForm::end(); ?>
</div>
Model B action using renderAjax
public function actionCreate()
{
$model = new Activities();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->activity_id]);
} elseif ( Yii::$app->request->isAjax ){
return $this->renderAjax('_form', [
'model' => $model,
]);
}
}
I am not getting Model B form data while saving Model form A..
Ideally, when you are dealing with AJAX Calls from View. you Must provide an ID to your form as below;
$form = ActiveForm::begin([ 'id' => 'activity-form' ]);
when you handle any kind of request inside the Controllers, you must first check the type of request when you re-render your form as below
elseif ( Yii::$app->request->isAjax ){
return $this->renderAjax('_form', [
'model' => $model,
]);
}
when i upload multiple files in Yii2, i am getting following error and cannot insert data into database:
finfo_file(C:\xampp\tmp\phpCACD.tmp): failed to open stream: No such
file or directory
controller file:
public function actionGallery($id)
{
$model = new Gallery();
if (Yii::$app->request->post()) {
$model->imageFiles = UploadedFile::getInstances($model,'imageFiles');
foreach ($model->imageFiles as $file) {
$imageName = Yii::$app->security->generateRandomString();
$model->added_date = date('Y-m-d');
$model->emp_id = $id;
$file->saveAs('uploads/emp/' . $imageName . '.' . $file->extension);
$originalFile = EMP_PROFILE_ORIGINAL.$imageName.'.'.$file->extension;
$thumbFile = EMP_PROFILE_THUMB.$imageName.'.'.$file->extension;
Image::thumbnail($originalFile, 200, 200)->save($thumbFile, ['quality' => 80]);
$model->save();
}
}
return $this->render('gallery', [
'gal' => $model
]);
}
view file:
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\grid\GridView;
?>
<div class="posts-form">
<div class="wrapper-md">
<div class="row">
<div class="col-sm-8">
<div class="panel panel-default">
<div class="panel-body">
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>
<?= $form->field($gal, 'imageFiles[]')->fileInput(['multiple' => true, 'accept' => 'image/*']) ?>
<div class="form-group">
<button class="btn btn-success">Submit</button>
<a class="btn btn-default" href="<?=\Yii::$app->urlManager->createUrl('post')?>">Cancel</a>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
</div>
</div>
</div>
</div>
but i am getting above error. I cannot find the solution for this.
first, in model you must have 2 variable that will save the images and the name of it.
`
* #property string $image_name
*/
class Gallery extends \yii\db\ActiveRecord
{
**public $fileImage=[];**
public static function tableName(){
`
in this case I use $image_name that is one of my model column, and $fileImage, $fileImage is an array that will be used to upload the image,
:)
then in controller
$model = new Gallery(); // this variable is only used to check if everything is valid
if ($model->load(Yii::$app->request->post())) {
$model->fileImage = UploadedFile::getInstances($model,'fileImage');
$a=0;
foreach ($model->fileImage as $file) {
$a++;
$model1 = new Gallery();
$file->saveAs("images/test".$a.".".$file->extension);
$model1->image_url="images/test.".$a.".".$file->extension;
$model1->image_name = "".$a;
$model1->save();
}
return $this->redirect(['index']);
} else {
return $this->render('create', [
'model' => $model,
]);
}
I think thats all. . .
You can use
$sql = 'INSERT INTO `table`(`id`, `col1`, `col2`, `path`) VALUES (Null,"'.($model2->col1).'","'.($model2->col2).'","'.($model2->path).'")';
$command = \Yii::$app->db->createCommand($sql);
$command->execute();
instead of $model->save();
I made an example,
so the whole code in controller would be:
public function actionCreate()
{
$model = new Planet();
if ($model->load(Yii::$app->request->post()) ) {
$model->file = UploadedFile::getInstances($model, 'file');
foreach ($model->file as $file) {
$model2 = new Planet();
$model2->load(Yii::$app->request->post());
$model2->path='uploads/' . $file;
$sql = 'INSERT INTO `planet`(`id`, `name`, `s_id`, `path`) VALUES (Null,"'.($model2->name).'","'.($model2->s_id).'","'.($model2->path).'")';
$command = \Yii::$app->db->createCommand($sql);
$command->execute();
$file->saveAs('uploads/' . $file->baseName . '.' . $file->extension);
}
return $this->render('view', [
'model' => $model,
]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
It works for me.
edit: also you can use $model2->save(false); It worked in my case.
Call $model->save()
before
$model->file->saveAs();
I was having the exact same problem
*I think you forget to create uploads and emp folder or maybe you use wrong folder name, please check your folder name...
*If you want to save the name of that file, you should use different variable (two variable) that will be used to save the images and the name of that images,
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.