I have a file attachment feature in a Laravel package. I want the uploaded attachment to save in the project directory using the package and NOT within the package. Currently, the file is uploaded into the package uploads directory instead of the project uploads directory. Any suggestions on how to save this file in the right location?
Controller:
$attachment->spot_buy_item_id = $id;
$attachment->name = $_FILES['uploadedfile']['name'];
$attachment->created_ts = Carbon::now();
$ds = DIRECTORY_SEPARATOR; //1
$storeFolder = '../../../resources/uploads';
if (!empty($_FILES)) {
$tempFile = $_FILES['uploadedfile']['tmp_name']; //3
$extension = pathinfo($_FILES['uploadedfile']['name'], PATHINFO_EXTENSION);
$attachment_hash = md5($tempFile);
$new = $attachment_hash.'.'.$extension;
// complete creating attachment object with newly created attachment_hash
$attachment->hash = $new;
$attachment->save();
$targetPath = dirname( __FILE__ ) . $ds. $storeFolder . $ds; //4
$targetFile = $targetPath. $new; //5
move_uploaded_file($tempFile,$targetFile); //6
chmod($targetFile, 0777);
}
else
{
return "error";
}
Service Provider (I thought publishing the uploads folder might work - nope.)
public function boot()
{
require __DIR__ . '/Http/routes.php';
$this->loadViewsFrom(__DIR__ . '/resources/views', 'ariel');
$this->publishes([
__DIR__ . '/resources/uploads' => public_path('vendor/uploads'),
], 'public');
$this->publishes([
__DIR__ . '/../database/migrations' => database_path('migrations')], 'migrations');
}
HERE WE GO. I used the (well-documented) the Storage facade to work with the local filesystem (project).
https://laravel.com/docs/5.1/filesystem
$attachment->spot_buy_item_id = $id;
$attachment->name = $_FILES['uploadedfile']['name'];
$attachment->created_ts = Carbon::now();
$ds = DIRECTORY_SEPARATOR; //1
$storeFolder = 'uploads';
if (!empty($_FILES)) {
$tempFile = $_FILES['uploadedfile']['tmp_name']; //3
$extension = pathinfo($_FILES['uploadedfile']['name'], PATHINFO_EXTENSION);
$attachment_hash = md5($tempFile);
$new = $attachment_hash.'.'.$extension;
// complete creating attachment object with newly created attachment_hash
$attachment->hash = $new;
$attachment->save();
$tmpPath = $storeFolder . $ds;
$targetFile = $tmpPath . $new; //5
Storage::disk('local')->put($targetFile, file_get_contents($request->file('uploadedfile')));
}
else
{
return "error";
}
Related
I'm just starting out with Laravel and trying to get file uploads working using Dropzone JS. I can upload files successfully, but they're landing in app/Http/Controllers, where they're not then publicly accessible.
It seems to be treating this directory as the root, so if I specify /uploads as the folder then they'll go in app/Http/Controllers/uploads (which is obviously no good either). Using ..s doesn't seem to have any effect.
This is my store method for the file uploads:
$ds = DIRECTORY_SEPARATOR;
$storeFolder = '';
if ( ! empty($_FILES)) {
$tempFile = $_FILES['file']['tmp_name'];
$targetPath = dirname( __FILE__ ) . $ds. $storeFolder . $ds;
$targetFile = $targetPath. $_FILES['file']['name'];
move_uploaded_file($tempFile,$targetFile);
}
I've also tried a number of other methods I found (below) but I get 500 errors in Chrome's element inspector with those.
From official docs
$path = $request->file('file')->store('uploads');
From a tutorial I found
$file = $request->file('file');
$destinationPath = '/';
$file->move($destinationPath,$file->getClientOriginalName());
From another tutorial
$uploadedFile = $request->file('file');
$filename = time().$uploadedFile->getClientOriginalName();
Storage::disk('local')->putFileAs(
'/'.$filename,
$uploadedFile,
$filename
);
The current method seems fine but just needs to store files in public/uploads.
Use this path instead:
$targetPath = public_path().'/uploads/';
I also suggest making a perfect route for our storage path so when someone adds hostname/storage it will not show your directory to someone only files can be accessible
Route::get('storage/{filename}', function ($filename)
{
$path = storage_path('public/' . $filename);
if (!File::exists($path)) {
abort(404);
}
$file = File::get($path);
$type = File::mimeType($path);
$response = Response::make($file, 200);
$response->header("Content-Type", $type);
return $response;
});
I used to store my upload files (images) in my public folder but this time I want to store them in my storage folder and I get this error
Can't write image data to path (C:\laragon\www\mynewsite\storage\images/aboutimage-1522481830.png)
Error comes from this line (where I use intervention/image package)
Image::make($image)->resize(1200, 600)->save($location);
My function:
if ($request->hasFile('image')) {
$image = $request->file('image');
$filename = 'aboutimage' . '-' . time() . '.' . $image->getClientOriginalExtension();
$location = storage_path('images/' . $filename);
Image::make($image)->resize(1200, 600)->save($location);
$oldFilename = $indexabout->image;
$indexabout->image = $filename;
Storage::delete($oldFilename);
}
any idea?
UPDATE
My files will upload in root/storage folder instead of root/storage/app/public/images
why is that?
Update 2
I changed my function to code below and it's uploading where it suppose to upload but it does not delete the old image
if ($request->hasFile('image')) {
$image = $request->file('image');
$filename = '/aboutimage' . '-' . time() . '.' . $image->getClientOriginalExtension();
$location = storage_path('app/public/images' . $filename);
Image::make($image)->resize(1200, 600)->save($location);
$oldFilename = $indexabout->image;
$indexabout->image = $filename;
Storage::delete($oldFilename);
}
SOLVED
here is final code:
if ($request->hasFile('image')) {
$image = $request->file('image');
$filename = 'aboutimage' . '-' . time() . '.' . $image->getClientOriginalExtension();
$location = storage_path('app/public/images/' . $filename); // root storage path
Image::make($image)->resize(1200, 600)->save($location);
Storage::delete('images/' . $indexabout->image); //public storage path
$indexabout->image = $filename;
}
Basically I gave Root/Storage path to store data and Public/Storage path for deleting them in update method.
I try to implement a very simple scale function while uploading the file to the server. My host has 5.5.38 php version and gd is included and is 2.1.0 version.
The upload function worked until I tried to use the scale function. Obviously I am doing the wrong way but honestly I don't know what I am doing wrong and after a lot of research i am here to ask for your help..
This is the code that i use to upload file and scale it:
$id2 = $_POST['hiddenId'];
$ds = DIRECTORY_SEPARATOR;
// CREATE DIRECTORY
$dir = "gallery/g";
$dir .= $id2;
$dir .= "/";
$dir2 = '../../' . $dir;
if (!mkdir($dir2,0777,true));
$foldername = $dir;
if (!empty($_FILES)) {
/* DATA FOR DATABASE */
$images = '';
$images .= $dir;
$images .= $_FILES['file']['name'];
/* UPLOAD FILE */
$fileupload = basename( $_FILES['file']['name']);
$fileType = $_FILES['file']['type'];
$fileSize = $_FILES['file']['size'];
$tempFile = $_FILES['file']['tmp_name'];
//$targetPath = dirname( __FILE__ ) . $ds . $foldername . $ds;
// FILE DIRECTORY
$targetPath = '../../' . $foldername;
// TRY TO SCALE IMAGE
$imagenew = ''; // NEW VARIABLE
$imagenew = imagecreatefromjpeg($tempFile); // PASSING THE TEMPFILE
$imagescaled = imagescale($imagenew, 800); // SCALING THE FILE
$targetFile = $targetPath. $imagescaled;
// MOVE SCALED FILE TO THE SERVER
move_uploaded_file($tempFile,$targetFile);
// UPDATE DATABASE
update_gallery($id2,$images,$con);
}
i inspected the code with firebug but it returns no error so I don't know where to start to catch the error.. May you help me please?
I created a page that can upload file to my database, but when a filename has (.), it doesnt save properly. For example I upload a file named imagefile.50.jpg, it just saves as image20.50
<?php
function upload_image()
{
if(isset($_FILES["user_image"]))
{
$extension = explode('.', $_FILES['user_image']['name']);
$new_name = $extension[0] . '.' . $extension[1];
$destination = './upload/' . $new_name;
move_uploaded_file($_FILES['user_image']['tmp_name'], $destination);
return $new_name;
}
}
To get the filename and extension of a file, you can use pathinfo, i.e.:
$file = "some_dir/somefile.test.php"; # $_FILES['user_image']['name']
$path_parts = pathinfo($file);
$fn = $path_parts['filename'];
$ext = $path_parts['extension'];
print $fn."\n";
print $ext;
Output:
somefile.test
php
I am using PHP (Symfony2) in my project which has image upload feature. Inside controller:
if ($request->isXmlHttpRequest() && $request->isMethod('POST')) {
$index=(int)$request->request->get('index');
$image_file = $request->files->get('shop_bundle_managementbundle_posttype')['images'][$index]['file'];
$image= new Image();
$image->setFile($image_file);
$image->setSubDir('hg');
$image->upload();
$em->persist($image);
$em->flush();
}
I use a class UploadFileMover that handle the file upload. I didn't write the following code but as I understand, an MD5 hash will be created from the original file name and used as filename. But the instance of UploadedFile contains a file name like "PHP"+number.tmp, not the original as stored in computer filesystem.
class UploadFileMover {
public function moveUploadedFile(UploadedFile $file, $uploadBasePath,$relativePath)
{
$originalName = $file->getFilename();
$targetFileName = $relativePath . DIRECTORY_SEPARATOR . $originalName;
$targetFilePath = $uploadBasePath . DIRECTORY_SEPARATOR . $targetFileName;
$ext = $file->getExtension();
$i=1;
while (file_exists($targetFilePath) && md5_file($file->getPath()) != md5_file($targetFilePath)) {
if ($ext) {
$prev = $i == 1 ? "" : $i;
$targetFilePath = $targetFilePath . str_replace($prev . $ext, $i++ . $ext, $targetFilePath);
} else {
$targetFilePath = $targetFilePath . $i++;
}
}
$targetDir = $uploadBasePath . DIRECTORY_SEPARATOR . $relativePath;
if (!is_dir($targetDir)) {
$ret = mkdir($targetDir, umask(), true);
if (!$ret) {
throw new \RuntimeException("Could not create target directory to move temporary file into.");
}
}
$file->move($targetDir, basename($targetFilePath));
return str_replace($uploadBasePath . DIRECTORY_SEPARATOR, "", $targetFilePath);
}
}
This class is instanciated when an image is uploaded. In other words, I have an Entity Image that has a method upload. Inside entity class:
public function upload()
{
if (null === $this->getFile()) {
return;
}
$uploadFileMover = new UploadFileMover();
$this->path = $uploadFileMover->moveUploadedFile($this->file, self::getUploadDir(),$this->subDir);
$this->file = null;
}
I var_dumped the filename all across the different steps but I cannot figure out where it is transformed to PHP16653.tmp.
Can it be related to an APACHE related configuration? Your help is appreciated. I really did a lot of research for similar issue in the web to no avail.
The problem was created by the line:
$originalName = $file->getFilename();
Use:
$originalName = $file->getClientOriginalName();
instead.