File copy
Hi Guys,
I am attempting to write a function whereby a user clicks a select button which will then copy files found in storage/public/templates/(template name)/index.html or style.css and place the copies into storage/user-templates/(uuid)/
The problem I have is that the folder is created but the files are not copied. I can also see data entries in my table but only the template_name is correct and the rest of the values such as html_file_path is 0
Here is my TemplatesComponent:
public function copyTemplate($id)
{
$template = \App\Models\Template::find($id);
// Generate unique folder name for user templates
$folderName = 'user-templates/' . Str::uuid()->toString();
$template = Template::find($id);
$htmlPath = $template->html_file_path;
$cssPath = $template->css_file_path;
$jsPath = $template->js_file_path;
// Only copy files if their paths are not null and the files exist
if ($template->html_file_path) {
$htmlPath = Storage::copy($template->html_file_path, $folderName . '/index.html');
}
if ($template->css_file_path) {
$cssPath = Storage::copy($template->css_file_path, $folderName . '/style.css');
}
if ($template->js_file_path) {
$jsPath = Storage::copy($template->js_file_path, $folderName . '/script.js');
}
// Create new record
UserTemplate::create([
'user_id' => auth()->id(),
'template_name' => $template->name,
'html_file_path' => $htmlPath,
'css_file_path' => $cssPath,
'js_file_path' => $jsPath,
]);
}
Any ideas?
Okay so I made some progress. The correct values are now showing in the table, however the copy function is still not working as expected.
When I put in the absolute path of the file it works, but if I use a variable which in this case I need to as there are many different templates, it does not function.
Here is the modified code:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\UserTemplate;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use App\Models\Template;
use Illuminate\Support\Facades\File;
class TemplatesComponent extends Component
{
public function render()
{
$templates = \App\Models\Template::all();
return view('livewire.templates-component', ['templates' => $templates]);
}
public function copyTemplate($id)
{
$template = \App\Models\Template::find($id);
// Generate unique folder name for user templates
$folderName = 'public/user-templates/' . Str::uuid()->toString();
$newhtml = $folderName . '/index.html';
$newcss = $folderName . '/style.css';
$newjs = $folderName . '/script.js';
$template = Template::find($id);
// Only copy files if their paths are not null and the files exist
if ($template->html_file_path) {
Storage::copy('public/templates/french-classic/index.html', $newhtml);
}
if ($template->css_file_path) {
$cssPath = Storage::copy($template->css_file_path, $folderName . '/style.css');
}
if ($template->js_file_path) {
$jsPath = Storage::copy($template->js_file_path, $folderName . '/script.js');
}
// Create new record
UserTemplate::create([
'user_id' => auth()->id(),
'template_name' => $template->name,
'html_file_path' => $newhtml,
'css_file_path' => $newcss,
'js_file_path' => $newjs,
]);
}
}
Hey!
It appears that the problem is coming from the way you're referencing the source file in your Storage::copy()
command. It might be due to the fact that the path to the file you're copying from is relative to the root directory, and not relative to the public
directory.
When using the Storage
facade, paths are relative to your configured disk. By default, this disk is local
, which means that your paths are relative to the storage/app
directory.
Therefore, if your html_file_path
(and others) are stored relative to the public
directory, they might not be found by the Storage::copy()
command, which could be why your files aren't being copied.
You need to adjust your paths to be relative to the storage/app
directory. For example, if your files are located in the storage/app/public/templates/(template name)/
directory, your html_file_path
should be something like public/templates/(template name)/index.html
.
Here's how to modify your function:
public function copyTemplate($id)
{
$template = \App\Models\Template::find($id);
// Generate unique folder name for user templates
$folderName = 'public/user-templates/' . Str::uuid()->toString();
// Only copy files if their paths are not null and the files exist
if ($template->html_file_path) {
Storage::copy($template->html_file_path, $folderName . '/index.html');
}
if ($template->css_file_path) {
Storage::copy($template->css_file_path, $folderName . '/style.css');
}
if ($template->js_file_path) {
Storage::copy($template->js_file_path, $folderName . '/script.js');
}
// Create new record
UserTemplate::create([
'user_id' => auth()->id(),
'template_name' => $template->name,
'html_file_path' => $folderName . '/index.html',
'css_file_path' => $folderName . '/style.css',
'js_file_path' => $folderName . '/script.js',
]);
}
Remember, you should always check if the source file exists before trying to copy it, to avid runtime errors. If your paths are stored correctly and your files are still not being copied, it could be due to a permission issue. Ensure that your web server user (www-data, apache, etc.) has read access to the source files and write access to the destination directory.
Let me know how it goes.