Finalize service option import/export
This commit is contained in:
parent
d608c313c3
commit
6269a08db7
16 changed files with 405 additions and 271 deletions
|
@ -33,6 +33,16 @@ interface ServiceOptionRepositoryInterface extends RepositoryInterface
|
|||
*/
|
||||
public function getWithCopyAttributes(int $id): ServiceOption;
|
||||
|
||||
/**
|
||||
* Return all of the data needed to export a service.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Pterodactyl\Models\ServiceOption
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function getWithExportAttributes(int $id): ServiceOption;
|
||||
|
||||
/**
|
||||
* Confirm a copy script belongs to the same service as the item trying to use it.
|
||||
*
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
namespace Pterodactyl\Contracts\Repository;
|
||||
|
||||
use Pterodactyl\Models\Service;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
interface ServiceRepositoryInterface extends RepositoryInterface
|
||||
{
|
||||
|
@ -18,23 +17,29 @@ interface ServiceRepositoryInterface extends RepositoryInterface
|
|||
* Return a service or all services with their associated options, variables, and packs.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Support\Collection
|
||||
* @return \Illuminate\Database\Eloquent\Collection|\Pterodactyl\Models\Service
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function getWithOptions(int $id = null): Collection;
|
||||
public function getWithOptions(int $id = null);
|
||||
|
||||
/**
|
||||
* Return a service or all services and the count of options, packs, and servers for that service.
|
||||
*
|
||||
* @param int|null $id
|
||||
* @return \Illuminate\Support\Collection
|
||||
* @return \Pterodactyl\Models\Service|\Illuminate\Database\Eloquent\Collection
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function getWithCounts(int $id = null): Collection;
|
||||
public function getWithCounts(int $id = null);
|
||||
|
||||
/**
|
||||
* Return a service along with its associated options and the servers relation on those options.
|
||||
*
|
||||
* @param int $id
|
||||
* @return mixed
|
||||
* @return \Pterodactyl\Models\Service
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function getWithOptionServers(int $id): Service;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/*
|
||||
* Pterodactyl - Panel
|
||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||
*
|
||||
* This software is licensed under the terms of the MIT license.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
namespace Pterodactyl\Exceptions\Service\ServiceOption;
|
||||
|
||||
use Pterodactyl\Exceptions\DisplayException;
|
||||
|
||||
class DuplicateOptionTagException extends DisplayException
|
||||
{
|
||||
}
|
|
@ -9,26 +9,38 @@
|
|||
|
||||
namespace Pterodactyl\Http\Controllers\Admin\Services\Options;
|
||||
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Pterodactyl\Models\ServiceOption;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Pterodactyl\Services\Services\Exporter\XMLExporterService;
|
||||
use Pterodactyl\Http\Requests\Admin\Service\OptionImportFormRequest;
|
||||
use Pterodactyl\Services\Services\Sharing\ServiceOptionExporterService;
|
||||
use Pterodactyl\Services\Services\Sharing\ServiceOptionImporterService;
|
||||
|
||||
class OptionShareController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Services\Exporter\XMLExporterService
|
||||
* @var \Pterodactyl\Services\Services\Sharing\ServiceOptionExporterService
|
||||
*/
|
||||
protected $exporterService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Services\Sharing\ServiceOptionImporterService
|
||||
*/
|
||||
protected $importerService;
|
||||
|
||||
/**
|
||||
* OptionShareController constructor.
|
||||
*
|
||||
* @param \Pterodactyl\Services\Services\Exporter\XMLExporterService $exporterService
|
||||
* @param \Pterodactyl\Services\Services\Sharing\ServiceOptionExporterService $exporterService
|
||||
* @param \Pterodactyl\Services\Services\Sharing\ServiceOptionImporterService $importerService
|
||||
*/
|
||||
public function __construct(XMLExporterService $exporterService)
|
||||
{
|
||||
public function __construct(
|
||||
ServiceOptionExporterService $exporterService,
|
||||
ServiceOptionImporterService $importerService
|
||||
) {
|
||||
$this->exporterService = $exporterService;
|
||||
$this->importerService = $importerService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,8 +54,25 @@ class OptionShareController extends Controller
|
|||
return response($this->exporterService->handle($option->id), 200, [
|
||||
'Content-Transfer-Encoding' => 'binary',
|
||||
'Content-Description' => 'File Transfer',
|
||||
'Content-Disposition' => 'attachment; filename=' . kebab_case($option->name) . '.xml',
|
||||
'Content-Type' => 'application/xml',
|
||||
'Content-Disposition' => 'attachment; filename=' . kebab_case($option->name) . '.json',
|
||||
'Content-Type' => 'application/json',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a new service option using an XML file.
|
||||
*
|
||||
* @param \Pterodactyl\Http\Requests\Admin\Service\OptionImportFormRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Pack\InvalidFileUploadException
|
||||
*/
|
||||
public function import(OptionImportFormRequest $request): RedirectResponse
|
||||
{
|
||||
$option = $this->importerService->handle($request->file('import_file'), $request->input('import_to_service'));
|
||||
|
||||
return redirect()->route('admin.services.option.view', ['option' => $option->id]);
|
||||
}
|
||||
}
|
||||
|
|
26
app/Http/Requests/Admin/Service/OptionImportFormRequest.php
Normal file
26
app/Http/Requests/Admin/Service/OptionImportFormRequest.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
/**
|
||||
* Pterodactyl - Panel
|
||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||
*
|
||||
* This software is licensed under the terms of the MIT license.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin\Service;
|
||||
|
||||
use Pterodactyl\Http\Requests\Admin\AdminFormRequest;
|
||||
|
||||
class OptionImportFormRequest extends AdminFormRequest
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'import_file' => 'bail|required|file|max:1000|mimetypes:application/json,text/plain',
|
||||
'import_to_service' => 'bail|required|integer|exists:services,id',
|
||||
];
|
||||
}
|
||||
}
|
|
@ -65,7 +65,6 @@ class ServiceOption extends Model implements CleansAttributes, ValidableContract
|
|||
*/
|
||||
protected static $applicationRules = [
|
||||
'service_id' => 'required',
|
||||
'author' => 'required',
|
||||
'name' => 'required',
|
||||
'description' => 'required',
|
||||
'tag' => 'required',
|
||||
|
@ -83,10 +82,10 @@ class ServiceOption extends Model implements CleansAttributes, ValidableContract
|
|||
*/
|
||||
protected static $dataIntegrityRules = [
|
||||
'service_id' => 'bail|numeric|exists:services,id',
|
||||
'author' => 'email',
|
||||
'uuid' => 'string|size:36',
|
||||
'name' => 'string|max:255',
|
||||
'description' => 'string',
|
||||
'tag' => 'bail|alpha_num|max:60|unique:service_options,tag',
|
||||
'tag' => 'bail|string|max:150',
|
||||
'docker_image' => 'string|max:255',
|
||||
'startup' => 'nullable|string',
|
||||
'config_from' => 'bail|nullable|numeric|exists:service_options,id',
|
||||
|
|
|
@ -61,6 +61,25 @@ class ServiceOptionRepository extends EloquentRepository implements ServiceOptio
|
|||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all of the data needed to export a service.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Pterodactyl\Models\ServiceOption
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function getWithExportAttributes(int $id): ServiceOption
|
||||
{
|
||||
/** @var \Pterodactyl\Models\ServiceOption $instance */
|
||||
$instance = $this->getBuilder()->with('scriptFrom', 'configFrom', 'variables')->find($id, $this->getColumns());
|
||||
if (! $instance) {
|
||||
throw new RecordNotFoundException;
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm a copy script belongs to the same service as the item trying to use it.
|
||||
*
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
namespace Pterodactyl\Repositories\Eloquent;
|
||||
|
||||
use Pterodactyl\Models\Service;
|
||||
use Illuminate\Support\Collection;
|
||||
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
|
||||
use Pterodactyl\Contracts\Repository\ServiceRepositoryInterface;
|
||||
|
||||
|
@ -25,9 +24,14 @@ class ServiceRepository extends EloquentRepository implements ServiceRepositoryI
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Return a service or all services with their associated options, variables, and packs.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Database\Eloquent\Collection|\Pterodactyl\Models\Service
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function getWithOptions(int $id = null): Collection
|
||||
public function getWithOptions(int $id = null)
|
||||
{
|
||||
$instance = $this->getBuilder()->with('options.packs', 'options.variables');
|
||||
|
||||
|
@ -44,9 +48,14 @@ class ServiceRepository extends EloquentRepository implements ServiceRepositoryI
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Return a service or all services and the count of options, packs, and servers for that service.
|
||||
*
|
||||
* @param int|null $id
|
||||
* @return \Illuminate\Database\Eloquent\Collection|\Pterodactyl\Models\Service
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function getWithCounts(int $id = null): Collection
|
||||
public function getWithCounts(int $id = null)
|
||||
{
|
||||
$instance = $this->getBuilder()->withCount(['options', 'packs', 'servers']);
|
||||
|
||||
|
@ -63,7 +72,12 @@ class ServiceRepository extends EloquentRepository implements ServiceRepositoryI
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Return a service along with its associated options and the servers relation on those options.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Pterodactyl\Models\Service
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function getWithOptionServers(int $id): Service
|
||||
{
|
||||
|
|
|
@ -1,132 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Pterodactyl - Panel
|
||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||
*
|
||||
* This software is licensed under the terms of the MIT license.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
namespace Pterodactyl\Services\Services\Exporter;
|
||||
|
||||
use Closure;
|
||||
use Carbon\Carbon;
|
||||
use Sabre\Xml\Writer;
|
||||
use Sabre\Xml\Service;
|
||||
use Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface;
|
||||
|
||||
class XMLExporterService
|
||||
{
|
||||
const XML_OPTION_NAMESPACE = '{https://pterodactyl.io/exporter/option/}';
|
||||
|
||||
/**
|
||||
* @var \Carbon\Carbon
|
||||
*/
|
||||
protected $carbon;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* @var \Sabre\Xml\Service
|
||||
*/
|
||||
protected $xml;
|
||||
|
||||
/**
|
||||
* XMLExporterService constructor.
|
||||
*
|
||||
* @param \Carbon\Carbon $carbon
|
||||
* @param \Sabre\Xml\Service $xml
|
||||
* @param \Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface $repository
|
||||
*/
|
||||
public function __construct(
|
||||
Carbon $carbon,
|
||||
Service $xml,
|
||||
ServiceOptionRepositoryInterface $repository
|
||||
) {
|
||||
$this->carbon = $carbon;
|
||||
$this->repository = $repository;
|
||||
$this->xml = $xml;
|
||||
|
||||
$this->xml->namespaceMap = [
|
||||
str_replace(['{', '}'], '', self::XML_OPTION_NAMESPACE) => 'p',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an XML structure to represent this service option.
|
||||
*
|
||||
* @param int $option
|
||||
* @return string
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function handle(int $option): string
|
||||
{
|
||||
$option = $this->repository->getWithCopyAttributes($option);
|
||||
|
||||
$struct = [
|
||||
'meta' => [
|
||||
'version' => 'PTDL_v1',
|
||||
],
|
||||
'exported_at' => $this->carbon->now()->toIso8601String(),
|
||||
'name' => $option->name,
|
||||
'author' => array_get(explode(':', $option->tag), 0),
|
||||
'tag' => $option->tag,
|
||||
'description' => $this->writeCData($option->description),
|
||||
'image' => $option->docker_image,
|
||||
'config' => [
|
||||
'files' => $this->writeCData($option->inherit_config_files),
|
||||
'startup' => $this->writeCData($option->inherit_config_startup),
|
||||
'logs' => $this->writeCData($option->inherit_config_logs),
|
||||
'stop' => $option->inherit_config_stop,
|
||||
],
|
||||
'scripts' => [
|
||||
'installation' => [
|
||||
'script' => $this->writeCData($option->copy_script_install),
|
||||
'container' => $option->copy_script_container,
|
||||
'entrypoint' => $option->copy_script_entry,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
return $this->xml->write(self::XML_OPTION_NAMESPACE . 'root', $this->recursiveArrayKeyPrepend($struct));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $array
|
||||
* @param string $prepend
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function recursiveArrayKeyPrepend(array $array, $prepend = self::XML_OPTION_NAMESPACE): array
|
||||
{
|
||||
$parsed = [];
|
||||
foreach ($array as $k => &$v) {
|
||||
$k = $prepend . $k;
|
||||
|
||||
if (is_array($v)) {
|
||||
$v = $this->recursiveArrayKeyPrepend($v);
|
||||
}
|
||||
|
||||
$parsed[$k] = $v;
|
||||
}
|
||||
|
||||
return $parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a closure to be used by the XML writer to generate a string wrapped in CDATA tags.
|
||||
*
|
||||
* @param string $value
|
||||
* @return \Closure
|
||||
*/
|
||||
protected function writeCData(string $value): Closure
|
||||
{
|
||||
return function (Writer $writer) use ($value) {
|
||||
return $writer->writeCData($value);
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
/**
|
||||
* Pterodactyl - Panel
|
||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||
*
|
||||
* This software is licensed under the terms of the MIT license.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
namespace Pterodactyl\Services\Services\Sharing;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface;
|
||||
|
||||
class ServiceOptionExporterService
|
||||
{
|
||||
/**
|
||||
* @var \Carbon\Carbon
|
||||
*/
|
||||
protected $carbon;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* XMLExporterService constructor.
|
||||
*
|
||||
* @param \Carbon\Carbon $carbon
|
||||
* @param \Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface $repository
|
||||
*/
|
||||
public function __construct(
|
||||
Carbon $carbon,
|
||||
ServiceOptionRepositoryInterface $repository
|
||||
) {
|
||||
$this->carbon = $carbon;
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an XML structure to represent this service option.
|
||||
*
|
||||
* @param int $option
|
||||
* @return string
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
*/
|
||||
public function handle(int $option): string
|
||||
{
|
||||
$option = $this->repository->getWithExportAttributes($option);
|
||||
|
||||
$struct = [
|
||||
'_comment' => 'DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PTERODACTYL PANEL - PTERODACTYL.IO',
|
||||
'meta' => [
|
||||
'version' => 'PTDL_v1',
|
||||
],
|
||||
'exported_at' => $this->carbon->now()->toIso8601String(),
|
||||
'name' => $option->name,
|
||||
'author' => array_get(explode(':', $option->tag), 0),
|
||||
'tag' => $option->tag,
|
||||
'description' => $option->description,
|
||||
'image' => $option->docker_image,
|
||||
'startup' => $option->display_startup,
|
||||
'config' => [
|
||||
'files' => $option->inherit_config_files,
|
||||
'startup' => $option->inherit_config_startup,
|
||||
'logs' => $option->inherit_config_logs,
|
||||
'stop' => $option->inherit_config_stop,
|
||||
],
|
||||
'scripts' => [
|
||||
'installation' => [
|
||||
'script' => $option->copy_script_install,
|
||||
'container' => $option->copy_script_container,
|
||||
'entrypoint' => $option->copy_script_entry,
|
||||
],
|
||||
],
|
||||
'variables' => $option->variables->transform(function ($item) {
|
||||
return collect($item->toArray())->except([
|
||||
'id', 'option_id', 'created_at', 'updated_at',
|
||||
])->toArray();
|
||||
}),
|
||||
];
|
||||
|
||||
return json_encode($struct, JSON_PRETTY_PRINT);
|
||||
}
|
||||
}
|
123
app/Services/Services/Sharing/ServiceOptionImporterService.php
Normal file
123
app/Services/Services/Sharing/ServiceOptionImporterService.php
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
/**
|
||||
* Pterodactyl - Panel
|
||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||
*
|
||||
* This software is licensed under the terms of the MIT license.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
namespace Pterodactyl\Services\Services\Sharing;
|
||||
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Pterodactyl\Models\ServiceOption;
|
||||
use Illuminate\Database\ConnectionInterface;
|
||||
use Pterodactyl\Contracts\Repository\ServiceRepositoryInterface;
|
||||
use Pterodactyl\Exceptions\Service\Pack\InvalidFileUploadException;
|
||||
use Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface;
|
||||
use Pterodactyl\Contracts\Repository\ServiceVariableRepositoryInterface;
|
||||
use Pterodactyl\Exceptions\Service\ServiceOption\DuplicateOptionTagException;
|
||||
|
||||
class ServiceOptionImporterService
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Database\ConnectionInterface
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\ServiceRepositoryInterface
|
||||
*/
|
||||
protected $serviceRepository;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\ServiceVariableRepositoryInterface
|
||||
*/
|
||||
protected $serviceVariableRepository;
|
||||
|
||||
/**
|
||||
* XMLImporterService constructor.
|
||||
*
|
||||
* @param \Illuminate\Database\ConnectionInterface $connection
|
||||
* @param \Pterodactyl\Contracts\Repository\ServiceRepositoryInterface $serviceRepository
|
||||
* @param \Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface $repository
|
||||
* @param \Pterodactyl\Contracts\Repository\ServiceVariableRepositoryInterface $serviceVariableRepository
|
||||
*/
|
||||
public function __construct(
|
||||
ConnectionInterface $connection,
|
||||
ServiceRepositoryInterface $serviceRepository,
|
||||
ServiceOptionRepositoryInterface $repository,
|
||||
ServiceVariableRepositoryInterface $serviceVariableRepository
|
||||
) {
|
||||
$this->connection = $connection;
|
||||
$this->repository = $repository;
|
||||
$this->serviceRepository = $serviceRepository;
|
||||
$this->serviceVariableRepository = $serviceVariableRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take an uploaded XML file and parse it into a new service option.
|
||||
*
|
||||
* @param \Illuminate\Http\UploadedFile $file
|
||||
* @param int $service
|
||||
* @return \Pterodactyl\Models\ServiceOption
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||
* @throws \Pterodactyl\Exceptions\Service\Pack\InvalidFileUploadException
|
||||
*/
|
||||
public function handle(UploadedFile $file, int $service): ServiceOption
|
||||
{
|
||||
if (! $file->isValid() || ! $file->isFile()) {
|
||||
throw new InvalidFileUploadException(trans('exceptions.service.exporter.import_file_error'));
|
||||
}
|
||||
|
||||
$parsed = json_decode($file->openFile()->fread($file->getSize()));
|
||||
|
||||
if (object_get($parsed, 'meta.version') !== 'PTDL_v1') {
|
||||
throw new InvalidFileUploadException(trans('exceptions.service.exporter.invalid_json_provided'));
|
||||
}
|
||||
|
||||
$service = $this->serviceRepository->getWithOptions($service);
|
||||
$service->options->each(function ($option) use ($parsed) {
|
||||
if ($option->tag === object_get($parsed, 'tag')) {
|
||||
throw new DuplicateOptionTagException(trans('exceptions.service.options.duplicate_tag'));
|
||||
}
|
||||
});
|
||||
|
||||
$this->connection->beginTransaction();
|
||||
$option = $this->repository->create([
|
||||
'uuid' => Uuid::uuid4()->toString(),
|
||||
'service_id' => $service->id,
|
||||
'name' => object_get($parsed, 'name'),
|
||||
'description' => object_get($parsed, 'description'),
|
||||
'tag' => object_get($parsed, 'tag'),
|
||||
'docker_image' => object_get($parsed, 'image'),
|
||||
'config_files' => object_get($parsed, 'config.files'),
|
||||
'config_startup' => object_get($parsed, 'config.startup'),
|
||||
'config_logs' => object_get($parsed, 'config.logs'),
|
||||
'config_stop' => object_get($parsed, 'config.stop'),
|
||||
'startup' => object_get($parsed, 'startup'),
|
||||
'script_install' => object_get($parsed, 'scripts.installation.script'),
|
||||
'script_entry' => object_get($parsed, 'scripts.installation.entrypoint'),
|
||||
'script_container' => object_get($parsed, 'scripts.installation.container'),
|
||||
'copy_script_from' => null,
|
||||
], true, true);
|
||||
|
||||
collect($parsed->variables)->each(function ($variable) use ($option) {
|
||||
$this->serviceVariableRepository->create(array_merge((array) $variable, [
|
||||
'option_id' => $option->id,
|
||||
]));
|
||||
});
|
||||
|
||||
$this->connection->commit();
|
||||
|
||||
return $option;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue