File upload in Cakephp 3.3 - image

I am trying to store an image in cakephp 3.0. I am only able to save the filename in db, however, unable to store the actual file on the server. Need help
Form:
echo $this->Form->create('User', array('url' => array('action' => 'create'), 'enctype' => 'multipart/form-data'));
echo $this->Form->input('upload', array('type' => 'file'));
Images controller:
*/
public function add()
{
$image = $this->Images->newEntity();
//Check if image has been uploaded
if(!empty($this->request->data['Images']['upload']['name']))
{
$file = $this->request->data['Images']['upload']; //put the data into a var for easy use
$ext = substr(strtolower(strrchr($file['name'], '.')), 1); //get the extension
$arr_ext = array('jpg', 'jpeg', 'gif'); //set allowed extensions
//only process if the extension is valid
if(in_array($ext, $arr_ext))
{
//do the actual uploading of the file. First arg is the tmp name, second arg is
//where we are putting it
move_uploaded_file($file['tmp_name'], WWW_ROOT . 'img' . $file['name']);
//prepare the filename for database entry
$this->data['Images']['image'] = $file['name'];
}
}
if ($this->request->is('post')) {
$image = $this->Images->patchEntity($image, $this->request->data);
if ($this->Images->save($image)) {
$this->Flash->success('The image has been saved.');
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error('The image could not be saved. Please, try again.');
}
}
$this->set(compact('image'));
$this->set('_serialize', ['image']);
}

For those who are looking for the answer just modify this line :
move_uploaded_file($file['tmp_name'], WWW_ROOT . 'img' .DS. $file['name']);
DS is a Directory Separator.

Welcome on stackoverflow!
Please check this question:
cakePHP 3.0 uploading images
This will help you, it's a good plugin for uploading images:
http://cakemanager.org/docs/utils/1.0/behaviors/uploadable/

Related

Storage disk S3 can not put file when deploy to server

I'm having a problem using Storage::disk('s3')->put() to store files to AWS S3 in laravel.
I am writing an api to upload files, everything works fine in the local environment, but when I deploy to the server it doesn't work, and the server returns a 500 error and there is no data in response
This is my code:
public static function uploadFile($file = null, $folder = null){
try {
$bucket = '';
if (empty($file->getClientOriginalName()) || empty($file->getSize())) return ResponseHelpers::clientBEErrorResponse('File Empty !', '');
if ((substr($folder, 0, 1) != '/') && !empty($folder)) $folder = '/' . $folder;
$ex_file = explode('.', $file->getClientOriginalName());
$extent = strtolower($ex_file[(count($ex_file) - 1)]);
unset($ex_file[(count($ex_file) - 1)]);
if (in_array($extent, ['jpg', 'jpeg', 'png', 'gif', 'xlsx', 'docs', 'pdf', 'docx', 'ppt', 'pptx'])) {
$uploadDir = $bucket . $folder.'/'. Str::slug($ex_file[0]).'-'.time().'.'.$extent;
if (in_array($ex_file[0], ['jpg', 'jpeg', 'png'])){
$image = \Image::make(file_get_contents($file));
$upload = Storage::disk('s3')->put($uploadDir, $image->encode('jpeg', 50));
} else{
$upload = Storage::disk('s3')->put($uploadDir, file_get_contents($file));
}
if ($upload){
return ResponseHelpers::showResponse([
'preview' => env('AWS_URL').$uploadDir,
'path' => $uploadDir
], '');
}
return ResponseHelpers::serverErrorResponse();
} else {
return ResponseHelpers::clientBEErrorResponse('Please Select File Type JPG, JPEG, PNG, GIF, XLSX, DOCS Too Upload', '');
}
} catch (\Exception $ex) {
return ResponseHelpers::serverErrorResponse($ex->getMessage(), '');
}
}
I can't even catch the error using try catch.
I tried using this function to upload files when using form with html in blade file view and strangely it still works. Looks like it only crashes when it's an API. I have checked and compared the input data of both ways, they are exactly the same.
Everything stops working when running here: Storage::disk('s3')->put($uploadDir, file_get_contents($file))
Response is completely empty and doesn't have any data or anything
Please check for me. Thanks

Multiple Image Upload in Laravel tweak to add additional field

I have a need to upload multiple images. This code below works well. This is using Intervention Image plugin. I am trying to customise this code to add another field which is a ForeignKey value to the parent of this image model. $request has the value coming from form. How to save it along with images?
The value is:
$request('vehicle_id')
How can tweak the below method so as save includes this vehicle_id as well?
public function uploadImage(Request $request)
{
$request->validate([
'image' => 'required',
'image.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048'
]);
//check if image exist
if ($request->hasFile('image')) {
$images = $request->file('image');
// create new directory for uploading image if doesn't exist
if( ! File::exists('images/'.auth()->user()->id)) {
$org_img = File::makeDirectory('images/'.auth()->user()->id, 0777, true);
}
// loop through each image to save and upload
foreach($images as $key => $image) {
//create new instance of Photo class
$newPhoto = new $this->photo;
//get file name of image and concatenate with 4 random integer for unique
$filename = rand(1111,9999).time().'.'.$image->getClientOriginalExtension();
//path of image for upload
$org_path = 'images/'.auth()->user()->id . $filename;
$newPhoto->image = 'images/'.auth()->user()->id.$filename;
//don't upload file when unable to save name to database
if ( ! $newPhoto->save()) {
return false;
}
// upload image to server
if ($org_img == true) {
Image::make($image)->fit(900, 500, function ($constraint) {
$constraint->upsize();
})->save($org_path);
}
}
}
return redirect('/home')->with('success','Images Uploaded');
}
I found solution
public function uploadImage(Request $request)
{
$request->validate([
'image' => 'required',
'image.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048',
'vehicle' => 'required'
]);
//check if image exist
if ($request->hasFile('image')) {
$images = $request->file('image');
// create new directory for uploading image if doesn't exist
if( ! File::exists('images/'.auth()->user()->id.'/')) {
$org_img = File::makeDirectory('images/'.auth()->user()->id.'/', 0777, true);
}
// loop through each image to save and upload
foreach($images as $key => $image) {
//create new instance of Photo class
$newPhoto = new $this->photo;
//get file name of image and concatenate with 4 random integer for unique
$filename = rand(1111,9999).time().'.'.$image->getClientOriginalExtension();
//path of image for upload
$org_path = 'images/'.auth()->user()->id.'/' . $filename;
$newPhoto->image = 'images/'.auth()->user()->id.'/' . $filename;
$newPhoto->vehicle = $request->input('vehicle');
//don't upload file when unable to save name to database
if ( ! $newPhoto->save()) {
return false;
}
// upload image to server
Image::make($image)->fit(900, 500, function ($constraint) {
$constraint->upsize();
})->save($org_path);
}
}
return redirect('/home')->with('success','Images Uploaded');

ContextErrorException in Symfony 3

I am trying to upload images in SF3, and I have this error when I upload:
Missing argument 2 for Symfony\Component\HttpFoundation\File\UploadedFile::__construct().
This is the part of my entity where is the error is located (line 9 here):
public function preUpload()
{
// if there is no file (optional field)
if (null === $this->image) {
return;
}
// $file = new File($this->getUploadRootDir() . '/' . $this->image);
$file = new File($this->getUploadRootDir() .'/' . $this->image);
$uploadedfile = new UploadedFile($this->getUploadRootDir() .'/' . $this->image);
// the name of the file is its id, one should just store also its extension
// to make clean, we should rename this attribute to "extension" rather than "url"
$this->url = $file->guessExtension();
// and we generate the alt attribute of the <img> tag,
// the value of the file name on the user's PC
$this->alt = $uploadedfile->getClientOriginalName();
}
Then my controller :
public function mediaEditAction(Request $request)
{
$media = new Media();
$form = $this->createForm(MediaType::class, $media);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$file = $media->getImage();
$fileName = md5(uniqid()).'.'.$file->guessExtension();
$file->move(
$this->getParameter('images_directory'),
$fileName
);
$media->setImage($fileName);
$em = $this->getDoctrine()->getManager();
$em->persist($media);
$em->flush();
$request->getSession()->getFlashBag()->add('Notice', 'Photo added with success');
// redirection
$url = $this->generateUrl('medecin_parametre');
// permanent redirection with the status http 301
return $this->redirect($url, 301);
} else {
return $this->render('DoctixMedecinBundle:Medecin:mediaedit.html.twig', array(
'form' => $form->createView()
));
}
}
It seems like you are doing unnecessary work and making this a little more complicated than it probably needs to be. Have you followed this Symfony guide for How to Upload Files?
In the meantime, it seems like the image name is what is in $this->image so you can just pass that as the 2nd constructor argument.
$uploadedfile = new UploadedFile($this->getUploadRootDir().'/'.$this->image, $this->image);
However, UploadedFile should probably only come from the form submission, and in your entity you would want to use File instead - like so:
use Symfony\Component\HttpFoundation\File\File;
$uploadedfile = new File($this->getUploadRootDir() .'/' . $this->image);

Laravel and DropzoneJS file uploaded with different extension

I created a form here with Laravel and DropzoneJS and I tried uploading a Gimp file (.xcf) and when it is uploaded it is saved in S3 as the following
<random-name>.
without the "xcf" extension just random name ending with a dot.
Also, I created a text file and renamed it to test.xcf when I tried uploading that file it was uploaded with the .txt extension.
Here is my UploadController.php which handles the upload:
<?php
namespace App\Http\Controllers;
use App\Upload;
use Illuminate\Http\Request;
class UploadController extends Controller
{
public function upload(Request $request)
{
$originalName = $request->file('file')->getClientOriginalName();
$fileSize = $request->file('file')->getClientSize();
$path = $request->file('file')->store('documents');
$explode = explode('documents/', $path);
$name = $explode[1];
$uniqueId = $this->generateUniqueId();
$upload = new Upload();
$upload->unique_id = $uniqueId;
$upload->name = $name;
$upload->path = $path;
$upload->original_name = $originalName;
$upload->size = $fileSize;
if ($upload->save())
{
return response()->json([
'original_name' => $originalName,
'size' => $fileSize,
'url' => env('AWS_URL') . $path,
'id' => $uniqueId,
'status' => 'OK'
]);
}
return response()->json(['status' => 'BAD', 'message' => 'There was a problem saving your file.']);
}
public function generateUniqueId()
{
$result = '1';
$result .= rand(100000000, 999999999);
while(Upload::where('unique_id', '=', $result)->first())
{
$result = '1';
$result .= rand(100000000, 999999999);
}
return $result;
}
}
I've got no idea why it's doing that.
I suggest, you generate your own hash for filename, like I do in this code:
$file = $request->file('csv');
$path = $file->storeAs(
'csv',
md5($file->getClientOriginalName()) . $file->getClientOriginalExtension(),
's3'
);
You can also add uniqid() to md5 input
If you're using laravel 5+ then you should get the extension also using this.
$extension = $file->getClientOriginalExtension();
This will work fine.

How to upload multiple images in php

I am developing a module of epaper in codeigniter(PyroCMS).
I want to know how can I upload multiple images ar once.
Can anyone guide me in uploading multiple images?
I tried but I only found code for uploading single image which I have already used in news module.
In the view file give this code for image upload:
echo form_label('Multi Images','',$label_attr);
echo form_upload($multi_photo_attr);
where
$multi_photo_attr = array(
'id' => "cat_multi_images",
'class' => "multi",
'name' => "cat_multi_images[]",
'maxlength' => "25",
'multiple' => "multiple"
);
Now you need to create a folder in the root directory where your photos will be uploaded.
After that in the controller's method you need to store the path to that folder in a variable.This variable will be used to upload the images in the folder.
Next,get the names of all the images in a array something like this:
foreach($_FILES["cat_multi_images"] as $key => $value)
{
$i=0;
foreach($value as $key1 => $value1)
{
$multi_photo_array[$i][$key] = $value1;
$i++;
}
After that for every array element,i.e.,for every image run the below code to upload it:
function UploadFile($files,$path)
{
$extensions = array('jpeg','JPEG','gif','GIF','png','PNG','jpg','JPG','pdf','PDF','ZIP','zip','rar','RAR','html','HTML','TXT','txt','doc','docx','DOC','DOCX','ppt','PPT','pptx','PPTX','xlsx','XLSX','xls','XLS','exe','EXE','mp3','MP3','wav','WAV','m4r','M4R','mpeg','MPEG','mpg','MPG','mpe','MPE','mov','MOV','avi','AVI',);
$destination = $path.$files["name"];
//print_r($destination);exit;
// GET FILE PARTS
$fileParts = pathinfo($files['name']);
$file_name = $files['name'];
$file_name_only = $fileParts['filename'];
$file_name_only = preg_replace('/[^a-zA-Z0-9]/','',$file_name_only);
$file_extention = $fileParts['extension'];
$Count = 0;
$destination = $path.$file_name_only.".$file_extention";
$file_name = $file_name_only.".$file_extention";;
// THIS SHOULD KEEP CHECKING UNTIL THE FILE DOESN'T EXISTS
while( file_exists($destination))
{
$Count += 1;
$destination = $path. $file_name_only."-".$Count.".$file_extention";
$file_name = $file_name_only."-".$Count.".$file_extention";
}
$fileextension='';
$filename='';
if(!empty($files))
{
$filename=$files['name'];
$fileextension=substr($filename,strpos($filename,".")+1);
if(in_array($fileextension,$extensions))
{
$uploadstatus=move_uploaded_file($files["tmp_name"],$destination);
if($uploadstatus)
{
return $file_name;
}
else
{
return false;
}
}
else
{
return false;
}
}
}
Just copy the above code.It should work as it is made for a general case by me!You can copy that code in your model file and call it in the controller like this :
$pr_photo_data = $this->admin_model->UploadFile($value,$targetPath_images);
$photo_list[] = $pr_photo_data;
And then store every image in the database
foreach($photo_list as $image)
{
$pro_image["cat_multi_images"] = $image;
$pro_retId = $this->admin_model->add_multipic_cat($pro_image);
}
where
function add_multipic_cat($data)
{
$retId = $this->database->query_insert("photo", $data);
return $retId;
}
Be careful.Take care and do every step accurately
check this one
https://github.com/blueimp/jQuery-File-Upload/wiki/jQuery-File-Upload,---Multi-file-upload-with-CodeIgniter
Struggling To Use PyroCMS Files Library To Upload Multiple Files

Resources