132 lines
3.9 KiB
PHP
132 lines
3.9 KiB
PHP
<?php
|
|
|
|
namespace Paymenter\Extensions\Servers\DownloadableProducts;
|
|
|
|
use App\Classes\Extension\Server;
|
|
use App\Models\Product;
|
|
use App\Models\Service;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Route;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Facades\URL;
|
|
|
|
class DownloadableProducts extends Server
|
|
{
|
|
|
|
public function getProductConfig($values = []): array
|
|
{
|
|
$downloadFile = $values['download_file'] ?? $values['server_config']['download_file'] ?? null;
|
|
|
|
return [
|
|
[
|
|
'name' => 'download_file',
|
|
'label' => 'File Name',
|
|
'type' => 'text',
|
|
'description' => 'Enter the file name you uploaded via SFTP to /var/www/paymenter/storage/app/downloads',
|
|
'required' => true,
|
|
'value' => $downloadFile,
|
|
],
|
|
];
|
|
}
|
|
|
|
public function testConfig(): bool|string
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public function createServer($service, $settings, $properties)
|
|
{
|
|
return [
|
|
'message' => 'Server created (no additional configuration needed).',
|
|
];
|
|
}
|
|
|
|
|
|
public function updateProductSettings(Product $product, array $properties)
|
|
{
|
|
if (!empty($properties['download_file'])) {
|
|
$product->settings()->updateOrCreate(
|
|
['key' => 'download_file'],
|
|
['value' => $properties['download_file']]
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
public function resolveProductFileName(Product $product): ?string
|
|
{
|
|
$setting = $product->settings()->where('key', 'download_file')->first();
|
|
return $setting ? basename($setting->value) : null;
|
|
}
|
|
|
|
|
|
public function getActions(Service $service)
|
|
{
|
|
$product = $service->product;
|
|
$fileName = $this->resolveProductFileName($product);
|
|
|
|
if (!$fileName) {
|
|
return [];
|
|
}
|
|
|
|
return [
|
|
[
|
|
'type' => 'button',
|
|
'label' => 'Download Product',
|
|
'url' => URL::temporarySignedRoute(
|
|
'service.download',
|
|
now()->addMinutes(5),
|
|
['service' => $service->id]
|
|
),
|
|
],
|
|
];
|
|
}
|
|
|
|
public function registerRoutes()
|
|
{
|
|
Route::get('/service/{service}/download', function ($serviceId) {
|
|
$service = Service::find($serviceId);
|
|
|
|
if (!$service) {
|
|
Log::warning('Download attempt: service not found', ['service_id' => $serviceId]);
|
|
abort(404, 'Service not found');
|
|
}
|
|
|
|
$product = $service->product;
|
|
|
|
if (!$product) {
|
|
Log::warning('Download attempt: product not found', ['service_id' => $serviceId]);
|
|
abort(404, 'Product not found');
|
|
}
|
|
|
|
$fileName = (new self())->resolveProductFileName($product);
|
|
|
|
if (!$fileName) {
|
|
abort(404, 'File not configured for this product.');
|
|
}
|
|
|
|
$disk = Storage::disk('downloads');
|
|
|
|
if (!$disk->exists($fileName)) {
|
|
Log::warning('Download attempt: file missing', [
|
|
'service_id' => $serviceId,
|
|
'product_id' => $product->id,
|
|
'file' => $fileName
|
|
]);
|
|
abort(404, "File not found in downloads: {$fileName}");
|
|
}
|
|
|
|
Log::info('File downloaded', [
|
|
'service_id' => $serviceId,
|
|
'product_id' => $product->id,
|
|
'file' => $fileName,
|
|
]);
|
|
|
|
return $disk->download($fileName, $fileName);
|
|
})->name('service.download')->middleware('signed');
|
|
}
|
|
}
|
|
|
|
$server = new DownloadableProducts();
|
|
$server->registerRoutes();
|