I'm working on mvc framework for a website and just want to delete old image from my image folder when i' m editing a post but get this errors:
Warning: unlink(C:\xampp\htdocs\Model View Controller2/public/images/2425.jpg): No such file or directory in C:\xampp\htdocs\Model View Controller2\app\Controller\Admin\ServicesController.php on line 72
This is my controller (when I'm editing the same image old one is deleted; its what i want for different image)
<?php
namespace App\Controller\Admin;
use Core\HTML\BootstrapForm;
use \App;
class ServicesController extends AppController{
public function __construct(){
parent::__construct();
$this->loadModel('Service');
}
public function index(){
$services = $this->Service->all();
$this->render('admin.services.index', compact('services'));
}
public function edit(){
$errors = false;
$this->loadModel('Service');
if (!empty($_POST)) {
if($_FILES['img']['size'] > 1500000){
$errors = "<strong>Ce fichier est trop lourd !</strong>";
}
if(strrchr($_FILES['img']['name'], '.') !== '.jpg'){
$errors = "<strong>L'extension de ce fichier n'est pas un .jpg !</strong>";
}
if($errors != true){
$dir = '../public/images/';
print_r($dir.$_FILES['img']['name']);
unlink($dir.$_FILES['img']['name']);
move_uploaded_file($_FILES['img']['tmp_name'], $dir.$_FILES['img']['name']);
$result = $this->Service->update($_GET['id'], array(
'titre' => $_POST['titre'],
'contenu' => $_POST['contenu'],
'img' => $dir.$_FILES['img']['name']));
}
}
$service = $this->Service->find($_GET['id']);
$services = $this->Service->extract('id', 'titre', 'contenu', 'img');
$form = new BootstrapForm($service);
$this->render('admin.services.edit', compact('services', 'form', 'errors'));
}
public function delete(){
if (!empty($_POST)) {
$result = $this->Service->delete($_POST['id']);
return $this->index();
}
}
}`
this is my view form edtit.php
<center><h1>Editer la page d'accueil Services</h1></center>
<?php if($errors): ?>
<center class="alert alert-danger">
<?= $errors; ?>
</center>
<?php endif; ?>
<form class="edit" action="" method="post" enctype="multipart/form-data">
<?= $form->input('titre', 'Titre'); ?>
<?= $form->input('contenu', 'Message', array('type' => 'textarea', 'rows' => 8)); ?>
<?= $form->input('img', 'image'); ?>
<img src="<?= $servie->img; ?>">
<?= $form->file('img', 'Choisissez une image'); ?>
<button class="btn btn-primary">Sauvegarder</button>
</form>
my ServiceTable.php
<?php
namespace App\Table;
use Core\Table\Table;
class ServiceTable extends Table{
protected $table = 'services';
/**
* Récupère les derniers article
* #return array
*/
public function last(){
return $this->query("
SELECT * FROM services");
}
}
If you want to check if the image already exists with that name, to then delete it before the upload, you could do:
if(file_exists($dir.$_FILES['img']['name'])) {
unlink($dir.$_FILES['img']['name']);
}
To prevent any warnings being thrown.
Related
I am coding a form to get user input and then pass that information to a controller and execute a function based on that, at this point I can not pass the data to the controller using POST method, I get empty vars.
So the Controller function display the view form correctly, I can type on the textboxes, after press submit button I get a setFlash custom message that the parameters are empty. I am using a model class with just two parameters.
a) This is the model:
<?php
namespace app\models;
use Yii;
use yii\base\Model;
class SendmailForm extends Model
{
public $template;
public $emtransport;
/**
* #return array the validation rules.
*/
public function rules()
{
return [
[['template', 'emtransport'], 'required'],
];
}
}
b) This is the view:
<?php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use yii\captcha\Captcha;
$this->title = 'Send Mail';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-contact">
<h1><?= Html::encode($this->title) ?></h1>
<?php if (Yii::$app->session->hasFlash('sminfo')): ?>
<div class="alert alert-success">
<?= Yii::$app->session->getFlash('sminfo');?>
</div>
<?php else: ?>
<p>
SendMail Exercise. Please choose needed options bellow:
</p>
<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(['id' => 'sendmail-form']); ?>
<?= $form->field($model, 'template')->textInput(['autofocus' => true]) ?>
<?= $form->field($model, 'emtransport') ?>
<div class="form-group">
<?= Html::submitButton('Submit', ['class' => 'btn btn-primary', 'value'=>'one', 'name'=>'sendbtn']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
<?php endif; ?>
</div>
And this is the controller's function:
public function actionSendmail(){
$model = new SendmailForm();
if ($model->load(Yii::$app->request->post())) {
$template = Yii::$app->request->post('template');
$emailTransport = Yii::$app->request->post("emtransport");
if($emailTransport=="local"){
for($i=0;$i<=2;$i++){
$xclient = 'client' . $i;
\app\models\User::findByUsername($xclient)->sendMail($template, 'Welcome To XYZ Services', ['accountInfo' => 'www.mysite.com']);
}//end of for loop
Yii::$app->session->setFlash("sminfo", "Emails sent successfully to the Clients");
return $this->refresh();
}//end of second if loop
else{
Yii::$app->session->setFlash("sminfo", "Params could not be verified!. Contact Tech Support");
return $this->refresh();
}
}//end of post if loop
return $this->render('sendmail', [
'model' => $model,
]);
}
The idea is to get the values from the view, at this moment I am getting empty values-
Two parts below:
$template = Yii::$app->request->post('template');
$emailTransport = Yii::$app->request->post("emtransport");
Change the following:
$template = $model->template;
$emailTransport = $model->emtransport;
After editing
public function actionSendmail(){
$model = new SendmailForm();
if ($model->load(Yii::$app->request->post())) {
$template = $model->template;
$emailTransport = $model->emtransport;
if($emailTransport=="local"){
for($i=0;$i<=2;$i++){
$xclient = 'client' . $i;
\app\models\User::findByUsername($xclient)->sendMail($template, 'Welcome To XYZ Services', ['accountInfo' => 'www.mysite.com']);
}//end of for loop
Yii::$app->session->setFlash("sminfo", "Emails sent successfully to the Clients");
return $this->refresh();
}//end of second if loop
else{
Yii::$app->session->setFlash("sminfo", "Params could not be verified!. Contact Tech Support");
return $this->refresh();
}
}//end of post if loop
return $this->render('sendmail', [
'model' => $model,
]);
}
I did some changes to the Controller and now it works, those are them:
//at the beginning of the Controller:
use app\models\SendmailForm;
//two lines changed in the function:
$model->template = $_POST['SendmailForm']['template'];
$model->emtransport = $_POST['SendmailForm']['emtransport'];
That's all I needed. Best regards
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
This is my view file and it has one form that should post a file with a text variable data of 0000000005. But for some reason the load function inside the controller does not populate these data.
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* #var $this yii\web\View */
/* #var $model backend\models\customs\UploadForm */
/* #var $form ActiveForm */
?>
<div class="vendor_file_upload_form">
<?php $form = ActiveForm::begin(
['id' => 'form-files'],
['options' => ['enctype' => 'multipart/form-data']]
); ?>
<?= $form->field($model, 'AppFile')->fileInput() ?>
<?= $form->field($model,'apid')->textInput(); ?>
<div class="form-group">
<?= Html::submitButton(Yii::t('app', 'Submit'), ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div><!-- vendor_file_upload_form -->
This is my controller
public function actionFiles($id=null)
{
$model = new UploadForm();
if ($model->load(Yii::$app->request->post()))
{
$model->AppFile = UploadedFile::getInstance($model, 'AppFile');
if ($model->upload())
{
\Yii::$app->getSession()->setFlash('success', 'File has been successfully uploaded.');
return $this->redirect(['index']);
}
else
{
\Yii::$app->getSession()->setFlash('error', 'Wrong File Format , Try proper format.');
return $this->redirect(['index']);
}
}
}
I found that for some reason Load data does not load all the posted form parameters. I have spent 3 hours and I am still unable to understand why my form data is not being transferred properly.
I checked the Payload and I found following which means my data is coming fine but load function is not loading properly.
------WebKitFormBoundaryZfszVA0IZuj02ZFT Content-Disposition: form-data; name="_csrf-backend"
UEZaLmZ4MzEWExBjLz8LSWAnHG9SGgFhaBcqbycRZWc1dGtCAD9JYg==
------WebKitFormBoundaryZfszVA0IZuj02ZFT Content-Disposition: form-data; name="UploadForm[AppFile]"
------WebKitFormBoundaryZfszVA0IZuj02ZFT Content-Disposition: form-data; name="UploadForm[AppFile]"; filename="falcon-wallpaper.jpg"
Content-Type: image/jpeg
------WebKitFormBoundaryZfszVA0IZuj02ZFT Content-Disposition: form-data; name="UploadForm[apid]"
0000000005
------WebKitFormBoundaryZfszVA0IZuj02ZFT--
EDIT:
Below is my model file,
<?php
/**
* Created by PhpStorm.
* Date: 1/8/2017
* Time: 9:52 PM
*/
namespace backend\models\customs;
use backend\models\ApplicationFiles;
use yii\base\Model;
use yii\web\UploadedFile;
/**
* UploadForm is the model behind the upload form.
*/
class UploadForm extends Model
{
/**
* #var UploadedFile
*/
public $AppFile; //files which needs to be uploaded
public $apid; //application_id
/**
* #return array the validation rules.
*/
public function rules()
{
return [
[['apid'], 'required','message'=>'No Application Id found'],
[['AppFile'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg'],
];
}
public function upload()
{
//upload on the backed/uploads folder with time stamp as the file name
if ($this->validate()) {
$File_name = time() . '.' . $this->AppFile->extension;
if($this->AppFile->saveAs(\Yii::$app->basePath.'/uploads/' .$File_name ))
{
$model = new ApplicationFiles();
$model->name = $File_name;
$model->path = \Yii::$app->basePath.'/uploads/' .$File_name;
$model->application_id = $this->apid;
// $model->type =
$model->save();
}
return true;
}
else
{
return false;
}
}
}
?>
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
}
}
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,