HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: /home/xedaptot/be.naniguide.com/app/Http/Controllers/Refactor/BuilderExportController.php
<?php

namespace App\Http\Controllers\Refactor;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use ZipArchive;
use RecursiveIteratorIterator;
use RecursiveDirectoryIterator;

class BuilderExportController extends Controller
{
    /**
     * Export builder HTML as a downloadable .html file.
     * Receives the rendered HTML from the builder (absolute URLs intact).
     */
    public function html(Request $request)
    {
        $html    = $request->input('html', '');
        $baseUrl = rtrim($request->input('baseUrl', ''), '/');

        if (empty($html)) {
            return response()->json(['error' => 'No HTML content provided.'], 422);
        }

        // Convert root-relative URLs to absolute (src="/..." → src="https://domain/...")
        if ($baseUrl) {
            $html = preg_replace(
                '/((?:src|href|action)=")(\/)/',
                '$1' . $baseUrl . '/',
                $html
            );
        }

        return response($html, 200, [
            'Content-Type'        => 'text/html; charset=utf-8',
            'Content-Disposition' => 'attachment; filename="index.html"',
            'Content-Length'      => strlen($html),
        ]);
    }

    /**
     * Export builder HTML + theme assets as a downloadable .zip file.
     * Makes asset URLs relative by stripping themeUrl prefix from the HTML,
     * then bundles the HTML + theme directory into a ZIP.
     */
    public function zip(Request $request)
    {
        $html     = $request->input('html', '');
        $themeUrl = rtrim($request->input('themeUrl', ''), '/');
        $theme    = $request->input('theme', 'default');

        if (empty($html)) {
            return response()->json(['error' => 'No HTML content provided.'], 422);
        }

        // Convert absolute asset URLs → relative paths (strip themeUrl prefix)
        if ($themeUrl) {
            $html = str_replace($themeUrl . '/', '', $html);
        }

        // Resolve theme directory on disk
        $themeDir = storage_path(join_paths('themes', $theme));
        if (!is_dir($themeDir)) {
            // Fallback to resource themes (built-in)
            $themeDir = resource_path(join_paths('themes', $theme));
        }
        if (!is_dir($themeDir)) {
            return response()->json(['error' => "Theme directory not found: {$theme}"], 422);
        }

        // Write HTML to temp file
        $tmpDir  = sys_get_temp_dir() . '/builder_export_' . uniqid();
        mkdir($tmpDir, 0755, true);
        $zipPath = $tmpDir . '/export.zip';

        $zip = new ZipArchive();
        if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
            return response()->json(['error' => 'Failed to create ZIP archive.'], 500);
        }

        // Add modified index.html
        $zip->addFromString('index.html', $html);

        // Add theme assets, skipping builder-internal files
        $skip = ['store.json', 'thumb.png', 'thumb.svg', 'index.json', 'index.html'];
        $files = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($themeDir, RecursiveDirectoryIterator::SKIP_DOTS),
            RecursiveIteratorIterator::LEAVES_ONLY
        );

        foreach ($files as $file) {
            if (!$file->isFile()) {
                continue;
            }

            $absPath  = $file->getRealPath();
            $relPath  = substr($absPath, strlen($themeDir) + 1);

            // Skip builder-internal files
            if (in_array(basename($relPath), $skip)) {
                continue;
            }
            // Skip template HTML files and widgets folder
            if (preg_match('/\.template\.html$/', $relPath)) {
                continue;
            }
            if (strpos($relPath, 'widgets/') === 0 || strpos($relPath, 'widgets\\') === 0) {
                continue;
            }

            $zip->addFile($absPath, $relPath);
        }

        $zip->close();

        $filename = preg_replace('/[^a-zA-Z0-9_-]/', '_', $theme) . '.zip';

        return response()->download($zipPath, $filename, [
            'Content-Type' => 'application/zip',
        ])->deleteFileAfterSend(true);
    }
}