PLATFORM
  • Tails

    Create websites with TailwindCSS

  • Blocks

    Design blocks for your website

  • Wave

    Start building the next great SAAS

  • Pines

    Alpine & Tailwind UI Library

  • Auth

    Plug'n Play Authentication for Laravel

  • Designer comingsoon

    Create website designs with AI

  • DevBlog comingsoon

    Blog platform for developers

  • Static

    Build a simple static website

  • SaaS Adventure

    21-day program to build a SAAS

Question By
Solved
Solved
brianh

Jun 24th, 2023 01:10 PM

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?

brianh

Jun 25th, 2023 02:49 AM

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

bobbyiliev

Jun 25th, 2023 05:16 AM

Best Answer

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.