File rename no longer working - php

I have an update controller function in a laravel resource controller thats pretty basic. Updates the title, body etc. in the DB as normal (no issues with data updates).
The issue is with images. My image directory for each project follows a slug like naming convention based on the title of the project. I built the update function so that the directory and images would be renamed if the title was changed. This was working fine as soon as I built it, but it's suddenly stopped. The directory renames, but the files do not. Here is the relevant snippet from the controller:
$count = 0;
$slug = Input::get('title');
$prefix = Str::slug($slug);
$oldPrefix = $project->imagesprefix;
$path = public_path().'/img/projects/';
$directory = $path . $prefix;
rename($path.$oldPrefix, $directory);
//dumped directory here and it's definitely set
$files = preg_grep('~\.(jpg)$~', scandir($directory));
//dumped $files here and the array is definitely set
foreach($files as $file){
rename($directory.'/'.$file, $directory.'/'.$prefix.'-'.$count.'.jpg');
++$count;
}
rename($directory.'/thumbnails/'.$oldprefix.'-thumb.jpg', $directory.'/thumbnails/'.prefix.'-thumb.jpg');
All of this was working fine when tested this afternoon. Now it updates the DB, renames the directory folder but fails to rename the files. I've dumped the both $files and $directory before the loop and they are both set.

If file rename fails then this is quite often related to permissions.

Related

Transfer files to new directories

I just need a simple code to transfer files to new directories that will have variable names.
for instance here is a snip of my code, it is very simple, see the attachment
As you can see this is a registration page, when the user is created, then a token is created a folder is created with the username which is a variable in this case, in the end, it created the folder and finally sends a confirmation email via php mailer.
I want once the folder I mentioned earlier is created post user registration it needs to automatically copy all files (.) located in: temp/accounts/profile into the new directory created, for instance:
temp/accounts/profile/newuser
I tried to do this but since the new directory relies on the username input it is a variable and I'm not sure how to build this query to transfer the files successfully after user registration.
Loop the contents from one directory and copy them over to the new one.
$targetDir = 'temp/accounts/profile/newuser';
//of course create this folder first if it doesn't exist
mkdir($targetDir);
// Scan the directory and retrieve all files
// `array_diff` is to clean out directory thingies than can persist
foreach(array_diff(scandir($dirname), ['.','..']) as $val){
copy("$dirname/$val", "$targetDir/$val");
}
You need to find all files and copy them over one by one. If you need to copy directories you'll have to implement a recursive copy, in that case, you could use is_dir within your loop to check if the filename is a directory.
<?php
$source = 'temp/accounts/profile/newuser';
$destination = 'temp/accounts/profile/' . $name;
$files = glob($source . "/*.*"); //Find all files
foreach($files as $filename){
copy($filename, $destination . "/" . basename($filename));
}
?>

How to store multiple uploaded files with Laravel's Storage Facade

Currently I have a project that is running Laravel 5.8 and I am trying to use a form that allows user's to upload their own images to the site and store it in the public folder. When trying to use the Storage facade with the 'put' method, a path gets returned but the images do not actually get stored.
if ($request->hasfile('images')) {
foreach ($request->file('images') as $file) {
$path = Storage::disk('public')->put('images', $file);
echo $path;
}
}
This is the code I am trying to use. The path gets echo'd as it should and I have not made any changes to the filesystem config. In the form, the input field images allows for submitting multiple files and the form does hasenctype="multipart/form-data". The $file variable also contains an instance of Illuminate\Http\UploadedFile.
The previous code I used which did work was:
if ($request->hasfile('images')) {
foreach ($request->file('images') as $file) {
$file->move(public_path('images'), $file->getClientOriginalName());
}
}
I would be okay with using my previous code if Laravel can give it a unique file name on upload but what would be causing my code with the Storage facade to not save the images properly? Does the put function just not work like that or is there something I am overlooking?
Edit:
So I realise the images were in fact saving correctly as they should be. I was looking inside the public folder rather than the storage folder which is why my second code example 'worked' but not the first. I realise when using the Storage facade I need to make use of Symbolic linking if I want to access these files on the web.
You need to also make sure you have created the symbolic link on your Ubuntu server or Windows development machine to the storage folder.
Windows you can use : mklink /j /path/to/laravel/public/youfolder /path/to/laravel/storage/youfolder
Ubuntu: ln -s /path/to/laravel/public/youfolder /path/to/laravel/storage/youfolder
To check & set you can also use use php artisan storage:link
Hope this helps
if ($request->hasfile('images')) {
foreach ($request->file('images') as $file) {
$path = Storage::disk('public')->put('images', $file);
$new_file_name = time() . "_" . uniqid() . "_" . $file->getClientOriginalName();
$path = Storage::disk('public')->put($new_file_name, file_get_contents($file));
echo $path;
}
}

Laravel 5 moving image to another folder dynamically

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);
}

removing draft file after saving permanently in moodle File API

I'm using moodle filemanager to get a file from user and save it permanently like this:
$fs = get_file_storage();
$pluginname='profile_field_fileupload';
$pluginfolder= 'profile_field_profileimage';
$draftitemid=file_get_submitted_draft_itemid($this->inputname);
if (empty($entry->id)) {
$entry = new stdClass;
$entry->id = $this->userid;
}
$context = context_user::instance($this->userid);
$files = $fs->get_area_files($context->id, $pluginname,$pluginfolder,false,'',false);
foreach ($files as $file) {
$file->delete();
}
file_save_draft_area_files($draftitemid, $context->id, $pluginname,$pluginfolder,$entry->id,array('subdirs'=>false, 'maxfiles'=>1));
But draft still exists.
How should I remove draft after saving it?
Wait a few days - Moodle's cron process automatically cleans up draft files after that point (the delay is to make sure you haven't still got a copy of the form open and in use).
Remember that the draft area files are taking up no extra storage space on your server, as all files with identical content are stored only once, with multiple entries in the 'mdl_files' table all pointing to the same physical location on the server's hard disk.

PHP Script to Sort a Large Folder of Files into Date based Sub Folders

I have a large list of call recordings from a PBX system and I need to sort them into more manageable folders.
Being a bit of a linux noob, how would I search through a specified folder and based on the date of the file, move it into a folder hierarchy.
Example I have 2013/04/23 as the folder structure.
Then I have files with dates as
20130403-blah283.mp3
20130403-blah284.mp3
20130403-blah285.mp3
20130403-blah286.mp3
20130403-blah287.mp3
etc. Any help would be appreciated.
This might give you a starting point:
get files
iterate through files
create new directory/file_name
create directory if !exists
copy file
delete old file
Model:
<?php
$base_path = "/PATH_TO_FILES/";
//$files = glob($base_path."*.mp3");
$files = array('20130403-blah283.mp3','20130403-blah284.mp3','20130403-blah285.mp3','20130403-blah286.mp3','20130403-blah287.mp3'); // for testing
foreach($files as $file){
$pieces = explode("-",$file);
$new_filename = $pieces[1];
$timestamp = $pieces[0];
$directory = substr($timestamp,0,4)."/".substr($timestamp,4,2)."/".substr($timestamp,6)."/";
if(!is_dir($base_path.$directory)){
mkdir($directory,0777);
}
copy($base_path.$file,$base_path.$directory.$new_filename);
//unlink($base_path.$directory.$new_filename); // DELETES OLD FILE ONLY UNCOMMENT WHEN YOUR READY!
}

Categories