Completed
Push — develop ( db1c13...df7e27 )
by Abdelrahman
05:50
created

FortServiceProvider::overrideExceptionHandler()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Rinvex\Fort\Providers;
6
7
use Illuminate\Routing\Router;
8
use Rinvex\Fort\Guards\SessionGuard;
9
use Rinvex\Fort\Services\AccessGate;
10
use Illuminate\Support\ServiceProvider;
11
use Rinvex\Fort\Contracts\RoleContract;
12
use Rinvex\Fort\Contracts\UserContract;
13
use Rinvex\Fort\Handlers\GenericHandler;
14
use Illuminate\Support\Facades\Validator;
15
use Rinvex\Fort\Contracts\AbilityContract;
16
use Rinvex\Fort\Contracts\SessionContract;
17
use Rinvex\Fort\Http\Middleware\Abilities;
18
use Illuminate\View\Compilers\BladeCompiler;
19
use Rinvex\Fort\Contracts\SocialiteContract;
20
use Rinvex\Fort\Http\Middleware\NoHttpCache;
21
use Rinvex\Fort\Console\Commands\SeedCommand;
22
use Rinvex\Fort\Http\Middleware\Authenticate;
23
use Rinvex\Fort\Console\Commands\MigrateCommand;
24
use Rinvex\Fort\Console\Commands\PublishCommand;
25
use Rinvex\Fort\Console\Commands\RollbackCommand;
26
use Rinvex\Fort\Http\Middleware\UpdateLastActivity;
27
use Rinvex\Fort\Http\Middleware\RedirectIfAuthenticated;
28
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
29
30
class FortServiceProvider extends ServiceProvider
31
{
32
    /**
33
     * The commands to be registered.
34
     *
35
     * @var array
36
     */
37
    protected $commands = [
38
        SeedCommand::class => 'command.rinvex.fort.seed',
39
        MigrateCommand::class => 'command.rinvex.fort.migrate',
40
        PublishCommand::class => 'command.rinvex.fort.publish',
41
        RollbackCommand::class => 'command.rinvex.fort.rollback',
42
    ];
43
44
    /**
45
     * {@inheritdoc}
46
     */
47
    public function register()
48
    {
49
        // Register bindings
50
        $this->registerPasswordBroker();
51
        $this->registerVerificationBroker();
52
53
        // Register console commands
54
        ! $this->app->runningInConsole() || $this->registerCommands();
55
56
        // Merge config
57
        $this->mergeConfigFrom(realpath(__DIR__.'/../../config/config.php'), 'rinvex.fort');
58
59
        // Register Access Gate Binding
60
        $this->registerAccessGate();
61
62
        // Bind eloquent models to IoC container
63
        $this->app->singleton('rinvex.fort.role', function ($app) {
64
            return new $app['config']['rinvex.fort.models.role']();
65
        });
66
        $this->app->alias('rinvex.fort.role', RoleContract::class);
67
68
        $this->app->singleton('rinvex.fort.ability', function ($app) {
69
            return new $app['config']['rinvex.fort.models.ability']();
70
        });
71
        $this->app->alias('rinvex.fort.ability', AbilityContract::class);
72
73
        $this->app->singleton('rinvex.fort.session', function ($app) {
74
            return new $app['config']['rinvex.fort.models.session']();
75
        });
76
        $this->app->alias('rinvex.fort.session', SessionContract::class);
77
78
        $this->app->singleton('rinvex.fort.socialite', function ($app) {
79
            return new $app['config']['rinvex.fort.models.socialite']();
80
        });
81
        $this->app->alias('rinvex.fort.socialite', SocialiteContract::class);
82
83
        $this->app->singleton('rinvex.fort.user', function ($app) {
84
            return new $app['config']['auth.providers.'.$app['config']['auth.guards.'.$app['config']['auth.defaults.guard'].'.provider'].'.model']();
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 149 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
85
        });
86
        $this->app->alias('rinvex.fort.user', UserContract::class);
87
    }
88
89
    /**
90
     * Register the access gate service.
91
     *
92
     * @return void
93
     */
94
    protected function registerAccessGate()
95
    {
96
        $this->app->singleton(GateContract::class, function ($app) {
97
            return new AccessGate($app, function () use ($app) {
98
                return call_user_func($app['auth']->userResolver());
99
            });
100
        });
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     */
106
    public function boot(Router $router)
107
    {
108
        // Add country validation rule
109
        Validator::extend('country', function ($attribute, $value) {
110
            return in_array($value, array_keys(countries()));
111
        }, 'Country MUST be valid!');
112
113
        // Add langauge validation rule
114
        Validator::extend('language', function ($attribute, $value) {
115
            return in_array($value, array_keys(languages()));
116
        }, 'Language MUST be valid!');
117
118
        if (config('rinvex.fort.boot.override_middleware')) {
119
            // Override middlware
120
            $this->overrideMiddleware($router);
121
        }
122
123
        // Publish resources
124
        ! $this->app->runningInConsole() || $this->publishResources();
125
126
        // Override session guard
127
        $this->overrideSessionGuard();
128
129
        // Register event handlers
130
        $this->app['events']->subscribe(GenericHandler::class);
131
132
        // Share current user instance with all views
133
        $this->app['view']->composer('*', function ($view) {
134
            $view->with('currentUser', auth()->user());
0 ignored issues
show
Bug introduced by
The method user does only exist in Illuminate\Contracts\Auth\Guard, but not in Illuminate\Contracts\Auth\Factory.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
135
        });
136
137
        // Register blade extensions
138
        $this->registerBladeExtensions();
139
    }
140
141
    /**
142
     * Publish resources.
143
     *
144
     * @return void
145
     */
146
    protected function publishResources()
147
    {
148
        $this->publishes([realpath(__DIR__.'/../../config/config.php') => config_path('rinvex.fort.php')], 'rinvex-fort-config');
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 129 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
149
        $this->publishes([realpath(__DIR__.'/../../database/migrations') => database_path('migrations')], 'rinvex-fort-migrations');
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 132 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
150
    }
151
152
    /**
153
     * Override session guard.
154
     *
155
     * @return void
156
     */
157
    protected function overrideSessionGuard()
158
    {
159
        // Add custom session guard
160
        $this->app['auth']->extend('session', function ($app, $name, array $config) {
161
            $provider = $app['auth']->createUserProvider($config['provider']);
162
163
            $guard = new SessionGuard($name, $provider, $app['session.store'], $app['request']);
164
165
            // When using the remember me functionality of the authentication services we
166
            // will need to be set the encryption instance of the guard, which allows
167
            // secure, encrypted cookie values to get generated for those cookies.
168
            if (method_exists($guard, 'setCookieJar')) {
169
                $guard->setCookieJar($this->app['cookie']);
170
            }
171
172
            if (method_exists($guard, 'setDispatcher')) {
173
                $guard->setDispatcher($this->app['events']);
174
            }
175
176
            if (method_exists($guard, 'setRequest')) {
177
                $guard->setRequest($this->app->refresh('request', $guard, 'setRequest'));
178
            }
179
180
            return $guard;
181
        });
182
    }
183
184
    /**
185
     * Override middleware.
186
     *
187
     * @param \Illuminate\Routing\Router $router
188
     *
189
     * @return void
190
     */
191
    protected function overrideMiddleware(Router $router)
192
    {
193
        // Append middleware to the 'web' middlware group
194
        $router->pushMiddlewareToGroup('web', Abilities::class);
195
        $router->pushMiddlewareToGroup('web', UpdateLastActivity::class);
196
197
        // Override route middleware on the fly
198
        $router->aliasMiddleware('auth', Authenticate::class);
199
        $router->aliasMiddleware('nohttpcache', NoHttpCache::class);
200
        $router->aliasMiddleware('guest', RedirectIfAuthenticated::class);
201
    }
202
203
    /**
204
     * Register the password broker.
205
     *
206
     * @return void
207
     */
208
    protected function registerPasswordBroker()
209
    {
210
        $this->app->singleton('auth.password', function ($app) {
211
            return new PasswordResetBrokerManager($app);
212
        });
213
214
        $this->app->bind('auth.password.broker', function ($app) {
215
            return $app->make('auth.password')->broker();
216
        });
217
    }
218
219
    /**
220
     * Register the verification broker.
221
     *
222
     * @return void
223
     */
224
    protected function registerVerificationBroker()
225
    {
226
        $this->app->singleton('rinvex.fort.emailverification', function ($app) {
227
            return new EmailVerificationBrokerManager($app);
228
        });
229
230
        $this->app->bind('rinvex.fort.emailverification.broker', function ($app) {
231
            return $app->make('rinvex.fort.emailverification')->broker();
232
        });
233
    }
234
235
    /**
236
     * Register the blade extensions.
237
     *
238
     * @return void
239
     */
240
    protected function registerBladeExtensions()
241
    {
242
        $this->app->afterResolving('blade.compiler', function (BladeCompiler $bladeCompiler) {
243
244
            // @role('writer') / @hasrole(['writer', 'editor'])
245
            $bladeCompiler->directive('role', function ($expression) {
246
                return "<?php if(auth()->user()->hasRole({$expression})): ?>";
247
            });
248
            $bladeCompiler->directive('endrole', function () {
249
                return '<?php endif; ?>';
250
            });
251
252
            // @hasrole('writer') / @hasrole(['writer', 'editor'])
253
            $bladeCompiler->directive('hasrole', function ($expression) {
254
                return "<?php if(auth()->user()->hasRole({$expression})): ?>";
255
            });
256
            $bladeCompiler->directive('endhasrole', function () {
257
                return '<?php endif; ?>';
258
            });
259
260
            // @hasanyrole(['writer', 'editor'])
261
            $bladeCompiler->directive('hasanyrole', function ($expression) {
262
                return "<?php if(auth()->user()->hasAnyRole({$expression})): ?>";
263
            });
264
            $bladeCompiler->directive('endhasanyrole', function () {
265
                return '<?php endif; ?>';
266
            });
267
268
            // @hasallroles(['writer', 'editor'])
269
            $bladeCompiler->directive('hasallroles', function ($expression) {
270
                return "<?php if(auth()->user()->hasAllRoles({$expression})): ?>";
271
            });
272
            $bladeCompiler->directive('endhasallroles', function () {
273
                return '<?php endif; ?>';
274
            });
275
        });
276
    }
277
278
    /**
279
     * Register console commands.
280
     *
281
     * @return void
282
     */
283
    protected function registerCommands()
284
    {
285
        // Register artisan commands
286
        foreach ($this->commands as $key => $value) {
287
            $this->app->singleton($value, function ($app) use ($key) {
0 ignored issues
show
Unused Code introduced by
The parameter $app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
288
                return new $key();
289
            });
290
        }
291
292
        $this->commands(array_values($this->commands));
293
    }
294
}
295