160 lines
5.7 KiB
PHP
160 lines
5.7 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Category;
|
|
use App\Models\Package;
|
|
use App\Models\Version;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class AdminPackageService
|
|
{
|
|
public function createPackage(array $data): Package
|
|
{
|
|
return DB::transaction(function () use ($data) {
|
|
$package = Package::query()->create([
|
|
'type' => $data['type'],
|
|
'slug' => $data['slug'],
|
|
'name' => $data['name'],
|
|
'summary' => $data['summary'] ?? '',
|
|
'description' => $data['description'] ?? '',
|
|
'author' => $data['author'] ?? '',
|
|
'homepage' => $data['homepage'] ?? '',
|
|
'icon_url' => $data['icon_url'] ?? '',
|
|
'license' => $data['license'] ?? '',
|
|
'status' => $data['status'] ?? 'draft',
|
|
'is_featured' => (bool) ($data['is_featured'] ?? false),
|
|
'sort_order' => (int) ($data['sort_order'] ?? 0),
|
|
'download_count' => 0,
|
|
'latest_version' => '',
|
|
]);
|
|
|
|
$this->syncCategories($package, Arr::get($data, 'categories', []));
|
|
|
|
return $package->load(['categories', 'latestStableVersion']);
|
|
});
|
|
}
|
|
|
|
public function updatePackage(Package $package, array $data): Package
|
|
{
|
|
return DB::transaction(function () use ($package, $data) {
|
|
$package->fill([
|
|
'name' => $data['name'] ?? $package->name,
|
|
'summary' => $data['summary'] ?? $package->summary,
|
|
'description' => $data['description'] ?? $package->description,
|
|
'author' => $data['author'] ?? $package->author,
|
|
'homepage' => $data['homepage'] ?? $package->homepage,
|
|
'icon_url' => $data['icon_url'] ?? $package->icon_url,
|
|
'license' => $data['license'] ?? $package->license,
|
|
'status' => $data['status'] ?? $package->status,
|
|
'is_featured' => array_key_exists('is_featured', $data) ? (bool) $data['is_featured'] : $package->is_featured,
|
|
'sort_order' => array_key_exists('sort_order', $data) ? (int) $data['sort_order'] : $package->sort_order,
|
|
]);
|
|
$package->save();
|
|
|
|
if (array_key_exists('categories', $data)) {
|
|
$this->syncCategories($package, Arr::get($data, 'categories', []));
|
|
}
|
|
|
|
$this->refreshLatestVersion($package->fresh());
|
|
|
|
return $package->fresh(['categories', 'latestStableVersion']);
|
|
});
|
|
}
|
|
|
|
public function updateStatus(Package $package, string $status): Package
|
|
{
|
|
$package->status = $status;
|
|
$package->save();
|
|
|
|
return $package->fresh(['categories', 'latestStableVersion']);
|
|
}
|
|
|
|
public function createVersion(Package $package, array $data): Version
|
|
{
|
|
return DB::transaction(function () use ($package, $data) {
|
|
$markAsLatest = array_key_exists('mark_as_latest', $data) ? (bool) $data['mark_as_latest'] : true;
|
|
|
|
if ($markAsLatest) {
|
|
$package->versions()->update(['is_latest' => false]);
|
|
}
|
|
|
|
$version = $package->versions()->create([
|
|
'version' => $data['version'],
|
|
'changelog' => $data['changelog'] ?? '',
|
|
'typecho_min' => $data['typecho_min'] ?? '1.2.0',
|
|
'typecho_max' => $data['typecho_max'] ?? '',
|
|
'php_min' => $data['php_min'] ?? '7.4',
|
|
'php_max' => $data['php_max'] ?? '',
|
|
'php_extensions' => json_encode($data['php_extensions'] ?? [], JSON_UNESCAPED_UNICODE),
|
|
'package_url' => $data['package_url'],
|
|
'package_size' => (int) ($data['package_size'] ?? 0),
|
|
'sha256' => strtolower($data['sha256']),
|
|
'is_stable' => array_key_exists('is_stable', $data) ? (bool) $data['is_stable'] : true,
|
|
'is_latest' => $markAsLatest,
|
|
'download_count' => 0,
|
|
'published_at' => $data['published_at'] ?? now(),
|
|
]);
|
|
|
|
$this->refreshLatestVersion($package->fresh());
|
|
|
|
return $version->fresh();
|
|
});
|
|
}
|
|
|
|
public function deleteVersion(Version $version): void
|
|
{
|
|
DB::transaction(function () use ($version) {
|
|
$package = $version->package;
|
|
$version->delete();
|
|
if ($package) {
|
|
$this->refreshLatestVersion($package->fresh());
|
|
}
|
|
});
|
|
}
|
|
|
|
public function refreshLatestVersion(Package $package): void
|
|
{
|
|
$latestStable = $package->versions()
|
|
->where('is_stable', true)
|
|
->orderByDesc('is_latest')
|
|
->orderByDesc('published_at')
|
|
->orderByDesc('id')
|
|
->first();
|
|
|
|
if ($latestStable) {
|
|
$package->latest_version = $latestStable->version;
|
|
$package->save();
|
|
return;
|
|
}
|
|
|
|
$latestAny = $package->versions()
|
|
->orderByDesc('is_latest')
|
|
->orderByDesc('published_at')
|
|
->orderByDesc('id')
|
|
->first();
|
|
|
|
$package->latest_version = $latestAny?->version ?: '';
|
|
$package->save();
|
|
}
|
|
|
|
private function syncCategories(Package $package, array $categorySlugs): void
|
|
{
|
|
$categorySlugs = array_values(array_unique(array_filter(array_map('strval', $categorySlugs))));
|
|
|
|
if (empty($categorySlugs)) {
|
|
$package->categories()->sync([]);
|
|
return;
|
|
}
|
|
|
|
$categoryIds = Category::query()
|
|
->where('type', $package->type)
|
|
->whereIn('slug', $categorySlugs)
|
|
->pluck('id')
|
|
->all();
|
|
|
|
$package->categories()->sync($categoryIds);
|
|
}
|
|
}
|