Tstore/app/Services/AdminPackageService.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);
}
}