Using Laravel Mediable and I'm trying to figure out the best way to delete an individual file. Say there's a list of files when I'm viewing the parent Model, and I click a delete icon to make an ajax request to delete file (which should remove both the corresponding Media object and the physical file...)
This works:
$path_parts = pathinfo($request->filename);
$attachment = Media::where('directory', $folder)
->where('filename', $path_parts['filename'])
->where('extension', $path_parts['extension'])
->first();
$attachment->delete();
but this deletes only the database row and not the physical file itself:
$attachment = Media::where('id', $request->fileid);
$attachment->delete();
I'd prefer deleting the file via the id because its unique but wondering what I'm missing...
You must delete the file also using this code
File::delete('path/to/'.$request->filename);
=updated=
The problem on the second block is just need to add ->first() at the end of the where clause
Related
I'm trying to download all the uploads together under one user. If one user has uploaded under multiple collections, I want to download all uploads under all collections in one click as a zip file.
I tried without the collection name in getMedia function. But it's not getting my result.
$user = User::where('id',auth()->user()->id)->first();
$downloads = $user->getMedia();
return MediaStream::create('my-files.zip')->addMedia($downloads);
How can I download all files without the collection name in the media library in one click as a zip file?
I got the solution.
With collection name
$user = User::where('id',auth()->user()->id)->first();
$downloads = $user->getMedia('passport');
return MediaStream::create('myfiles.zip')->addMedia($downloads);
Without collection name
$user = User::where('id',auth()->user()->id)->first();
$downloads = ModelsMedia::where('model_id',$user->id)->get();
return MediaStream::create('myfiles.zip')->addMedia($downloads);
I have a Laravel website and I have several routes that load the contents of images from Storage. I do this using the following code:
public function show_image($name) {
echo Storage::disk('images')->get($name);
}
I want to prevent users being able to set name to something like ../../../error.log. So I don't want users to escape the Storage directory. I have a few ideas on how to accomplish this however I want to know is there a best practice?
If you need just file name, not location, disallow them from inputting folder of any kind. Just cut the string on /.
end(preg_split("#/#", $name));
When you need to allow some folders and all of the contents, check the folder name, subfolder name, etc.
You could either keep a registry/index of the uploaded images, and only allow the user to show a image from that registry (e.g. an images database table).
Or you could do a scan of the directory, that you are allowing files from, and make sure, that the requested file is in that list.
public function show_image($name) {
$files = Storage::disk('images')->files();
if (! in_array($name, $files)) {
throw new \Exception('Requested file not found');
}
echo Storage::disk('images')->get($name);
}
(code untested)
I'm using Laravel and taking in input and file uploads. This page takes changes that users want to make to an order. The end goal is to take this input and apply it to multiple orders.
I can reuse the input for each of the orders. But what would be a good way for me to copy that file in the request to multiple directories? For example, as in the documentation, I originally have: $request->file('photo')->move($destinationPath, $fileName); which works fine for one order. But now that I want to apply it to many orders, I can't move that same file from the request anymore since it doesn't exist.
And it looks like the UploadedFile object doesn't have a copy() method. Any ideas would be appreciated. Thank you.
Do not depend on component too much. Keep it simple
$request->file('photo')->move($destination_path, $file_name);
//Add DIRECTORY_SEPARATOR between path and filename if needed
copy($destination_path.$file_name, $new_path.$new_file_name);
If I may make a suggestion assuming these files are going to stay the same (you aren't allowing your users to modify these files by order), I think it makes sense to store one copy of the file on the server and use a database table to determine which orders that file belongs to and manage it all in the table. You may need to create a files table and an file_order table and give it a many to many relationship to your orders table but in the end, if these files are allowed to be large, could save you a lot of space and in my opinion, make it easier to manage.
In Laravel, look at the vendor\laravel\framework\src\Illuminate\Filesystem\Filesystem.php , and I hope you'll get the everything of file, how they manage the files.
How to copy a file, move a file, delete a file everything is described clearly in that.
For copy a file in Laravel, there function is:
/**
* Copy a file to a new location.
*
* #param string $path
* #param string $target
* #return bool
*/
public function copy($path, $target)
{
return copy($path, $target);
}
I think there's nothing to say now.
Just use that
File::copy('file_name_with_full_path', 'target_directory_where_copy');
Hope, it might be helpful for you.
Here is my BrandController.php
https://gist.github.com/a958926883b9e7cc68f7#file-brandcontroller-php-L53
I've gone through all my files of my custom module, and compared them to the one given from the custom module maker, and I couldn't find much differences.
Are you attempting to upload multiple files? If you're using multiple fileupload elements with the same name you'll get an array of items.
So when the following line is called,
//this way the name is saved in DB
$data['filename'] = $_FILES['filename']['name'];
It will have the value
["name"]=>array(2) {
[0]=>string(9)"file0.txt"
[1]=>string(9)"file1.txt"
}
you'll need to update the code to loop through each $_FILES['filename']['name'] and upload and save the files separately.
You may unknowingly uploaded multiple files. If you that is not your intention, you may check your in your HTML and check the name attribute of the tag. It must not be an array (like this).
<input type="file" name="my_files[]" />
If you only see Array() in your database, it means you are indeed uploading a multiple files. You can process them by using loops.
If you are really sure that you are uploading 1 image, you may follow #Palanikumar's suggestion. Use a print_r() and display the $_FILES and paste it here. IF you don't want to use that, You can use
json_encode($the-data-you-are-going-to-insert-to-the-database);
If you don't know where to put the print_r() function, you may put it after line 56 of this file.
https://gist.github.com/desbest/a958926883b9e7cc68f7#file-brandcontroller-php-L53
if(isset($_FILES['filename']['name']) && $_FILES['filename']['name'] != '') {
print_r($_FILES);
die;
If saveAction() is being called inside an ajax function you need to log the ajax response. Assuming you are using jquery..
$ajaxResponse = $.POST({...});
console.log($ajaxResponse.responseText);
Then, you you can view it inside a browser's console. If nothing appears, you may use a non-async request
$ajaxResponse = $.POST({
// your options,
// your another option,
async: FALSE
});
Usually file upload will return in array format. So that each uploaded file will have the information like name, type, size, temporary name, error. You can get the file information using print function (print_r($_FILES)). So if you want to display name of the file you have to use something like this $_FILES['filename']['name']
Use print function and debugging tool then save file information using loops.
For more info please check here.
You aren't setting the enctype of the form so the image will never be sent. updated the code to
$form = new Varien_Data_Form(array( 'enctype' => 'multipart/form-data'));
How to populate image field value with drupal_execute.
for ex my content type (test) has two additional fields
1. photo (image filed),
2. phid (text field)
for phid $form_state['values']['field_phid'][0]['value'] ='14'; . how to populate photo which is image field type
If the file is already uploaded to Drupal and has a file ID (fid) then you can just do
$form_state['values']['field_image_filed'][0]['fid'] = 17; //where 17 is the Drupal file ID of the file you want input
If the file isn't already uploaded it's a lot trickier. You'll first need to programmatically create the file. I can't walk you through it off-hand but a good place to look for a template as to how it should be done is the file_service_save() function in the Services module's file_service.inc:
http://drupalcode.org/viewvc/drupal/contributions/modules/services/services/file_service/file_service.inc?revision=1.1.2.7.2.3&view=markup&pathrev=DRUPAL-6--2-2
To be clear: I'm not saying you'll use file_service_save() to accomplish the upload, but that that code shows you what needs to be done. It will show you how to save the file to the server using file_save_data(), record the file to the Drupal "files" table, then call hook_file_insert to notify other modules that a file's been saved.
i found the solution as below . i dont know pros and cons but it works fine for me.
$image = "*******/test.jpg";
$field = content_fields('field_img', 'img_test');
$validators = array_merge(filefield_widget_upload_validators($field), imagefield_widget_upload_validators($field));
$files_path = filefield_widget_file_path($field);
$form_state['values']['field_img'][]= field_file_save_file($image, $validators, $files_path, FILE_EXISTS_REPLACE);