Can't upload files reliably in Yii2 - yii2

I got this method that's intended to upload a file, but sometimes it does so when $this->imageFile is not instantiated. I have no idea why.
public function upload()
{
$path = Url::to('#webroot/images/photos/');
$filename = strtolower($this->username) . '.jpg';
$this->imageFile->saveAs($path . $filename);
return true;
}
I call the method upload() in beforeSave() like this:
public function beforeSave($insert)
{
if(parent::beforeSave($insert)){
if($this->isNewRecord)
{
$this->password = Yii::$app->security->generatePasswordHash($this->password);
}
$this->upload();
return true;
}
else
{
return false;
}
}
I called this method like 100 times with mixed results. I have no idea why this method call doesn't give the same result. It should either never work or always work, but for some reason the code is not deterministic at all.
public function actionCreate()
{
$model = new Member();
$model->imageFile = UploadedFile::getInstance($model, 'imageFile');
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
Another thing, when I use this code, I get a file, but the username is blank so I get a .jpeg file without a name.
public function actionCreate()
{
$model = new Member();
$model->imageFile = UploadedFile::getInstance($model, 'imageFile');
$model->upload();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}

<?php
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
In the If clause you are redirecting to view and $model disappears between requests naturally. But in else you sending $model to view directly. It looks like the buggy section.
The other one, when you move the $model->upload() to actionCreate, you are placing it before If statement but you are loading the post to the model in if clause so, naturally user wasn't loading when you are trying to upload.
If you are prefer to send $model->upload() to action just be sure to call following method before upload. $model->load(Yii::$app->request->post())

Related

Yii2 upload multiple success but save only first value to database

I'm coding a multiple upload function for my website. The upload was successful. But it's only save the first value to my database. Example i upload 3 files name 1.jpg, 2.jpg, 3.jpg. Then it will upload the 3 files successfully but save only the 1.jpg's name to database.
My controllers
public function actionCreate()
{
$model = new Resource3d();
if ($model->load(Yii::$app->request->post())) {
$model->files = UploadedFile::getInstances($model, 'files');
foreach ($model->files as $files){
$files->saveAs('uploads/resource3d/' . $files->baseName . $files->extension);
$model->path = '../web/uploads/resource3d/'. $files->baseName . $files->extension;
$model->name = $files->baseName;
$model->save();
}
return $this->redirect(['index']);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
My models:
public $files;
public function rules()
{
return [
[['name', 'path'], 'string', 'max' => 255],
[['files'], 'file', 'skipOnEmpty' => false, 'maxFiles' => 0],
];
}
Please help.
Thank you.
You are creating single object of your model Resource3d. You need to create multiple object if you want to save multiple records.
Try this :
public function actionCreate()
{
$model = new Resource3d();
if ($model->load(Yii::$app->request->post())) {
$model->files = UploadedFile::getInstances($model, 'files');
foreach ($model->files as $files){
$res_model = new Resource3d();
$res_model->load(Yii::$app->request->post());
$files->saveAs('uploads/resource3d/' . $files->baseName . $files->extension);
$res_model->path = '../web/uploads/resource3d/'. $files->baseName . $files->extension;
$res_model->name = $files->baseName;
$res_model->save();
}
return $this->redirect(['index']);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
This is just an example, change it according to your need.

insert a value from a db to textfield in yii2

i'm still beginner in yii and php.
my problem is:
i want add a value that from db to my textfield.
my db table 'config' have 3 column, id;name;value;
i have tried code like this:
<?= $form->field($model, 'name')->textInput(['value'=>$model->value])->label('name',['class'=>'label-class'])?>
but it didn't show the value.
i want a update form for change value . example: name: title; value: hello world.
Your controller should be something like that:
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
protected function findModel($id)
{
if (($model = Mymodel::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
and in view you simply write
<?= $form->field($model, 'name')->textInput()->label('name',['class'=>'label-class'])?>
Your database values will be in your field.
For simple CRUD you may use GII http://www.yiiframework.com/doc-2.0/guide-start-gii.html

yii2 is not getting id in action after $model->save() and when I click the update item icon

I have a yii2 project, I am developing on my windows localhost and hosting remotely on linux.
Locally (windows) every thing is perfect.
While on linux, I have $model->id = null after $nodel->save(), although data is saved.
public function actionCreate() {
$model = new AppBreakingNews();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
I have tried die($model->id) after the save, it printed null.
Moreover, when I click on the update icon in the grid view, I am facing the same problem.
The AppBreakingNews is as follows:
<?php
namespace app\models\appmodels;
use app\models\BreakingNews;
use yii\behaviors\TimestampBehavior;
class AppBreakingNews extends BreakingNews {
public function behaviors() {
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'created_at',
'updatedAtAttribute' => 'updated_at',
'value' => date('Y-m-d H:i:s'),
],
];
}
}
Notice that appBreakingNews extends the model BreakingNews that is generated by yii2 without any change.
Thanks in advance..
Please try to save model->save(false); because i think it validate something from model file.
public function actionCreate() {
$model = new AppBreakingNews();
if ($model->load(Yii::$app->request->post()) && $model->save(false)) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
or can you please print your model file here.

Auto create folder and upload image in Yii2

I have created ..\frontend\web\uploads.
This is the function Create in PropertiesControllers.php configuration that I have:
public function actionCreate()
{
$model = new Properties();
$date = date('YmdHis');
if ($model->load(Yii::$app->request->post())) {
$file = \yii\web\UploadedFile::getInstance($model, 'url_img');
if (!empty($file))
$model->url_img = $date.$file;
if($model->save())
{
if (!empty($file))
$file->saveAs( Yii::getAlias('#frontend') .'/web/uploads/'.$date.$file);
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('create', ['model' => $model]);
} else {
return $this->render('create', ['model' => $model]);
}
}
It works when uploads is existed. But I want to redirect to new folder in uploads as uploads\img
if (!empty($file))
$file->saveAs( Yii::getAlias('#frontend') .'/web/uploads/img'.$date.$file);
It show error because ../web/uploads/img is not existed.
I don't know to solve this issue. Help me!
I suggest you to create the img folder before $file->saveAs(. In Yii2,you can make use of yii\helpers\FileHelper to create a directory. If your problem is like img folder does not exists inside uploads,then you can create the folder with yii\helpers\FileHelper as
$path = Yii::getAlias('#frontend')."/web/uploads/img";
\yii\helpers\FileHelper::createDirectory($path, $mode = 0775, $recursive = true);
Full code
public function actionCreate() {
$model = new Properties();
$date = date('YmdHis');
if ($model->load(Yii::$app->request->post())) {
$file = \yii\web\UploadedFile::getInstance($model, 'url_img');
if (!empty($file))
$model->url_img = $date . $file;
if ($model->save()) {
if (!empty($file)) {
$path = Yii::getAlias('#frontend') . "/web/uploads/img";
//here you create the folder
if (\yii\helpers\FileHelper::createDirectory($path, $mode = 0775, $recursive = true)) {
$file->saveAs(Yii::getAlias('#frontend') . '/web/uploads/img/' . $date . $file);
}
}
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('create', ['model' => $model]);
} else {
return $this->render('create', ['model' => $model]);
}
}
More info about FileHelper here http://www.yiiframework.com/doc-2.0/yii-helpers-filehelper.html

How to save multiple models in one form in Yii2

I'm doing a form where I enter the data in two models in a single form. My question is how to record data entry in actionCreate () and call these models in a single form.
These are my inscritoController.php
public function actionCreate()
{
$model = new Inscrito();
$modelEmpresa = new Empresa();
if ($model->load(Yii::$app->request->post()) && $model->load(Yii::$app->request->post()) && $modelEmpresa->save() && $modelEmpresa->save())
{
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
'modelEmpresa' => $modelEmpresa,
]);
}
}
And Error:
PHP Notice – yii\base\ErrorException
Undefined variable: modelEmpresa
add this line in your controller
use app\models\Empresa;
Load Yii::$app->request->post() to $modelEmpresa and confirm model call in your controller use app\models\Empresa;
public function actionCreate()
{
$model = new Inscrito();
$modelEmpresa = new Empresa();
if ($model->load(Yii::$app->request->post()) && $modelEmpresa->load(Yii::$app->request->post()) && $model->save() && $modelEmpresa->save())
{
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
'modelEmpresa' => $modelEmpresa,
]);
}
}