102 lines
3.0 KiB
PHP
102 lines
3.0 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
class SiteAssetSyncService
|
|
{
|
|
/**
|
|
* Copy a file from Laravel's public disk into usher-site/public so Next.js can serve it as a static asset.
|
|
*
|
|
* Returns the relative path under Next.js public/ (no leading slash), e.g. "uploads/articles/images/foo.jpg".
|
|
* If the Next.js public path is not configured / not present, returns null and callers should fall back
|
|
* to serving from Laravel storage.
|
|
*/
|
|
public static function syncPublicDiskFileToNext(string $publicDiskPath): ?string
|
|
{
|
|
$publicDiskPath = ltrim($publicDiskPath, '/');
|
|
|
|
$nextPublicRoot = static::resolveNextPublicRoot();
|
|
if (! $nextPublicRoot) {
|
|
return null;
|
|
}
|
|
|
|
$source = Storage::disk('public')->path($publicDiskPath);
|
|
if (! is_file($source)) {
|
|
Log::warning("Site asset sync skipped (source missing): {$publicDiskPath}");
|
|
|
|
return null;
|
|
}
|
|
|
|
$prefix = config('services.nextjs.public_upload_prefix', 'uploads');
|
|
$prefix = trim((string) $prefix, '/');
|
|
if ($prefix === '') {
|
|
$prefix = 'uploads';
|
|
}
|
|
|
|
$relativeDest = $prefix.'/'.$publicDiskPath;
|
|
$dest = rtrim($nextPublicRoot, '/').'/'.$relativeDest;
|
|
|
|
$destDir = dirname($dest);
|
|
if (! is_dir($destDir) && ! @mkdir($destDir, 0755, true) && ! is_dir($destDir)) {
|
|
Log::warning("Site asset sync failed (mkdir): {$destDir}");
|
|
|
|
return null;
|
|
}
|
|
|
|
if (! @copy($source, $dest)) {
|
|
Log::warning("Site asset sync failed (copy): {$publicDiskPath} -> {$dest}");
|
|
|
|
return null;
|
|
}
|
|
|
|
// Optionally commit+push the updated assets into the usher-site repo.
|
|
NextjsRepoSyncService::scheduleAssetsPush();
|
|
|
|
return $relativeDest;
|
|
}
|
|
|
|
/**
|
|
* Delete a previously synced Next.js public asset (best-effort).
|
|
*/
|
|
public static function deleteNextPublicFile(?string $nextPublicRelativePath): void
|
|
{
|
|
if (! $nextPublicRelativePath) {
|
|
return;
|
|
}
|
|
|
|
$nextPublicRoot = static::resolveNextPublicRoot();
|
|
if (! $nextPublicRoot) {
|
|
return;
|
|
}
|
|
|
|
$rel = ltrim($nextPublicRelativePath, '/');
|
|
$path = rtrim($nextPublicRoot, '/').'/'.$rel;
|
|
|
|
if (is_file($path)) {
|
|
@unlink($path);
|
|
}
|
|
|
|
// Stage deletion via scheduled push (best-effort).
|
|
NextjsRepoSyncService::scheduleAssetsPush();
|
|
}
|
|
|
|
private static function resolveNextPublicRoot(): ?string
|
|
{
|
|
$configured = config('services.nextjs.public_path');
|
|
if (is_string($configured) && $configured !== '' && is_dir($configured)) {
|
|
return $configured;
|
|
}
|
|
|
|
// Local-dev default: sibling repo next to this Laravel repo.
|
|
$guess = base_path('../usher-site/public');
|
|
if (is_dir($guess)) {
|
|
return $guess;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|