What I want to do is let a user save an image and when they're accessing their accounts I want the image to display.
What I'm currently doing is I'm saving the images in public folder
Store the path to the database
Path: css\img\myPic.jpg
Display the image
<img class="border" src='esc($empInfo['img'])' style="height: 200px; width: 200px">
But since this is a public folder I can't save personal pictures in this folder
I also tried saving the path to writable\uploads\myPic.jpg but no luck
If you look for a manual or a concept , you can also try this:
You must have some folder where you store all personal images
When user needs it, copy the file into Public folder with a random generated 32 character name (GUID type) but with the original extension.
Then feed it to the user in the view.
Once displayed after the view is called you can delete the image from that folder.
As of the the moment. the solution that I got is "copying" the file(in my case it is an image file)from writable/uploads to public using Publish Library.
$publisher = new Publisher(WRITEPATH . 'uploads', FCPATH. 'img/');
$publisher->addPaths([
'img/myPic.jpg',
]);
$publisher->copy(true); // `true` to enable overwrite
Source Path: WRITEPATH . 'uploads'
Destination Path: FCPATH. 'img/'
Source File: img/myPic.jpg
Now you can ref the image in img tags.
Next step should be replacing/deleting the image after use, because this is not gonna be different when you upload the image at public folder. Will try to update if I found a solution
Source: https://codeigniter.com/user_guide/libraries/publisher.html
PS. Feel free to correct me :) I am also new to web developing in general
Part2: I added this to my function. what it does is after copying the image to the public folder I then rename to 'myPic.jpg'. this will solve my previous problem "replacing/deleting the image after use".
$renameFile = rename(FCPATH. 'img/'.$fileName, FCPATH . 'img/'. 'myPic.jpg');
if($renameFile){
return true;
}
else{
return false;
}
Related
This my data that I want to store my pdf files in my public folders. Anyone can give me any idea?
I tried to foreach the data to get that file but it seems not working in my end. Anyone can help me?
To store files in your public folder you can use the public disk that's included in your application's filesystems configuration file, the default config will store files in storage/app/public.
To make these files accessible from the web though (which I'm assuming is what you want) you need to create a symbolic link from public/storage to storage/app/public.
To do that just run:
php artisan storage:link
Once you've done this you can use Laravel's storage facade to interact with the files in your public folder to save, retrieve and download them.
Store
use Illuminate\Support\Facades\Storage;
Storage::put('file.jpg', $contents);
Download
return Storage::download('file.jpg');
return Storage::download('file.jpg', $name, $headers);
Retrieve
$contents = Storage::get('file.jpg');
If you need to store user uploaded files to your public storage, you can do it like this:
$path = $request->file('yourUploadedPdf')->store('yourPdfsFolder');
Laravel's store method will generate a unique ID for the filename and the extension will be determined by the MIME type of the uploaded file. The store method also returns the path, including the generated filename, so you can store it in your DB if needed.
If you need to specify the filename then you can do this:
$path = $request->file('pdf')->storeAs(
'yourPdfsFolder', 'yourPdfFileName'
);
Just a note, I'm assuming you'll be having public as your default disk, if not, then you'll need to specify the disk you're using in these method / Storage facade calls.
And a further note, when using the public disk, everything - by default - gets stored under storage/app/public so anytime you're defining a folder to store your uploaded PDFs under, it'll be storage/app/public/yourFolder.
I have a custom form using a "managed_file" which uploads to temp folder. Programmatically, I then load that file and move it to its permanent storage (overwriting any existing file with the* name) e.g.
// Upload file
$upfile = $this->entityTypeManager->getStorage('file')->load($fid);
// Source and destination
$sourceUri = $this->fileSystem->realpath($upfile->getFileUri());
$destinationUri = $this->fileSystem->realpath(\Drupal::config('system.file')->get('default_scheme') . "://") . '/x/y/z/XYZ_NEW.pdf';
// Move and overwrite
$this->fileSystem->move($sourceUri, $destinationUri, FileSystemInterface::EXISTS_REPLACE);
All of this works (i.e. the file physically is moved into the correct place with correct name); however, the file displayed in the listings (i.e. /admin/content/files) still shows the incorrect temporary folder as the URI.
Basically the file in the listings page seems to be showing the original filepath and name* of a previously successfully moved* file.
If I load this file with incorrect URI, i.e. using the incorrect temp path, the data loads, but then will not have a file info (as it doesn't exist. Also clicking the filename by browser under listings will show page not found and the URL showing the old URL i.e. /system/temporary?file=XYZ.pdf).
If I load this file by correct URI, i.e. using the correct destination path, file not found - same if I go to the path directly in the browser.
It appears the managed file doesn't know it was moved. How to resolve this bug?
The docs for FileSystem::move say "Moves a file to a new location without database changes or hook invocation."
So you are going to need to update the file entity with the new values..
Try this, untested:
// Upload file
$upfile = $this->entityTypeManager->getStorage('file')->load($fid);
// Source and destination
$sourceUri = $this->fileSystem->realpath($upfile->getFileUri());
$destinationUri = $this->fileSystem->realpath(\Drupal::config('system.file')->get('default_scheme') . "://") . '/x/y/z/XYZ_NEW.pdf';
// Move and overwrite
$newFileName = $this->fileSystem->move($sourceUri, $destinationUri, FileSystemInterface::EXISTS_REPLACE);
// Set the new file path on the file entity.
$upfile->setFileUri($newFileName);
// Set the file to permanent if needed.
$upfile->setPermanent();
// Save entity with changes.
$upfile->save();
I did not test this though.
You can check the functions on the file entity in the docs here
It turns out the class based methods do not update the database
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21File%21FileSystem.php/function/FileSystem%3A%3Amove/8.9.x
The procedural version does
https://api.drupal.org/api/drupal/core%21modules%21file%21file.module/function/file_move/8.9.x
I have an image that I loaded by using URLImage class. Here is the code:
EncodedImage placeholder = EncodedImage.createFromImage(Image.createImage(getWidth()/2, getWidth()/2 , 0xF92D2D), true);
Image originImg = URLImage.createToStorage(placeholder, imgFileName, photo_url);
To my understanding, this image is being saved into Storage with createToStorage() method. However, next time when I am loading this form, I don't want to download the image again, I want to take it from the Storage, because its faster.
So what I did, I added check :
if (Storage.getInstance().exists(imgFileName)) {
// Take the image from the Storage
originImg = Image.createImage(Storage.getInstance().createInputStream(imgFileName));
} else {
// Load the image with URLImage class.
}
However, it seems like my file is never saved into the Storage. What can be wrong?
You don't need to do that. URLImage seamlessly loads the file from storage if the file is already there. You can open the network monitor and see if a request is made to the URL for this specific image.
I'm not sure why the Storage.getInstance().exists(imgFileName) method would fail. I assume the image name is different in the different execution or something of that sort. You can see that images are created in your .cn1 directory.
I am uploading user profile image which is uploading and moved to storage/app/upload/images folder but when I am trying to display that image, below given error occurs.
Method App\Image::__toString() must not throw an exception, caught Illuminate\Database\Eloquent\JsonEncodingException
Here is my controller function for displaying
public function userProfile() {
$image = Image::all();
return view('frontend.layouts.Profile',compact('image'));
}
My view in which I am displaying image
#foreach($image as $images)
<img style="width:210px ; height: 230px " src="/storage/app/upload/images/{{$images->image}}" >
#endforeach
Please Upload your image in Public directory and then try to access that, it will work fine
There are three ways of making an image available to a user:
1. As a public asset
Here the image is made available to everyone. For instance your website logo, or landing page image would be accessed by all. So there is a url to the image that is easily accessed by all. These sort of files would go straight to public/img/ folder.
2. As a protected image available only if specific url is requested
Here user specific images would be accessed by specific people. Think of your members' personal photos that you want to make available only to the member herself or to some specific person. In this case you would store the images in storage/app/public and make a symlink using the artisan command php artisan storage:link You can read more on this here. Assuming that you store your files using random names using str_random() you would then generate urls to your image using the asset() helper like: echo asset('storage/X3jf5j5b2j3n.jpg'); Given that the file names are random, it would be hard to access this image by everyone excepting those who have the url generated using the asset() helper.
3. As a protected image made available using Intervention library
In this case you would first check if user is logged in and then dynamically load the image using Intervention via another protected route. So in your web routes you would first have the user authorization using auth middleware:
Route::group(['middleware' => 'auth'], function () {
Route::get('user', 'UserController#userProfile');
Route::get('images/{image}', 'UserController#serveImage'); // this route serves the image only if user is logged in
});
Then once your have installed Intervention library using composer, our UserController would look like:
use Intervention;
class UserController extends Controller
{
public function userProfile()
{
$images = Image::all();
return view('frontend.layouts.Profile', compact('images'));
}
public function serveImage($image)
{
$filename = storage_path('app/images/'.$image);
return Intervention::make($filename)->response();
}
}
You can see that the image is now being served from the storage folder and not public folder. So this method serveImage() is called only when the route defined earlier for it is authorized. Intervention then works its magic to read the image and send it as a http response.
Your view would change one tad bit to accommodate the new route end point that we defined called images. I assume here that you are storing the filename of the image in db by a field named filename:
#foreach($images as $image)
<img style="width:210px ; height: 230px " src="{{ url('/images/'.$image->filename) }}" >
#endforeach
Note: Do bear in mind that the preferred way to serve images is by using method 2 since it is much faster. You can use method 3 sparingly if you really don't want anyone to even stumble upon the files using the urls.
I'm creating a project of a school. I want to show the uploaded stuff by teachers to students.
But I also need to save the file in the folder which is named as faculty name. Student will be able to browse the main directory and after that he can go in the particular faculties folder.
How can I do it? Any suggestions will be appreciated.
For file upload I would start with example like in this answer. Moving files from temporary folder could be easily done by the file uploading action.
For browsing files in your case I would create an action that is able to navigate to the folder where the files are and get a list of files from that folder. Something like this
String file = application.getRealPath("/upload");
File f = new File(file);
String [] fileNames = f.list();
File [] fileObjects= f.listFiles();
for (int i = 0; i < fileObjects.length; i++) {
if(!fileObjects[i].isDirectory()){
String fname = file+fileNames[i];
out.println(fileNames[i]);
}
}
Then map this files to the JSP as links. When that link is clicked you can retrieve the actual path on the server when action is executed. What to do with the data, of course you can return stream result from the action that is used for streaming to the client browser. You can use docs examples from the Struts site or like in this example.
To navigate to the folder use parameters in GET request, that will be used to store current directory in session. You can change it if a user change the current directory from the view layer.