Completed
Push — master ( bab9dc...2e4827 )
by Abdelrahman
10:15 queued 08:43
created

FoundationServiceProvider::bindBladeCompiler()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 14
rs 9.7998
cc 2
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cortex\Foundation\Providers;
6
7
use Illuminate\Routing\Router;
8
use Illuminate\Support\Collection;
9
use Illuminate\Support\Facades\Schema;
10
use Illuminate\Support\ServiceProvider;
11
use Rinvex\Support\Traits\ConsoleTools;
12
use Illuminate\Database\Schema\Blueprint;
13
use Cortex\Foundation\Models\ImportRecord;
14
use Cortex\Foundation\Models\AbstractModel;
15
use Illuminate\View\Compilers\BladeCompiler;
16
use Cortex\Foundation\Generators\LangJsGenerator;
17
use Cortex\Foundation\Console\Commands\SeedCommand;
18
use Illuminate\Database\Eloquent\Relations\Relation;
19
use Cortex\Foundation\Console\Commands\InstallCommand;
20
use Cortex\Foundation\Console\Commands\MigrateCommand;
21
use Cortex\Foundation\Console\Commands\PublishCommand;
22
use Cortex\Foundation\Console\Commands\CoreSeedCommand;
23
use Cortex\Foundation\Console\Commands\RollbackCommand;
24
use Illuminate\Support\Facades\Session as SessionFacade;
25
use Cortex\Foundation\Verifiers\EloquentPresenceVerifier;
26
use Cortex\Foundation\Console\Commands\CoreInstallCommand;
27
use Cortex\Foundation\Console\Commands\CoreMigrateCommand;
28
use Cortex\Foundation\Console\Commands\CorePublishCommand;
29
use Cortex\Foundation\Console\Commands\CoreRollbackCommand;
30
use Cortex\Foundation\Http\Middleware\NotificationMiddleware;
31
use Cortex\Foundation\Overrides\Illuminate\Routing\Redirector;
32
use Cortex\Foundation\Overrides\Illuminate\Routing\UrlGenerator;
33
use Cortex\Foundation\Overrides\Mcamara\LaravelLocalization\LaravelLocalization;
34
use Cortex\Foundation\Overrides\Mariuzzo\LaravelJsLocalization\Commands\LangJsCommand;
35
36
class FoundationServiceProvider extends ServiceProvider
37
{
38
    use ConsoleTools;
39
40
    /**
41
     * The commands to be registered.
42
     *
43
     * @var array
44
     */
45
    protected $commands = [
46
        SeedCommand::class => 'command.cortex.foundation.seed',
47
        InstallCommand::class => 'command.cortex.foundation.install',
48
        MigrateCommand::class => 'command.cortex.foundation.migrate',
49
        PublishCommand::class => 'command.cortex.foundation.publish',
50
        RollbackCommand::class => 'command.cortex.foundation.rollback',
51
        CoreSeedCommand::class => 'command.cortex.foundation.coreseed',
52
        CoreInstallCommand::class => 'command.cortex.foundation.coreinstall',
53
        CoreMigrateCommand::class => 'command.cortex.foundation.coremigrate',
54
        CorePublishCommand::class => 'command.cortex.foundation.corempublish',
55
        CoreRollbackCommand::class => 'command.cortex.foundation.corerollback',
56
    ];
57
58
    /**
59
     * Register any application services.
60
     *
61
     * This service provider is a great spot to register your various container
62
     * bindings with the application. As you can see, we are registering our
63
     * "Registrar" implementation here. You can add your own bindings too!
64
     *
65
     * @return void
66
     */
67
    public function register(): void
68
    {
69
        $this->overrideNotificationMiddleware();
70
        $this->overrideLaravelLocalization();
71
        $this->overrideUrlGenerator();
72
        $this->bindPresenceVerifier();
73
        $this->bindBlueprintMacro();
74
        $this->overrideRedirector();
75
        $this->bindBladeCompiler();
76
        $this->overrideLangJS();
77
78
        // Bind eloquent models to IoC container
79
        $this->app->singleton('cortex.foundation.import_record', $importerModel = $this->app['config']['cortex.foundation.models.import_record']);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 146 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...
80
        $importerModel === ImportRecord::class || $this->app->alias('cortex.foundation.import_record', ImportRecord::class);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 124 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...
81
82
        // Merge config
83
        $this->mergeConfigFrom(realpath(__DIR__.'/../../config/config.php'), 'cortex.foundation');
84
85
        // Override datatables html builder
86
        $this->app->bind(\Yajra\DataTables\Html\Builder::class, \Cortex\Foundation\Overrides\Yajra\DataTables\Html\Builder::class);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 131 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...
87
88
        // Register console commands
89
        ! $this->app->runningInConsole() || $this->registerCommands();
90
    }
91
92
    /**
93
     * Bootstrap any application services.
94
     *
95
     * @return void
96
     */
97
    public function boot(Router $router): void
98
    {
99
        // Fix the specified key was too long error
100
        Schema::defaultStringLength(191);
101
102
        // Override presence verifier
103
        $this->app['validator']->setPresenceVerifier($this->app['cortex.foundation.presence.verifier']);
104
105
        // Early set application locale globaly
106
        $router->pattern('locale', '[a-z]{2}');
107
        $this->app['laravellocalization']->setLocale();
108
109
        $router->model('media', config('medialibrary.media_model'));
110
111
        // Map relations
112
        Relation::morphMap([
113
            'media' => config('medialibrary.media_model'),
114
        ]);
115
116
        // Load resources
117
        require __DIR__.'/../../routes/breadcrumbs/frontarea.php';
118
        require __DIR__.'/../../routes/breadcrumbs/tenantarea.php';
119
        $this->loadRoutesFrom(__DIR__.'/../../routes/web/adminarea.php');
120
        $this->loadRoutesFrom(__DIR__.'/../../routes/web/frontarea.php');
121
        $this->loadRoutesFrom(__DIR__.'/../../routes/web/tenantarea.php');
122
        $this->loadRoutesFrom(__DIR__.'/../../routes/web/managerarea.php');
123
        $this->loadViewsFrom(__DIR__.'/../../resources/views', 'cortex/foundation');
124
        $this->loadTranslationsFrom(__DIR__.'/../../resources/lang', 'cortex/foundation');
125
        $this->app->runningInConsole() || $this->app->afterResolving('blade.compiler', function () {
126
            require __DIR__.'/../../routes/menus/managerarea.php';
127
            require __DIR__.'/../../routes/menus/tenantarea.php';
128
            require __DIR__.'/../../routes/menus/adminarea.php';
129
            require __DIR__.'/../../routes/menus/frontarea.php';
130
        });
131
132
        // Publish Resources
133
        ! $this->app->runningInConsole() || $this->publishesLang('cortex/foundation');
134
        ! $this->app->runningInConsole() || $this->publishesViews('cortex/foundation');
135
        ! $this->app->runningInConsole() || $this->publishesConfig('cortex/foundation');
136
        ! $this->app->runningInConsole() || $this->publishesMigrations('cortex/foundation');
137
138
        SessionFacade::extend('database', function ($app) {
139
            $table = $app['config']['session.table'];
140
141
            $lifetime = $app['config']['session.lifetime'];
142
            $connection = $app['config']['session.connection'];
143
144
            return new \Cortex\Foundation\Overrides\Illuminate\Session\DatabaseSessionHandler(
145
                $app['db']->connection($connection), $table, $lifetime, $app
146
            );
147
        });
148
149
        $this->app->booted(function () {
150
            if ($this->app->routesAreCached()) {
151
                require $this->app->getCachedRoutesPath();
152
            } else {
153
                $this->app['router']->getRoutes()->refreshNameLookups();
154
                $this->app['router']->getRoutes()->refreshActionLookups();
155
            }
156
        });
157
158
        Collection::macro('similar', function (Collection $newCollection) {
159
            return $newCollection->diff($this)->isEmpty() && $this->diff($newCollection)->isEmpty();
160
        });
161
    }
162
163
    /**
164
     * Override notification middleware.
165
     *
166
     * @return void
167
     */
168
    protected function overrideNotificationMiddleware(): void
169
    {
170
        $this->app->singleton('Cortex\Foundation\Http\Middleware\NotificationMiddleware', function ($app) {
171
            return new NotificationMiddleware(
172
                $app['session.store'],
173
                $app['notification'],
174
                $app['config']->get('notification.session_key')
175
            );
176
        });
177
    }
178
179
    /**
180
     * Bind blade compiler.
181
     *
182
     * @return void
183
     */
184
    protected function bindBladeCompiler(): void
185
    {
186
        $this->app->afterResolving('blade.compiler', function (BladeCompiler $bladeCompiler) {
187
188
            // @alerts('container')
189
            $bladeCompiler->directive('alerts', function ($container = null) {
190
                if (strcasecmp('()', $container) === 0) {
191
                    $container = null;
192
                }
193
194
                return "<?php echo app('notification')->container({$container})->show(); ?>";
195
            });
196
        });
197
    }
198
199
    /**
200
     * Override the Redirector instance.
201
     *
202
     * @return void
203
     */
204
    protected function overrideRedirector(): void
205
    {
206
        $this->app->singleton('redirect', function ($app) {
207
            $redirector = new Redirector($app['url']);
208
209
            // If the session is set on the application instance, we'll inject it into
210
            // the redirector instance. This allows the redirect responses to allow
211
            // for the quite convenient "with" methods that flash to the session.
212
            if (isset($app['session.store'])) {
213
                $redirector->setSession($app['session.store']);
214
            }
215
216
            return $redirector;
217
        });
218
    }
219
220
    /**
221
     * Override the UrlGenerator instance.
222
     *
223
     * @return void
224
     */
225
    protected function overrideUrlGenerator(): void
226
    {
227
        $this->app->singleton('url', function ($app) {
228
            $routes = $app['router']->getRoutes();
229
230
            // The URL generator needs the route collection that exists on the router.
231
            // Keep in mind this is an object, so we're passing by references here
232
            // and all the registered routes will be available to the generator.
233
            $app->instance('routes', $routes);
234
235
            $url = new UrlGenerator(
236
                $routes, $app->rebinding(
237
                    'request', $this->requestRebinder()
238
                )
239
            );
240
241
            $url->setSessionResolver(function () {
242
                return $this->app['session'];
243
            });
244
245
            // If the route collection is "rebound", for example, when the routes stay
246
            // cached for the application, we will need to rebind the routes on the
247
            // URL generator instance so it has the latest version of the routes.
248
            $app->rebinding('routes', function ($app, $routes) {
249
                $app['url']->setRoutes($routes);
250
            });
251
252
            return $url;
253
        });
254
    }
255
256
    /**
257
     * Get the URL generator request rebinder.
258
     *
259
     * @return \Closure
260
     */
261
    protected function requestRebinder()
262
    {
263
        return function ($app, $request) {
264
            $app['url']->setRequest($request);
265
        };
266
    }
267
268
    /**
269
     * Override the LaravelLocalization instance.
270
     *
271
     * @return void
272
     */
273
    protected function overrideLaravelLocalization(): void
274
    {
275
        $this->app->singleton('laravellocalization', function () {
276
            return new LaravelLocalization();
277
        });
278
    }
279
280
    /**
281
     * Register console commands.
282
     *
283
     * @return void
284
     */
285
    protected function overrideLangJS(): void
286
    {
287
        // Bind the Laravel JS Localization command into the app IOC.
288
        $this->app->singleton('localization.js', function ($app) {
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...
289
            $app = $this->app;
290
            $laravelMajorVersion = (int) $app::VERSION;
291
292
            $files = $app['files'];
293
294
            if ($laravelMajorVersion === 4) {
295
                $langs = $app['path.base'].'/app/lang';
296
            } elseif ($laravelMajorVersion === 5) {
297
                $langs = $app['path.base'].'/resources/lang';
298
            }
299
            $messages = $app['config']->get('localization-js.messages');
300
            $generator = new LangJsGenerator($files, $langs, $messages);
0 ignored issues
show
Bug introduced by
The variable $langs does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
301
302
            return new LangJsCommand($generator);
303
        });
304
305
        // Bind the Laravel JS Localization command into Laravel Artisan.
306
        $this->commands('localization.js');
307
    }
308
309
    /**
310
     * Bind presence verifier.
311
     *
312
     * @return void
313
     */
314
    protected function bindPresenceVerifier(): void
315
    {
316
        $this->app->bind('cortex.foundation.presence.verifier', function ($app) {
317
            return new EloquentPresenceVerifier($app['db'], new $app[AbstractModel::class]());
318
        });
319
    }
320
321
    /**
322
     * Bind blueprint macro.
323
     *
324
     * @return void
325
     */
326
    protected function bindBlueprintMacro(): void
327
    {
328
        Blueprint::macro('auditable', function () {
329
            $this->integer('created_by_id')->unsigned()->after('created_at')->nullable();
330
            $this->string('created_by_type')->after('created_at')->nullable();
331
            $this->integer('updated_by_id')->unsigned()->after('updated_at')->nullable();
332
            $this->string('updated_by_type')->after('updated_at')->nullable();
333
        });
334
335
        Blueprint::macro('dropAuditable', function () {
336
            $this->dropForeign($this->createIndexName('foreign', ['updated_by_type']));
337
            $this->dropForeign($this->createIndexName('foreign', ['updated_by_id']));
338
            $this->dropForeign($this->createIndexName('foreign', ['created_by_type']));
339
            $this->dropForeign($this->createIndexName('foreign', ['created_by_id']));
340
            $this->dropColumn(['updated_by_type', 'updated_by_id', 'created_by_type', 'created_by_id']);
341
        });
342
343
        Blueprint::macro('auditableAndTimestamps', function ($precision = 0) {
344
            $this->timestamp('created_at', $precision)->nullable();
345
            $this->integer('created_by_id')->unsigned()->nullable();
346
            $this->string('created_by_type')->nullable();
347
            $this->timestamp('updated_at', $precision)->nullable();
348
            $this->integer('updated_by_id')->unsigned()->nullable();
349
            $this->string('updated_by_type')->nullable();
350
        });
351
352
        Blueprint::macro('dropauditableAndTimestamps', function () {
353
            $this->dropForeign($this->createIndexName('foreign', ['updated_by_type']));
354
            $this->dropForeign($this->createIndexName('foreign', ['updated_by_id']));
355
            $this->dropForeign($this->createIndexName('foreign', ['updated_at']));
356
            $this->dropForeign($this->createIndexName('foreign', ['created_by_type']));
357
            $this->dropForeign($this->createIndexName('foreign', ['created_by_id']));
358
            $this->dropForeign($this->createIndexName('foreign', ['created_at']));
359
            $this->dropColumn(['updated_by_type', 'updated_by_id', 'updated_at', 'created_by_type', 'created_by_id', 'created_at']);
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...
360
        });
361
    }
362
}
363