Skip to content

Commit 90bbe57

Browse files
committed
Move services onto new services system, includes tests
1 parent e91079d commit 90bbe57

26 files changed

+899
-272
lines changed

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ services:
1212
before_install:
1313
- mysql -e 'CREATE DATABASE IF NOT EXISTS travis;'
1414
before_script:
15-
# - phpenv config-rm xdebug.ini
1615
- cp .env.travis .env
1716
- composer install --no-interaction --prefer-dist --no-suggest --verbose
1817
- php artisan migrate --seed -v

app/Contracts/Repository/ServiceRepositoryInterface.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,12 @@ interface ServiceRepositoryInterface extends RepositoryInterface
3333
* @return \Illuminate\Support\Collection
3434
*/
3535
public function getWithOptions($id = null);
36+
37+
/**
38+
* Return a service along with its associated options and the servers relation on those options.
39+
*
40+
* @param int $id
41+
* @return mixed
42+
*/
43+
public function getWithOptionServers($id);
3644
}

app/Exceptions/Services/ServiceOption/HasActiveServersException.php renamed to app/Exceptions/Services/HasActiveServersException.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* SOFTWARE.
2323
*/
2424

25-
namespace Pterodactyl\Exceptions\Services\ServiceOption;
25+
namespace Pterodactyl\Exceptions\Services;
2626

2727
class HasActiveServersException extends \Exception
2828
{

app/Http/Controllers/Admin/OptionController.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
use Pterodactyl\Services\Services\Options\InstallScriptUpdateService;
3939
use Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface;
4040
use Pterodactyl\Exceptions\Services\ServiceOption\InvalidCopyFromException;
41-
use Pterodactyl\Exceptions\Services\ServiceOption\HasActiveServersException;
41+
use Pterodactyl\Exceptions\Services\HasActiveServersException;
4242
use Pterodactyl\Exceptions\Services\ServiceOption\NoParentConfigurationFoundException;
4343

4444
class OptionController extends Controller
@@ -145,14 +145,14 @@ public function store(ServiceOptionFormRequest $request)
145145
/**
146146
* Delete a given option from the database.
147147
*
148-
* @param \Pterodactyl\Models\ServiceOption $option
148+
* @param \Pterodactyl\Models\ServiceOption $option
149149
* @return \Illuminate\Http\RedirectResponse
150150
*/
151-
public function delete(ServiceOption $option)
151+
public function destroy(ServiceOption $option)
152152
{
153153
try {
154154
$this->optionDeletionService->handle($option->id);
155-
$this->alert->success()->flash();
155+
$this->alert->success(trans('admin/services.options.notices.option_deleted'))->flash();
156156
} catch (HasActiveServersException $exception) {
157157
$this->alert->danger($exception->getMessage())->flash();
158158

@@ -229,6 +229,7 @@ public function editConfiguration(Request $request, ServiceOption $option)
229229
* @return \Illuminate\Http\RedirectResponse
230230
*
231231
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
232+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
232233
*/
233234
public function updateScripts(EditOptionScript $request, ServiceOption $option)
234235
{

app/Http/Controllers/Admin/ServiceController.php

Lines changed: 108 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -24,129 +24,173 @@
2424

2525
namespace Pterodactyl\Http\Controllers\Admin;
2626

27-
use Log;
28-
use Alert;
29-
use Pterodactyl\Models;
30-
use Illuminate\Http\Request;
31-
use Pterodactyl\Exceptions\DisplayException;
27+
use Pterodactyl\Models\Service;
28+
use Prologue\Alerts\AlertsMessageBag;
3229
use Pterodactyl\Http\Controllers\Controller;
33-
use Pterodactyl\Repositories\ServiceRepository;
34-
use Pterodactyl\Exceptions\DisplayValidationException;
30+
use Pterodactyl\Services\Services\ServiceUpdateService;
31+
use Pterodactyl\Services\Services\ServiceCreationService;
32+
use Pterodactyl\Services\Services\ServiceDeletionService;
33+
use Pterodactyl\Exceptions\Services\HasActiveServersException;
34+
use Pterodactyl\Http\Requests\Admin\Service\ServiceFormRequest;
35+
use Pterodactyl\Contracts\Repository\ServiceRepositoryInterface;
36+
use Pterodactyl\Http\Requests\Admin\Service\ServiceFunctionsFormRequest;
3537

3638
class ServiceController extends Controller
3739
{
40+
/**
41+
* @var \Prologue\Alerts\AlertsMessageBag
42+
*/
43+
protected $alert;
44+
45+
/**
46+
* @var \Pterodactyl\Services\Services\ServiceCreationService
47+
*/
48+
protected $creationService;
49+
50+
/**
51+
* @var \Pterodactyl\Services\Services\ServiceDeletionService
52+
*/
53+
protected $deletionService;
54+
55+
/**
56+
* @var \Pterodactyl\Contracts\Repository\ServiceRepositoryInterface
57+
*/
58+
protected $repository;
59+
60+
/**
61+
* @var \Pterodactyl\Services\Services\ServiceUpdateService
62+
*/
63+
protected $updateService;
64+
65+
public function __construct(
66+
AlertsMessageBag $alert,
67+
ServiceCreationService $creationService,
68+
ServiceDeletionService $deletionService,
69+
ServiceRepositoryInterface $repository,
70+
ServiceUpdateService $updateService
71+
) {
72+
$this->alert = $alert;
73+
$this->creationService = $creationService;
74+
$this->deletionService = $deletionService;
75+
$this->repository = $repository;
76+
$this->updateService = $updateService;
77+
}
78+
3879
/**
3980
* Display service overview page.
4081
*
41-
* @param \Illuminate\Http\Request $request
4282
* @return \Illuminate\View\View
4383
*/
44-
public function index(Request $request)
84+
public function index()
4585
{
4686
return view('admin.services.index', [
47-
'services' => Models\Service::withCount('servers', 'options', 'packs')->get(),
87+
'services' => $this->repository->getWithOptions(),
4888
]);
4989
}
5090

5191
/**
5292
* Display create service page.
5393
*
54-
* @param \Illuminate\Http\Request $request
5594
* @return \Illuminate\View\View
5695
*/
57-
public function create(Request $request)
96+
public function create()
5897
{
5998
return view('admin.services.new');
6099
}
61100

62101
/**
63102
* Return base view for a service.
64103
*
65-
* @param \Illuminate\Http\Request $request
66-
* @param int $id
104+
* @param int $service
67105
* @return \Illuminate\View\View
68106
*/
69-
public function view(Request $request, $id)
107+
public function view($service)
70108
{
71109
return view('admin.services.view', [
72-
'service' => Models\Service::with('options', 'options.servers')->findOrFail($id),
110+
'service' => $this->repository->getWithOptionServers($service),
73111
]);
74112
}
75113

76114
/**
77115
* Return function editing view for a service.
78116
*
79-
* @param \Illuminate\Http\Request $request
80-
* @param int $id
117+
* @param \Pterodactyl\Models\Service $service
81118
* @return \Illuminate\View\View
82119
*/
83-
public function viewFunctions(Request $request, $id)
120+
public function viewFunctions(Service $service)
84121
{
85-
return view('admin.services.functions', ['service' => Models\Service::findOrFail($id)]);
122+
return view('admin.services.functions', ['service' => $service]);
86123
}
87124

88125
/**
89126
* Handle post action for new service.
90127
*
91-
* @param \Illuminate\Http\Request $request
128+
* @param \Pterodactyl\Http\Requests\Admin\Service\ServiceFormRequest $request
92129
* @return \Illuminate\Http\RedirectResponse
130+
*
131+
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
93132
*/
94-
public function store(Request $request)
133+
public function store(ServiceFormRequest $request)
95134
{
96-
$repo = new ServiceRepository;
135+
$service = $this->creationService->handle($request->normalize());
136+
$this->alert->success(trans('admin/services.notices.service_created', ['name' => $service->name]))->flash();
97137

98-
try {
99-
$service = $repo->create($request->intersect([
100-
'name', 'description', 'folder', 'startup',
101-
]));
102-
Alert::success('Successfully created new service!')->flash();
103-
104-
return redirect()->route('admin.services.view', $service->id);
105-
} catch (DisplayValidationException $ex) {
106-
return redirect()->route('admin.services.new')->withErrors(json_decode($ex->getMessage()))->withInput();
107-
} catch (DisplayException $ex) {
108-
Alert::danger($ex->getMessage())->flash();
109-
} catch (\Exception $ex) {
110-
Log::error($ex);
111-
Alert::danger('An error occured while attempting to add a new service. This error has been logged.')->flash();
112-
}
113-
114-
return redirect()->route('admin.services.new')->withInput();
138+
return redirect()->route('admin.services.view', $service->id);
115139
}
116140

117141
/**
118142
* Edits configuration for a specific service.
119143
*
120-
* @param \Illuminate\Http\Request $request
121-
* @param int $id
144+
* @param \Pterodactyl\Http\Requests\Admin\Service\ServiceFormRequest $request
145+
* @param \Pterodactyl\Models\Service $service
122146
* @return \Illuminate\Http\RedirectResponse
147+
*
148+
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
149+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
123150
*/
124-
public function edit(Request $request, $id)
151+
public function update(ServiceFormRequest $request, Service $service)
125152
{
126-
$repo = new ServiceRepository;
127-
$redirectTo = ($request->input('redirect_to')) ? 'admin.services.view.functions' : 'admin.services.view';
153+
$this->updateService->handle($service->id, $request->normalize());
154+
$this->alert->success(trans('admin/services.notices.service_updated'))->flash();
128155

156+
return redirect()->route('admin.services.view', $service);
157+
}
158+
159+
/**
160+
* Update the functions file for a service.
161+
*
162+
* @param \Pterodactyl\Http\Requests\Admin\Service\ServiceFunctionsFormRequest $request
163+
* @param \Pterodactyl\Models\Service $service
164+
* @return \Illuminate\Http\RedirectResponse
165+
*
166+
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
167+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
168+
*/
169+
public function updateFunctions(ServiceFunctionsFormRequest $request, Service $service)
170+
{
171+
$this->updateService->handle($service->id, $request->normalize());
172+
$this->alert->success(trans('admin/services.notices.functions_updated'))->flash();
173+
174+
return redirect()->route('admin.services.view.functions', $service->id);
175+
}
176+
177+
/**
178+
* Delete a service from the panel.
179+
*
180+
* @param \Pterodactyl\Models\Service $service
181+
* @return \Illuminate\Http\RedirectResponse
182+
*/
183+
public function destroy(Service $service)
184+
{
129185
try {
130-
if ($request->input('action') !== 'delete') {
131-
$repo->update($id, $request->intersect([
132-
'name', 'description', 'folder', 'startup', 'index_file',
133-
]));
134-
Alert::success('Service has been updated successfully.')->flash();
135-
} else {
136-
$repo->delete($id);
137-
Alert::success('Successfully deleted service from the system.')->flash();
138-
139-
return redirect()->route('admin.services');
140-
}
141-
} catch (DisplayValidationException $ex) {
142-
return redirect()->route($redirectTo, $id)->withErrors(json_decode($ex->getMessage()))->withInput();
143-
} catch (DisplayException $ex) {
144-
Alert::danger($ex->getMessage())->flash();
145-
} catch (\Exception $ex) {
146-
Log::error($ex);
147-
Alert::danger('An error occurred while attempting to update this service. This error has been logged.')->flash();
186+
$this->deletionService->handle($service->id);
187+
$this->alert->success(trans('admin/services.notices.service_deleted'))->flash();
188+
} catch (HasActiveServersException $exception) {
189+
$this->alert->danger($exception->getMessage())->flash();
190+
191+
return redirect()->back();
148192
}
149193

150-
return redirect()->route($redirectTo, $id);
194+
return redirect()->route('admin.services');
151195
}
152196
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
/*
3+
* Pterodactyl - Panel
4+
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
namespace Pterodactyl\Http\Requests\Admin\Service;
26+
27+
use Pterodactyl\Http\Requests\Admin\AdminFormRequest;
28+
29+
class ServiceFormRequest extends AdminFormRequest
30+
{
31+
/**
32+
* @return array
33+
*/
34+
public function rules()
35+
{
36+
$rules = [
37+
'name' => 'required|string|min:1|max:255',
38+
'description' => 'required|nullable|string',
39+
'folder' => 'required|regex:/^[\w.-]{1,50}$/|unique:services,folder',
40+
'startup' => 'required|nullable|string',
41+
];
42+
43+
if ($this->method() === 'PATCH') {
44+
$service = $this->route()->parameter('service');
45+
$rules['folder'] = $rules['folder'] . ',' . $service->id;
46+
47+
return $rules;
48+
}
49+
50+
return $rules;
51+
}
52+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
/*
3+
* Pterodactyl - Panel
4+
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
namespace Pterodactyl\Http\Requests\Admin\Service;
26+
27+
use Pterodactyl\Http\Requests\Admin\AdminFormRequest;
28+
29+
class ServiceFunctionsFormRequest extends AdminFormRequest
30+
{
31+
/**
32+
* @return array
33+
*/
34+
public function rules()
35+
{
36+
return [
37+
'index_file' => 'required|nullable|string',
38+
];
39+
}
40+
}

0 commit comments

Comments
 (0)