Skip to content

Commit cd63d69

Browse files
Tofandelifox
authored andcommitted
Improve provider
1 parent 9eb77c7 commit cd63d69

File tree

9 files changed

+147
-100
lines changed

9 files changed

+147
-100
lines changed

config/twill.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
/*
2727
|--------------------------------------------------------------------------
28-
| Application strict url handeling
28+
| Application strict url handling
2929
|--------------------------------------------------------------------------
3030
|
3131
| Setting this value to true will enable strict domain handling.

phpunit-legacy.xml

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@
1717
</report>
1818
</coverage>
1919
<testsuites>
20-
<testsuite name="Browser">
21-
<directory>tests/Browser</directory>
22-
</testsuite>
2320
<testsuite name="Unit">
2421
<directory>tests/unit</directory>
2522
<directory>tests/integration</directory>
2623
</testsuite>
24+
<testsuite name="Browser">
25+
<directory>tests/Browser</directory>
26+
</testsuite>
2727
</testsuites>
2828
<logging/>
2929
<php>

phpunit.xml

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
</report>
88
</coverage>
99
<testsuites>
10-
<testsuite name="Browser">
11-
<directory>tests/Browser</directory>
12-
</testsuite>
1310
<testsuite name="Unit">
1411
<directory>tests/unit</directory>
1512
<directory>tests/integration</directory>
1613
</testsuite>
14+
<testsuite name="Browser">
15+
<directory>tests/Browser</directory>
16+
</testsuite>
1717
</testsuites>
1818
<logging/>
1919
<php>

src/Exceptions/Handler.php

+5-40
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,16 @@
22

33
namespace A17\Twill\Exceptions;
44

5+
use Illuminate\Contracts\Container\Container;
56
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
6-
use Illuminate\Support\Facades\Request;
7-
use Illuminate\Support\Str;
8-
use Illuminate\Validation\ValidationException;
9-
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
107

8+
/** @deprecated It is not needed anymore and will be removed in v4 */
119
class Handler extends ExceptionHandler
1210
{
13-
/**
14-
* Get the view used to render HTTP exceptions.
15-
*
16-
* @return string
17-
*/
18-
protected function getHttpExceptionView(HttpExceptionInterface $e)
11+
public function __construct(Container $container)
1912
{
20-
$usesAdminPath = !empty(config('twill.admin_app_path'));
21-
$adminAppUrl = config('twill.admin_app_url', config('app.url'));
13+
parent::__construct($container);
2214

23-
$isSubdomainAdmin = !$usesAdminPath && Str::contains(Request::url(), $adminAppUrl);
24-
$isSubdirectoryAdmin = $usesAdminPath && Str::startsWith(Request::path(), config('twill.admin_app_path'));
25-
26-
return $this->getTwillErrorView($e->getStatusCode(), !$isSubdomainAdmin && !$isSubdirectoryAdmin);
27-
}
28-
29-
/**
30-
* Get the Twill error view used to render a specified HTTP status code.
31-
*
32-
* @param integer $statusCode
33-
* @return string
34-
*/
35-
protected function getTwillErrorView($statusCode, $frontend = false)
36-
{
37-
if ($frontend) {
38-
$view = config('twill.frontend.views_path') . ".errors.$statusCode";
39-
40-
return view()->exists($view) ? $view : "errors::{$statusCode}";
41-
}
42-
43-
$view = "twill.errors.$statusCode";
44-
45-
return view()->exists($view) ? $view : "twill::errors.$statusCode";
46-
}
47-
48-
protected function invalidJson($request, ValidationException $exception)
49-
{
50-
return response()->json($exception->errors(), $exception->status);
15+
trigger_deprecation('area17/twill', '3.4', 'The Twill Exception handler is deprecated and will be removed in v4, go back to extending the laravel ExceptionHandler');
5116
}
5217
}

src/Http/Controllers/Admin/Controller.php

-3
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ class Controller extends BaseController
2020

2121
public function __construct()
2222
{
23-
if (Config::get('twill.bind_exception_handler', true)) {
24-
App::singleton(ExceptionHandler::class, TwillHandler::class);
25-
}
2623
}
2724

2825
/**

src/Http/Controllers/Front/Controller.php

-4
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@ class Controller extends BaseController
1919

2020
public function __construct()
2121
{
22-
if (Config::get('twill.bind_exception_handler', true)) {
23-
App::singleton(ExceptionHandler::class, TwillHandler::class);
24-
}
25-
2622
$this->seo = new Seo();
2723

2824
$this->seo->title = Config::get('twill.seo.site_title');

src/TwillRoutes.php

+10
Original file line numberDiff line numberDiff line change
@@ -402,4 +402,14 @@ public function getAuthRedirectPath(): string
402402
return config('twill.auth_login_redirect_path')
403403
?? rtrim(config('twill.admin_app_url') ?: '', '/') . '/' . ltrim(config('twill.admin_app_path') ?? 'admin', '/');
404404
}
405+
406+
public function isTwillRequest(): bool
407+
{
408+
$adminAppUrl = config('twill.admin_app_url', config('app.url'));
409+
410+
$matchesDomain = !config('twill.admin_app_strict') || Str::endsWith(\request()->getSchemeAndHttpHost(), $adminAppUrl);
411+
$matchesPath = empty(config('twill.admin_app_path')) || \request()->is(config('twill.admin_app_path', '') . '*');
412+
413+
return $matchesDomain && $matchesPath;
414+
}
405415
}

src/TwillServiceProvider.php

+86-46
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use A17\Twill\Commands\Update;
2929
use A17\Twill\Commands\UpdateExampleCommand;
3030
use A17\Twill\Commands\UpdateMorphMapReferences;
31+
use A17\Twill\Facades\TwillRoutes;
3132
use A17\Twill\Http\ViewComposers\CurrentUser;
3233
use A17\Twill\Http\ViewComposers\FilesUploaderConfig;
3334
use A17\Twill\Http\ViewComposers\Localization;
@@ -42,14 +43,20 @@
4243
use Astrotomic\Translatable\TranslatableServiceProvider;
4344
use Cartalyst\Tags\TagsServiceProvider;
4445
use Exception;
46+
use Illuminate\Contracts\Debug\ExceptionHandler;
47+
use Illuminate\Contracts\Foundation\CachesConfiguration;
4548
use Illuminate\Database\Eloquent\Relations\Relation;
4649
use Illuminate\Foundation\AliasLoader;
50+
use Illuminate\Foundation\Exceptions\Handler;
4751
use Illuminate\Support\Facades\Blade;
4852
use Illuminate\Support\Facades\View;
4953
use Illuminate\Support\ServiceProvider;
5054
use Illuminate\Support\Str;
55+
use Illuminate\Support\ViewErrorBag;
56+
use Illuminate\Validation\ValidationException;
5157
use PragmaRX\Google2FAQRCode\Google2FA as Google2FAQRCode;
5258
use Spatie\Activitylog\ActivitylogServiceProvider;
59+
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
5360

5461
class TwillServiceProvider extends ServiceProvider
5562
{
@@ -79,8 +86,6 @@ class TwillServiceProvider extends ServiceProvider
7986
*/
8087
public function boot(): void
8188
{
82-
$this->requireHelpers();
83-
8489
$this->publishConfigs();
8590
$this->publishMigrations();
8691
$this->publishAssets();
@@ -116,8 +121,13 @@ private function requireHelpers(): void
116121
*/
117122
public function register(): void
118123
{
119-
$this->mergeConfigs();
124+
$this->requireHelpers();
120125

126+
if (! ($this->app instanceof CachesConfiguration && $this->app->configurationIsCached())) {
127+
$this->mergeConfigs();
128+
}
129+
130+
$this->registerErrorHandlers();
121131
$this->registerProviders();
122132
$this->registerAliases();
123133
$this->registerFacades();
@@ -150,8 +160,6 @@ public function register(): void
150160
'blocks' => config('twill.models.block', Block::class),
151161
'groups' => config('twill.models.group', Group::class),
152162
]);
153-
154-
config(['twill.version' => $this->version()]);
155163
}
156164

157165
private function registerFacades(): void
@@ -214,47 +222,6 @@ private function registerAliases(): void
214222
*/
215223
private function publishConfigs(): void
216224
{
217-
if (config('twill.enabled.users-management')) {
218-
config([
219-
'auth.providers.twill_users' => [
220-
'driver' => 'eloquent',
221-
'model' => twillModel('user'),
222-
],
223-
]);
224-
225-
config([
226-
'auth.guards.twill_users' => [
227-
'driver' => 'session',
228-
'provider' => 'twill_users',
229-
],
230-
]);
231-
232-
if (blank(config('auth.passwords.twill_users'))) {
233-
config([
234-
'auth.passwords.twill_users' => [
235-
'provider' => 'twill_users',
236-
'table' => config('twill.password_resets_table', 'twill_password_resets'),
237-
'expire' => 60,
238-
'throttle' => 60,
239-
],
240-
]);
241-
}
242-
}
243-
244-
config(
245-
['activitylog.enabled' => config('twill.enabled.dashboard') ? true : config('twill.enabled.activitylog')]
246-
);
247-
config(['activitylog.subject_returns_soft_deleted_models' => true]);
248-
249-
config(
250-
[
251-
'analytics.service_account_credentials_json' => config(
252-
'twill.dashboard.analytics.service_account_credentials_json',
253-
storage_path('app/analytics/service-account-credentials.json')
254-
),
255-
]
256-
);
257-
258225
$this->publishes([__DIR__ . '/../config/twill-publish.php' => config_path('twill.php')], 'config');
259226
$this->publishes([__DIR__ . '/../config/translatable.php' => config_path('translatable.php')], 'config');
260227
}
@@ -299,6 +266,49 @@ private function mergeConfigs(): void
299266
}
300267

301268
$this->mergeConfigFrom(__DIR__ . '/../config/services.php', 'services');
269+
270+
if (config('twill.enabled.users-management')) {
271+
config([
272+
'auth.providers.twill_users' => [
273+
'driver' => 'eloquent',
274+
'model' => twillModel('user'),
275+
],
276+
]);
277+
278+
config([
279+
'auth.guards.twill_users' => [
280+
'driver' => 'session',
281+
'provider' => 'twill_users',
282+
],
283+
]);
284+
285+
if (blank(config('auth.passwords.twill_users'))) {
286+
config([
287+
'auth.passwords.twill_users' => [
288+
'provider' => 'twill_users',
289+
'table' => config('twill.password_resets_table', 'twill_password_resets'),
290+
'expire' => 60,
291+
'throttle' => 60,
292+
],
293+
]);
294+
}
295+
}
296+
297+
config(
298+
['activitylog.enabled' => config('twill.enabled.dashboard') ? true : config('twill.enabled.activitylog')]
299+
);
300+
config(['activitylog.subject_returns_soft_deleted_models' => true]);
301+
302+
config(
303+
[
304+
'analytics.service_account_credentials_json' => config(
305+
'twill.dashboard.analytics.service_account_credentials_json',
306+
storage_path('app/analytics/service-account-credentials.json')
307+
),
308+
]
309+
);
310+
311+
config(['twill.version' => $this->version()]);
302312
}
303313

304314
private function setLocalDiskUrl($type): void
@@ -625,4 +635,34 @@ public function check2FA(): void
625635
);
626636
}
627637
}
638+
639+
private function registerErrorHandlers(): void
640+
{
641+
$handler = app(ExceptionHandler::class);
642+
if ($handler instanceof Handler) {
643+
$handler->renderable(function (HttpExceptionInterface $e) {
644+
$statusCode = $e->getStatusCode();
645+
if (TwillRoutes::isTwillRequest()) {
646+
$view = "twill.errors.$statusCode";
647+
648+
$view = view()->exists($view) ? $view : "twill::errors.$statusCode";
649+
} else {
650+
$view = config('twill.frontend.views_path') . ".errors.$statusCode";
651+
652+
$view = view()->exists($view) ? $view : null;
653+
}
654+
return $view ? response()->view($view, [
655+
'errors' => new ViewErrorBag(),
656+
'exception' => $e,
657+
], $e->getStatusCode(), $e->getHeaders()) : null;
658+
});
659+
660+
$handler->renderable(function (ValidationException $exception) {
661+
if (TwillRoutes::isTwillRequest() && request()->expectsJson()) {
662+
return response()->json($exception->errors(), $exception->status);
663+
}
664+
return null;
665+
});
666+
}
667+
}
628668
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace A17\Twill\Tests\Integration\Exceptions;
4+
5+
use A17\Twill\Tests\Integration\TestCase;
6+
use Illuminate\Http\Request;
7+
use Illuminate\Support\Facades\Route;
8+
use Illuminate\View\View;
9+
10+
class ExceptionHandlerTest extends TestCase
11+
{
12+
public function test404InAdmin()
13+
{
14+
$res = $this->get('/twill/foobar');
15+
$res->assertStatus(404);
16+
$this->assertEquals($res->original->name(), "twill::errors.404");
17+
}
18+
19+
public function test404InFrontend()
20+
{
21+
$res = $this->get('/foobar');
22+
$res->assertStatus(404);
23+
$this->assertTrue(is_string($res->original));
24+
}
25+
26+
public function testValidationException()
27+
{
28+
Route::post('/twill/validation-exception', function (Request $request) {
29+
$request->validate([
30+
'dummy' => 'required',
31+
]);
32+
});
33+
34+
$res = $this->postJson('/twill/validation-exception');
35+
$res->assertStatus(422);
36+
// Response is directly an array of exceptions and doesn't have a response key
37+
$res->assertJsonValidationErrors('dummy', null);
38+
}
39+
}

0 commit comments

Comments
 (0)