I would like to rename a collection of uploaded files, but when I use addAllMediaFromRequest() I can't retrieve information from the files.
In this example; I need to know the file extension in order to rename the file.
$files = $post->addAllMediaFromRequest();
$files->each(function (FileAdder $file) {
$file->usingFileName(Str::random(16) . '.jpg') // What if it's a png?
->toMediaCollection();
});
To get a file extension within laravel:
$request->file('photo')->extension()
To create new file name:
$newFileName = Str::random(20) .'.'.$request->file('photo')->extension();
don't forget to import Str class.
then you could rename the uploaded file before storing it easily
$item->addMedia($request->photo)->usingFileName($newFileName)->toMediaCollection('photo');
code tested Laravel v9
Related
I uploaded this excel file: myExceldocument.xlsx
After uploading I want to store in a folder.
I used this method:
$uploadedFile = $request->file('files')[0]->getClientOriginalName(); //it worked
Excel::store(new DeductionsImport, $uploadedFile, 'documents');
'documents' is related to filesystem.
The excel file is correctly filed in my folder called 'documents'.
The problem is when I open it, the excel file is empty!
Do you know why ?
My goal is only upload an excel document and store in folder.
Excel::store is for storing exports, not saving uploaded files.
If you are simply trying to save your myExceldocument.xlsx to your documents folder, the request object has a simple method for it.
// Where 'files' is the name of the upload field in HTML.
$request->file('files')->store('documents');
Another example:
$fileNameToStore = $request->file('files')[0]
Storage::disk('documents')->put($fileNameToStore, fopen($file, 'r+'));
work but is not the best solution because folder is filed with '' :
$file->storeAs('',$file->getClientOriginalName(),'documents');
I am allowing users to upload any kind of file on my page, but there might be a clash in names of files. So, I want to rename the file automatically, so that anytime any file gets uploaded, in the database and in the folder after upload, the name of the file gets changed also when other user downloads the same file, renamed file will get downloaded.
I tried:
if (Input::hasFile('file')){
echo "Uploaded</br>";
$file = Input::file('file');
$file ->move('uploads');
$fileName = Input::get('rename_to');
}
But, the name gets changed to something like:
php5DEB.php
phpCFEC.php
What can I do to maintain the file in the same type and format and just change its name?
I also want to know how can I show the recently uploaded file on the page and make other users download it??
For unique file Name saving
In 5.3 (best for me because use md5_file hashname in Illuminate\Http\UploadedFile):
public function saveFile(Request $request) {
$file = $request->file('your_input_name')->store('your_path','your_disk');
}
In 5.4 (use not unique Str::random(40) hashname in Illuminate\Http\UploadedFile). I Use this code to ensure unique name:
public function saveFile(Request $request) {
$md5Name = md5_file($request->file('your_input_name')->getRealPath());
$guessExtension = $request->file('your_input_name')->guessExtension();
$file = $request->file('your_input_name')->storeAs('your_path', $md5Name.'.'.$guessExtension ,'your_disk');
}
Use this one
$file->move($destinationPath, $fileName);
You can use php core function rename(oldname,newName) http://php.net/manual/en/function.rename.php
Find this tutorial helpful.
file uploads 101
Everything you need to know about file upload is there.
-- Edit --
I modified my answer as below after valuable input from #cpburnz and #Moinuddin Quadri. Thanks guys.
First your storage driver should look like this in /your-app/config/filesystems.php
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'), // hence /your-app/storage/app/public
'visibility' => 'public',
],
You can use other file drivers like s3 but for my example I'm working on local driver.
In your Controller you do the following.
$file = request()->file('file'); // Get the file from request
$yourModel->create([
'file' => $file->store('my_files', 'public'),
]);
Your file get uploaded to /your-app/storage/app/public/my_files/ and you can access the uploaded file like
asset('storage/'.$yourModel->image)
Make sure you do
php artisan storage:link
to generate a simlink in your /your-app/public/ that points to /your-app/storage/app/public so you could access your files publicly. More info on filesystem - the public disk.
By this approach you could persists the same file name as that is uploaded. And the great thing is Laravel generates an unique name for the file so there could be no duplicates.
To answer the second part of your question that is to show recently uploaded files, as you persist a reference for the file in the database, you could access them by your database record and make it ->orderBy('id', 'DESC');. You could use whatever your logic is and order by descending order.
You can rename your uploaded file as you want . you can use either move or storeAs method with appropiate param.
$destinationPath = 'uploads';
$file = $request->file('product_image');
foreach($file as $singleFile){
$original_name = strtolower(trim($singleFile->getClientOriginalName()));
$file_name = time().rand(100,999).$original_name;
// use one of following
// $singleFile->move($destinationPath,$file_name); public folder
// $singleFile->storeAs('product',$file_name); storage folder
$fileArray[] = $file_name;
}
print_r($fileArray);
correct usage.
$fileName = Input::get('rename_to');
Input::file('photo')->move($destinationPath, $fileName);
at the top after namespace
use Storage;
Just do something like this ....
// read files
$excel = $request->file('file');
// rename file
$excelName = time().$excel->getClientOriginalName();
// rename to anything
$excelName = substr($excelName, strpos($excelName, '.c'));
$excelName = 'Catss_NSE_'.date("M_D_Y_h:i_a_").$excelName;
$excel->move(public_path('equities'),$excelName);
This guy collect the extension only:
$excelName = substr($excelName, strpos($excelName, '.c'));
This guy rename its:
$excelName = 'Catss_NSE_'.date("M_D_Y_h:i_a_").$excelName;
I want to extract text from docx and doc file. I am using this class The one in the answer.
Everything works fine when i use them in native php and docx file in the same directory of the php files. It extracts pretty well. This is not the case when i upload them through <input type="file">. You can see in the link that this class accepts only docx,doc,pptx and xlsx. I know when you upload file in php it renames and move to temp to avoid name clashing and overwriting. So i came with something like getting the tmp file and removing its extension and adding docx or doc to it.
Here is my code
$file = $request->file('resume');
echo $file."<br>";
$withoutExt = preg_replace('/\\.[^.\\s]{3,4}$/', '', $file);
$echo $withoutExt."<br>";
$original_file = $withoutExt.".docx"."<br>";
$echo $original_file."<br>";
$doc_file = new DocxConversion($original_file);
$echo $docText= $doc_file->convertToText();
The above code gives me the output as i expected till converting the .tmp to .docx but finally says File Not exists Here is the output
C:\xampp\tmp\phpCB7E.tmp
C:\xampp\tmp\phpCB7E
C:\xampp\tmp\phpCB7E.docx
File Not exists
I have also tried to put a docx file in the controllers directory and tried to execute like this
public function index1(){
echo "hello";
$docObj = new DocxConversion("hello.docx");
var_dump($docText= $docObj->convertToText());
}
The above approach also says File not exists. Am i doing anything wrong here? It works perfectly with the same file in native code where my php files and docx files are in same directory but not when i use it in my controller.
Assuming your $file is a UploadedFile you can use the getRealPath method to get the path to the filename,
$file = $request->file('resume');
$doc_file = new DocxConversion($file->getRealPath());
echo $doc_file->convertToText();
Currently the zip is downloading and the images within the zip are off the names that are stored on the server i need to rename them
I have 3 images on the server i need to download the images but before adding files to zip i need to rename them
public function downimages(){
$this->_check(); // session checker
$this->load->helper('download');
$this->load->library('zip');
$idm=$this->uri->segment(3);
$ab=$this->adminmod->downimg($idm);
$down=explode('-/,-', $ab[0]->director); //gets the directory stores in array
$fname=explode('-/,-', $ab[0]->file_oname); //gets the file names stores in array
foreach ($down as $key =>$value){
$name = $fname[$key]; // this is where the name is stored need to use this to rename
$data = "./"($value);
$this->zip->read_file($data); //adds the images to zip archive
}
$this->zip->download($idm.'.zip'); //downloads the zip fles
// redirect($_SERVER['HTTP_REFERER']);
}
My server image names are like xfasf.jpg 2) sadweq.jpg 3)wqweq.jpg
my actual file names are image1.jpg 2)blue.jpg 3)red.jpg whcih comes from $name
How do i go about this?
Solution Was Quite Easy
Solved IT at the $this->zip->read_file($data);
I just put the $name like this
$this->zip->read_file($data,$name);
now the files get renamed before they get zipped and then downloaded
Solved IT at the $this->zip->read_file($data); i jsut put the $name like this $this->zip->read_file($data,$name); now the files get renamed before they get downloaded
I have a fileupload module in my app. I can upload files in img/upload/{container_id}/file_name_here.
The {container_id} will depend on what folder the user will use.
The problem I encountered is when they try to edit a record to another folder. The file that they uploaded remains in the old folder.
I want to move the file also to the new folder the user defines.
I have here my code, I'm stuck in moving the file.
$attachments = Attachment::where('document_id',$id)->select('filename')->get();
$document = Document::findOrFail($id);
foreach($attachments as $attachment)
{
$attachment->filename = base_path().'/public/img/upload/'.$document->container_id."/".$attachment->filename;
}
Document::findOrFail($id)->update($request->all());
$document = Document::findOrFail($id);
$x = Attachment::where('document_id','=',$id)->count();
foreach($attachments as $file)
{
HOW_DO_I_MOVE_THE_FILE????
$x++;
}
return redirect('documents');
Update:
In your case, you should use rename():
rename ('current/path/to/foo', 'new/path/to/foo');
With rename() you can not only rename, but also move! Simply, if the path of the second param differs. So you can use in your loop the attachment path as first param, and a destination path as second.
Documentation: http://php.net/rename
Below the Laravel approach for moving after upload.
From the documentation:
$request->file('photo')->move($destinationPath);
$request->file('photo')->move($destinationPath, $fileName);
photo is the name of your file upload input element.
Note, you can use the array notation, if you've multi upload, such as:
foreach ($request->file('photo') as $photo)
{
$photo->move($destinationPath, $chooseYourFileName);
}