Skip to content

Commit d608c31

Browse files
committed
Complete the service option export configuration
1 parent 0d73925 commit d608c31

File tree

6 files changed

+141
-40
lines changed

6 files changed

+141
-40
lines changed

app/Contracts/Repository/ServiceOptionRepositoryInterface.php

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,29 @@
99

1010
namespace Pterodactyl\Contracts\Repository;
1111

12+
use Pterodactyl\Models\ServiceOption;
13+
1214
interface ServiceOptionRepositoryInterface extends RepositoryInterface
1315
{
1416
/**
1517
* Return a service option with the variables relation attached.
1618
*
1719
* @param int $id
18-
* @return mixed
20+
* @return \Pterodactyl\Models\ServiceOption
21+
*
22+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
1923
*/
20-
public function getWithVariables($id);
24+
public function getWithVariables(int $id): ServiceOption;
2125

2226
/**
23-
* Return a service option with the copyFrom relation loaded onto the model.
27+
* Return a service option with the scriptFrom and configFrom relations loaded onto the model.
2428
*
2529
* @param int $id
26-
* @return mixed
30+
* @return \Pterodactyl\Models\ServiceOption
31+
*
32+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
2733
*/
28-
public function getWithCopyFrom($id);
34+
public function getWithCopyAttributes(int $id): ServiceOption;
2935

3036
/**
3137
* Confirm a copy script belongs to the same service as the item trying to use it.
@@ -34,5 +40,5 @@ public function getWithCopyFrom($id);
3440
* @param int $service
3541
* @return bool
3642
*/
37-
public function isCopiableScript($copyFromId, $service);
43+
public function isCopiableScript(int $copyFromId, int $service): bool;
3844
}

app/Http/Controllers/Admin/OptionController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ public function viewConfiguration(ServiceOption $option)
163163
*/
164164
public function viewScripts($option)
165165
{
166-
$option = $this->serviceOptionRepository->getWithCopyFrom($option);
166+
$option = $this->serviceOptionRepository->getWithCopyAttributes($option);
167167
$copyOptions = $this->serviceOptionRepository->findWhere([
168168
['copy_script_from', '=', null],
169169
['service_id', '=', $option->service_id],

app/Http/Controllers/Admin/Services/Options/OptionShareController.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
use Pterodactyl\Models\ServiceOption;
1313
use Pterodactyl\Http\Controllers\Controller;
14+
use Symfony\Component\HttpFoundation\Response;
1415
use Pterodactyl\Services\Services\Exporter\XMLExporterService;
1516

1617
class OptionShareController extends Controller
@@ -32,13 +33,16 @@ public function __construct(XMLExporterService $exporterService)
3233

3334
/**
3435
* @param \Pterodactyl\Models\ServiceOption $option
35-
* @return $this
36+
* @return \Symfony\Component\HttpFoundation\Response
3637
*
3738
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
3839
*/
39-
public function export(ServiceOption $option)
40+
public function export(ServiceOption $option): Response
4041
{
41-
return response($this->exporterService->handle($option), 200, [
42+
return response($this->exporterService->handle($option->id), 200, [
43+
'Content-Transfer-Encoding' => 'binary',
44+
'Content-Description' => 'File Transfer',
45+
'Content-Disposition' => 'attachment; filename=' . kebab_case($option->name) . '.xml',
4246
'Content-Type' => 'application/xml',
4347
]);
4448
}

app/Models/ServiceOption.php

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ class ServiceOption extends Model implements CleansAttributes, ValidableContract
114114
*
115115
* @return string
116116
*/
117-
public function getDisplayStartupAttribute($value)
117+
public function getDisplayStartupAttribute()
118118
{
119119
return (is_null($this->startup)) ? $this->service->startup : $this->startup;
120120
}
@@ -125,9 +125,9 @@ public function getDisplayStartupAttribute($value)
125125
*
126126
* @return string
127127
*/
128-
public function getCopyScriptInstallAttribute($value)
128+
public function getCopyScriptInstallAttribute()
129129
{
130-
return (is_null($this->copy_script_from)) ? $this->script_install : $this->copyFrom->script_install;
130+
return (is_null($this->copy_script_from)) ? $this->script_install : $this->scriptFrom->script_install;
131131
}
132132

133133
/**
@@ -136,9 +136,9 @@ public function getCopyScriptInstallAttribute($value)
136136
*
137137
* @return string
138138
*/
139-
public function getCopyScriptEntryAttribute($value)
139+
public function getCopyScriptEntryAttribute()
140140
{
141-
return (is_null($this->copy_script_from)) ? $this->script_entry : $this->copyFrom->script_entry;
141+
return (is_null($this->copy_script_from)) ? $this->script_entry : $this->scriptFrom->script_entry;
142142
}
143143

144144
/**
@@ -147,9 +147,49 @@ public function getCopyScriptEntryAttribute($value)
147147
*
148148
* @return string
149149
*/
150-
public function getCopyScriptContainerAttribute($value)
150+
public function getCopyScriptContainerAttribute()
151151
{
152-
return (is_null($this->copy_script_from)) ? $this->script_container : $this->copyFrom->script_container;
152+
return (is_null($this->copy_script_from)) ? $this->script_container : $this->scriptFrom->script_container;
153+
}
154+
155+
/**
156+
* Return the file configuration for a service option.
157+
*
158+
* @return string
159+
*/
160+
public function getInheritConfigFilesAttribute()
161+
{
162+
return is_null($this->config_from) ? $this->config_files : $this->configFrom->config_files;
163+
}
164+
165+
/**
166+
* Return the startup configuration for a service option.
167+
*
168+
* @return string
169+
*/
170+
public function getInheritConfigStartupAttribute()
171+
{
172+
return is_null($this->config_from) ? $this->config_startup : $this->configFrom->config_startup;
173+
}
174+
175+
/**
176+
* Return the log reading configuration for a service option.
177+
*
178+
* @return string
179+
*/
180+
public function getInheritConfigLogsAttribute()
181+
{
182+
return is_null($this->config_from) ? $this->config_logs : $this->configFrom->config_logs;
183+
}
184+
185+
/**
186+
* Return the stop command configuration for a service option.
187+
*
188+
* @return string
189+
*/
190+
public function getInheritConfigStopAttribute()
191+
{
192+
return is_null($this->config_from) ? $this->config_stop : $this->configFrom->config_stop;
153193
}
154194

155195
/**
@@ -197,8 +237,18 @@ public function packs()
197237
*
198238
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
199239
*/
200-
public function copyFrom()
240+
public function scriptFrom()
201241
{
202242
return $this->belongsTo(self::class, 'copy_script_from');
203243
}
244+
245+
/**
246+
* Get the parent service option from which to copy configuration settings.
247+
*
248+
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
249+
*/
250+
public function configFrom()
251+
{
252+
return $this->belongsTo(self::class, 'config_from');
253+
}
204254
}

app/Repositories/Eloquent/ServiceOptionRepository.php

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
namespace Pterodactyl\Repositories\Eloquent;
1111

1212
use Pterodactyl\Models\ServiceOption;
13+
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
1314
use Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface;
1415

1516
class ServiceOptionRepository extends EloquentRepository implements ServiceOptionRepositoryInterface
@@ -23,25 +24,51 @@ public function model()
2324
}
2425

2526
/**
26-
* {@inheritdoc}
27+
* Return a service option with the variables relation attached.
28+
*
29+
* @param int $id
30+
* @return \Pterodactyl\Models\ServiceOption
31+
*
32+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
2733
*/
28-
public function getWithVariables($id)
34+
public function getWithVariables(int $id): ServiceOption
2935
{
30-
return $this->getBuilder()->with('variables')->find($id, $this->getColumns());
36+
/** @var \Pterodactyl\Models\ServiceOption $instance */
37+
$instance = $this->getBuilder()->with('variables')->find($id, $this->getColumns());
38+
if (! $instance) {
39+
throw new RecordNotFoundException;
40+
}
41+
42+
return $instance;
3143
}
3244

3345
/**
34-
* {@inheritdoc}
46+
* Return a service option with the scriptFrom and configFrom relations loaded onto the model.
47+
*
48+
* @param int $id
49+
* @return \Pterodactyl\Models\ServiceOption
50+
*
51+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
3552
*/
36-
public function getWithCopyFrom($id)
53+
public function getWithCopyAttributes(int $id): ServiceOption
3754
{
38-
return $this->getBuilder()->with('copyFrom')->find($id, $this->getColumns());
55+
/** @var \Pterodactyl\Models\ServiceOption $instance */
56+
$instance = $this->getBuilder()->with('scriptFrom', 'configFrom')->find($id, $this->getColumns());
57+
if (! $instance) {
58+
throw new RecordNotFoundException;
59+
}
60+
61+
return $instance;
3962
}
4063

4164
/**
42-
* {@inheritdoc}
65+
* Confirm a copy script belongs to the same service as the item trying to use it.
66+
*
67+
* @param int $copyFromId
68+
* @param int $service
69+
* @return bool
4370
*/
44-
public function isCopiableScript($copyFromId, $service)
71+
public function isCopiableScript(int $copyFromId, int $service): bool
4572
{
4673
return $this->getBuilder()->whereNull('copy_script_from')
4774
->where('id', '=', $copyFromId)

app/Services/Services/Exporter/XMLExporterService.php

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99

1010
namespace Pterodactyl\Services\Services\Exporter;
1111

12+
use Closure;
1213
use Carbon\Carbon;
1314
use Sabre\Xml\Writer;
1415
use Sabre\Xml\Service;
15-
use Pterodactyl\Models\ServiceOption;
1616
use Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface;
1717

1818
class XMLExporterService
@@ -58,35 +58,36 @@ public function __construct(
5858
/**
5959
* Return an XML structure to represent this service option.
6060
*
61-
* @param int|\Pterodactyl\Models\ServiceOption $option
61+
* @param int $option
6262
* @return string
6363
*
6464
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
6565
*/
66-
public function handle($option): string
66+
public function handle(int $option): string
6767
{
68-
if (! $option instanceof ServiceOption) {
69-
$option = $this->repository->find($option);
70-
}
68+
$option = $this->repository->getWithCopyAttributes($option);
7169

7270
$struct = [
71+
'meta' => [
72+
'version' => 'PTDL_v1',
73+
],
7374
'exported_at' => $this->carbon->now()->toIso8601String(),
7475
'name' => $option->name,
7576
'author' => array_get(explode(':', $option->tag), 0),
7677
'tag' => $option->tag,
77-
'description' => $option->description,
78+
'description' => $this->writeCData($option->description),
7879
'image' => $option->docker_image,
7980
'config' => [
80-
'files' => $option->config_files,
81-
'startup' => $option->config_startup,
82-
'logs' => $option->config_logs,
83-
'stop' => $option->config_stop,
81+
'files' => $this->writeCData($option->inherit_config_files),
82+
'startup' => $this->writeCData($option->inherit_config_startup),
83+
'logs' => $this->writeCData($option->inherit_config_logs),
84+
'stop' => $option->inherit_config_stop,
8485
],
8586
'scripts' => [
8687
'installation' => [
87-
'script' => function (Writer $writer) use ($option) {
88-
return $writer->writeCData($option->copy_script_install);
89-
},
88+
'script' => $this->writeCData($option->copy_script_install),
89+
'container' => $option->copy_script_container,
90+
'entrypoint' => $option->copy_script_entry,
9091
],
9192
],
9293
];
@@ -115,4 +116,17 @@ protected function recursiveArrayKeyPrepend(array $array, $prepend = self::XML_O
115116

116117
return $parsed;
117118
}
119+
120+
/**
121+
* Return a closure to be used by the XML writer to generate a string wrapped in CDATA tags.
122+
*
123+
* @param string $value
124+
* @return \Closure
125+
*/
126+
protected function writeCData(string $value): Closure
127+
{
128+
return function (Writer $writer) use ($value) {
129+
return $writer->writeCData($value);
130+
};
131+
}
118132
}

0 commit comments

Comments
 (0)