88 lines
2.6 KiB
PHP
88 lines
2.6 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Requests\Admin;
|
||
|
||
use Illuminate\Foundation\Http\FormRequest;
|
||
use Illuminate\Validation\Validator;
|
||
use ZipArchive;
|
||
|
||
class PublishZipVersionRequest extends FormRequest
|
||
{
|
||
public function authorize(): bool
|
||
{
|
||
return true;
|
||
}
|
||
|
||
protected function prepareForValidation(): void
|
||
{
|
||
$extensions = $this->input('php_extensions');
|
||
|
||
if (is_string($extensions)) {
|
||
$this->merge([
|
||
'php_extensions' => collect(preg_split('/[,,\s]+/u', $extensions))
|
||
->map(fn ($item) => trim((string) $item))
|
||
->filter()
|
||
->values()
|
||
->all(),
|
||
]);
|
||
}
|
||
}
|
||
|
||
public function rules(): array
|
||
{
|
||
return [
|
||
'package_file' => ['required', 'file', 'mimes:zip', 'max:51200'],
|
||
'version' => ['nullable', 'string', 'max:32', 'regex:/^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?$/'],
|
||
'typecho_min' => ['nullable', 'string', 'max:16'],
|
||
'typecho_max' => ['nullable', 'string', 'max:16'],
|
||
'php_min' => ['nullable', 'string', 'max:16'],
|
||
'php_max' => ['nullable', 'string', 'max:16'],
|
||
'php_extensions' => ['nullable', 'array'],
|
||
'php_extensions.*' => ['string', 'max:32'],
|
||
'is_stable' => ['nullable', 'boolean'],
|
||
'mark_as_latest' => ['nullable', 'boolean'],
|
||
'changelog' => ['nullable', 'string'],
|
||
'published_at' => ['nullable', 'date'],
|
||
];
|
||
}
|
||
|
||
public function withValidator(Validator $validator): void
|
||
{
|
||
$validator->after(function (Validator $validator) {
|
||
$file = $this->file('package_file');
|
||
|
||
if (!$file || !$file->isValid() || $this->zipHasManifestAtRoot($file->getRealPath())) {
|
||
return;
|
||
}
|
||
|
||
if (blank((string) $this->input('version', ''))) {
|
||
$validator->errors()->add('version', 'zip 根目录没有 manifest.json 时,必须手动填写版本号。');
|
||
}
|
||
});
|
||
}
|
||
|
||
private function zipHasManifestAtRoot(string $path): bool
|
||
{
|
||
$zip = new ZipArchive();
|
||
|
||
if ($zip->open($path) !== true) {
|
||
return false;
|
||
}
|
||
|
||
try {
|
||
for ($i = 0; $i < $zip->numFiles; $i++) {
|
||
$stat = $zip->statIndex($i);
|
||
$name = trim((string) ($stat['name'] ?? ''), '/');
|
||
|
||
if ($name === 'manifest.json') {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
} finally {
|
||
$zip->close();
|
||
}
|
||
}
|
||
}
|