Passed
Pull Request — 2.x (#1042)
by Antonio Carlos
06:36
created

TwillServiceProvider::extendBlade()   B

Complexity

Conditions 6
Paths 2

Size

Total Lines 75
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 49
CRAP Score 6.0002

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
eloc 49
c 2
b 0
f 0
nc 2
nop 0
dl 0
loc 75
ccs 49
cts 50
cp 0.98
crap 6.0002
rs 8.4905

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace A17\Twill;
4
5
use Exception;
6
use A17\Twill\Commands\BlockMake;
7
use A17\Twill\Commands\Build;
8
use A17\Twill\Commands\CapsuleInstall;
9
use A17\Twill\Commands\CreateSuperAdmin;
10
use A17\Twill\Commands\Dev;
11
use A17\Twill\Commands\GenerateBlocks;
12
use A17\Twill\Commands\Install;
13
use A17\Twill\Commands\ListBlocks;
14
use A17\Twill\Commands\ListIcons;
15
use A17\Twill\Commands\MakeCapsule;
16
use A17\Twill\Commands\ModuleMake;
17
use A17\Twill\Commands\ModuleMakeDeprecated;
18
use A17\Twill\Commands\RefreshLQIP;
19
use A17\Twill\Commands\SyncLang;
20
use A17\Twill\Commands\Update;
21
use A17\Twill\Http\ViewComposers\ActiveNavigation;
22
use A17\Twill\Http\ViewComposers\CurrentUser;
23
use A17\Twill\Http\ViewComposers\FilesUploaderConfig;
24
use A17\Twill\Http\ViewComposers\Localization;
25
use A17\Twill\Http\ViewComposers\MediasUploaderConfig;
26
use A17\Twill\Models\Block;
27
use A17\Twill\Models\File;
28
use A17\Twill\Models\Media;
29
use A17\Twill\Models\User;
30
use A17\Twill\Services\Capsules\HasCapsules;
31
use A17\Twill\Services\FileLibrary\FileService;
32
use A17\Twill\Services\MediaLibrary\ImageService;
33
use Astrotomic\Translatable\TranslatableServiceProvider;
34
use Cartalyst\Tags\TagsServiceProvider;
35
use Illuminate\Database\Eloquent\Relations\Relation;
36
use Illuminate\Foundation\AliasLoader;
37
use Illuminate\Support\Facades\View;
38
use Illuminate\Support\ServiceProvider;
39
use Illuminate\Support\Str;
40
use Spatie\Activitylog\ActivitylogServiceProvider;
41
use PragmaRX\Google2FAQRCode\Google2FA as Google2FAQRCode;
42
43
class TwillServiceProvider extends ServiceProvider
44
{
45
    use HasCapsules;
0 ignored issues
show
Bug introduced by
The trait A17\Twill\Services\Capsules\HasCapsules requires the property $command which is not provided by A17\Twill\TwillServiceProvider.
Loading history...
46
47
    /**
48
     * The Twill version.
49
     *
50
     * @var string
51
     */
52
    const VERSION = '2.4.0';
53
54
    /**
55
     * Service providers to be registered.
56
     *
57
     * @var string[]
58
     */
59
    protected $providers = [
60
        RouteServiceProvider::class,
61
        AuthServiceProvider::class,
62
        ValidationServiceProvider::class,
63
        TranslatableServiceProvider::class,
64
        TagsServiceProvider::class,
65
        ActivitylogServiceProvider::class,
66
        CapsulesServiceProvider::class,
67
    ];
68
69 73
    private $migrationsCounter = 0;
0 ignored issues
show
introduced by
The private property $migrationsCounter is not used, and could be removed.
Loading history...
70
71 73
    /**
72
     * Bootstraps the package services.
73 73
     *
74 73
     * @return void
75 73
     */
76
    public function boot()
77 73
    {
78
        $this->requireHelpers();
79 73
80 73
        $this->publishConfigs();
81
        $this->publishMigrations();
82 73
        $this->publishAssets();
83 73
84 73
        $this->registerCommands();
85
86
        $this->registerAndPublishViews();
87
        $this->registerAndPublishTranslations();
88
89 73
        $this->extendBlade();
90
        $this->addViewComposers();
91 73
92 73
        $this->check2FA();
93 73
    }
94 73
95 73
    /**
96 73
     * @return void
97 73
     */
98
    private function requireHelpers()
99
    {
100
        require_once __DIR__ . '/Helpers/routes_helpers.php';
101
        require_once __DIR__ . '/Helpers/i18n_helpers.php';
102
        require_once __DIR__ . '/Helpers/media_library_helpers.php';
103
        require_once __DIR__ . '/Helpers/frontend_helpers.php';
104 73
        require_once __DIR__ . '/Helpers/migrations_helpers.php';
105
        require_once __DIR__ . '/Helpers/helpers.php';
106 73
    }
107
108 73
    /**
109 73
     * Registers the package services.
110
     *
111 73
     * @return void
112 73
     */
113
    public function register()
114
    {
115
        $this->mergeConfigs();
116
117
        $this->registerProviders();
118 73
        $this->registerAliases();
119 73
120
        Relation::morphMap([
121
            'users' => User::class,
122
            'media' => Media::class,
123
            'files' => File::class,
124
            'blocks' => Block::class,
125
        ]);
126 73
127
        config(['twill.version' => $this->version()]);
128 73
    }
129 73
130
    /**
131
     * Registers the package service providers.
132 73
     *
133 73
     * @return void
134 8
     */
135 73
    private function registerProviders()
136
    {
137
        foreach ($this->providers as $provider) {
138 73
            $this->app->register($provider);
139 73
        }
140 3
141 73
        if (config('twill.enabled.media-library')) {
142
            $this->app->singleton('imageService', function () {
143 73
                return $this->app->make(config('twill.media_library.image_service'));
144
            });
145
        }
146
147
        if (config('twill.enabled.file-library')) {
148
            $this->app->singleton('fileService', function () {
149
                return $this->app->make(config('twill.file_library.file_service'));
150 73
            });
151
        }
152 73
    }
153
154 73
    /**
155 73
     * Registers the package facade aliases.
156
     *
157
     * @return void
158 73
     */
159 73
    private function registerAliases()
160
    {
161
        $loader = AliasLoader::getInstance();
162 73
163
        if (config('twill.enabled.media-library')) {
164
            $loader->alias('ImageService', ImageService::class);
165
        }
166
167
        if (config('twill.enabled.file-library')) {
168
            $loader->alias('FileService', FileService::class);
169 73
        }
170
171 73
    }
172 73
173 73
    /**
174
     * Defines the package configuration files for publishing.
175
     *
176
     * @return void
177 73
     */
178 73
    private function publishConfigs()
179
    {
180
        if (config('twill.enabled.users-management')) {
181
            config(['auth.providers.twill_users' => [
182 73
                'driver' => 'eloquent',
183 73
                'model' => User::class,
184 73
            ]]);
185 73
186
            config(['auth.guards.twill_users' => [
187
                'driver' => 'session',
188
                'provider' => 'twill_users',
189 73
            ]]);
190 73
191
            config(['auth.passwords.twill_users' => [
192 73
                'provider' => 'twill_users',
193
                'table' => config('twill.password_resets_table', 'twill_password_resets'),
194 73
                'expire' => 60,
195 73
            ]]);
196 73
        }
197 73
198
        config(['activitylog.enabled' => config('twill.enabled.dashboard') ? true : config('twill.enabled.activitylog')]);
199
        config(['activitylog.subject_returns_soft_deleted_models' => true]);
200
201
        config(['analytics.service_account_credentials_json' => config('twill.dashboard.analytics.service_account_credentials_json', storage_path('app/analytics/service-account-credentials.json'))]);
202
203
        $this->publishes([__DIR__ . '/../config/twill-publish.php' => config_path('twill.php')], 'config');
204 73
        $this->publishes([__DIR__ . '/../config/twill-navigation.php' => config_path('twill-navigation.php')], 'config');
205
        $this->publishes([__DIR__ . '/../config/translatable.php' => config_path('translatable.php')], 'config');
206 73
    }
207 73
208 73
    /**
209 73
     * Merges the package configuration files into the given configuration namespaces.
210 73
     *
211 73
     * @return void
212 73
     */
213 73
    private function mergeConfigs()
214 73
    {
215 73
        $this->mergeConfigFrom(__DIR__ . '/../config/twill.php', 'twill');
216 73
        $this->mergeConfigFrom(__DIR__ . '/../config/frontend.php', 'twill.frontend');
217 73
        $this->mergeConfigFrom(__DIR__ . '/../config/debug.php', 'twill.debug');
218 73
        $this->mergeConfigFrom(__DIR__ . '/../config/seo.php', 'twill.seo');
219
        $this->mergeConfigFrom(__DIR__ . '/../config/blocks.php', 'twill.block_editor');
220 73
        $this->mergeConfigFrom(__DIR__ . '/../config/enabled.php', 'twill.enabled');
221 73
        $this->mergeConfigFrom(__DIR__ . '/../config/file-library.php', 'twill.file_library');
222 73
        $this->mergeConfigFrom(__DIR__ . '/../config/media-library.php', 'twill.media_library');
223
        $this->mergeConfigFrom(__DIR__ . '/../config/imgix.php', 'twill.imgix');
224
        $this->mergeConfigFrom(__DIR__ . '/../config/glide.php', 'twill.glide');
225 73
        $this->mergeConfigFrom(__DIR__ . '/../config/dashboard.php', 'twill.dashboard');
226 73
        $this->mergeConfigFrom(__DIR__ . '/../config/oauth.php', 'twill.oauth');
227 73
        $this->mergeConfigFrom(__DIR__ . '/../config/disks.php', 'filesystems.disks');
228
229
        if (config('twill.media_library.endpoint_type') === 'local'
230 73
            && config('twill.media_library.disk') === 'twill_media_library') {
231 73
            $this->setLocalDiskUrl('media');
232
        }
233 73
234
        if (config('twill.file_library.endpoint_type') === 'local'
235 73
            && config('twill.file_library.disk') === 'twill_file_library') {
236 73
            $this->setLocalDiskUrl('file');
237 73
        }
238 73
239 73
        $this->mergeConfigFrom(__DIR__ . '/../config/services.php', 'services');
240 73
    }
241
242 73
    private function setLocalDiskUrl($type)
243
    {
244 73
        config([
245
            'filesystems.disks.twill_' . $type . '_library.url' => request()->getScheme()
246 73
            . '://'
247 73
            . str_replace(['http://', 'https://'], '', config('app.url'))
248
            . '/storage/'
249
            . trim(config('twill.' . $type . '_library.local_path'), '/ '),
250 73
        ]);
251 73
    }
252 73
253
    private function publishMigrations()
254 73
    {
255 73
        if (config('twill.load_default_migrations', true)) {
256 73
            $this->loadMigrationsFrom(__DIR__ . '/../migrations/default');
257
        }
258 73
259
        $this->publishes([
260 73
            __DIR__ . '/../migrations/default' => database_path('migrations'),
261 69
        ], 'migrations');
262
263 69
        $this->publishOptionalMigration('users-2fa');
264 69
        $this->publishOptionalMigration('users-oauth');
265 69
    }
266
267 73
    private function publishOptionalMigration($feature)
268
    {
269
        if (config('twill.enabled.' . $feature, false)) {
270
            $this->loadMigrationsFrom(__DIR__ . '/../migrations/optional/' . $feature);
271
272 73
            $this->publishes([
273
                __DIR__ . '/../migrations/optional/' . $feature => database_path('migrations'),
274 73
            ], 'migrations');
275 73
        }
276 73
    }
277 73
278
    /**
279
     * @return void
280
     */
281
    private function publishAssets()
282 73
    {
283
        $this->publishes([
284 73
            __DIR__ . '/../dist' => public_path(),
285
        ], 'assets');
286 73
    }
287 73
288 73
    /**
289
     * @return void
290
     */
291
    private function registerAndPublishViews()
292
    {
293 73
        $viewPath = __DIR__ . '/../views';
294
295 73
        $this->loadViewsFrom($viewPath, 'twill');
296 73
        $this->publishes([$viewPath => resource_path('views/vendor/twill')], 'views');
297
    }
298
299
    /**
300
     * @return void
301
     */
302
    private function registerCommands()
303
    {
304
        $this->commands([
305
            Install::class,
306
            ModuleMake::class,
307
            MakeCapsule::class,
308
            ModuleMakeDeprecated::class,
309
            BlockMake::class,
310 73
            ListIcons::class,
311
            ListBlocks::class,
312
            CreateSuperAdmin::class,
313
            RefreshLQIP::class,
314
            GenerateBlocks::class,
315
            Build::class,
316
            Update::class,
317 5
            Dev::class,
318
            SyncLang::class,
319 5
            CapsuleInstall::class,
320
        ]);
321 5
    }
322
323 5
    /**
324
     * @param string $view
325 5
     * @param string $expression
326 5
     * @return string
327 5
     */
328 5
    private function includeView($view, $expression)
329 4
    {
330
        [$name] = str_getcsv($expression, ',', '\'');
331
332 5
        $partialNamespace = view()->exists('admin.' . $view . $name) ? 'admin.' : 'twill::';
333
334
        $view = $partialNamespace . $view . $name;
335
336
        $expression = explode(',', $expression);
337
        array_shift($expression);
338
        $expression = "(" . implode(',', $expression) . ")";
339
        if ($expression === "()") {
340 73
            $expression = '([])';
341
        }
342 73
343
        return "<?php echo \$__env->make('{$view}', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->with{$expression}->render(); ?>";
344 73
    }
345
346 73
    /**
347
     * Defines the package additional Blade Directives.
348 73
     *
349
     * @return void
350
     */
351 73
    private function extendBlade()
352
    {
353 73
        $blade = $this->app['view']->getEngineResolver()->resolve('blade')->getCompiler();
354 5
355 73
        $blade->directive('dd', function ($param) {
356
            return "<?php dd({$param}); ?>";
357 73
        });
358
359 3
        $blade->directive('dumpData', function ($data) {
360
            return sprintf("<?php (new Symfony\Component\VarDumper\VarDumper)->dump(%s); exit; ?>",
361 3
                null != $data ? $data : "get_defined_vars()");
362 3
        });
363
364 3
        $blade->directive('formField', function ($expression) {
365 3
            return $this->includeView('partials.form._', $expression);
366 3
        });
367 3
368
        $blade->directive('partialView', function ($expression) {
369 3
370
            $expressionAsArray = str_getcsv($expression, ',', '\'');
371
372
            [$moduleName, $viewName] = $expressionAsArray;
373 3
            $partialNamespace = 'twill::partials';
374 3
375 3
            $viewModule = "twillViewName($moduleName, '{$viewName}')";
376 3
            $viewApplication = "'admin.partials.{$viewName}'";
377 2
            $viewModuleTwill = "'twill::'.$moduleName.'.{$viewName}'";
378
            $view = $partialNamespace . "." . $viewName;
379
380 3
            if (!isset($moduleName) || is_null($moduleName)) {
381 3
                $viewModule = $viewApplication;
382 3
            }
383 3
384 3
            $expression = explode(',', $expression);
385 3
            $expression = array_slice($expression, 2);
386 3
            $expression = "(" . implode(',', $expression) . ")";
387 3
            if ($expression === "()") {
388 3
                $expression = '([])';
389
            }
390
391 73
            return "<?php
392
            if( view()->exists($viewModule)) {
393 73
                echo \$__env->make($viewModule, \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->with{$expression}->render();
394 1
            } elseif( view()->exists($viewApplication)) {
395 1
                echo \$__env->make($viewApplication, \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->with{$expression}->render();
396 1
            } elseif( view()->exists($viewModuleTwill)) {
397 73
                echo \$__env->make($viewModuleTwill, \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->with{$expression}->render();
398
            } elseif( view()->exists('$view')) {
399 73
                echo \$__env->make('$view', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->with{$expression}->render();
400 1
            }
401 73
            ?>";
402
        });
403 73
404 73
        $blade->directive('pushonce', function ($expression) {
405 73
            [$pushName, $pushSub] = explode(':', trim(substr($expression, 1, -1)));
406 73
            $key = '__pushonce_' . $pushName . '_' . str_replace('-', '_', $pushSub);
407 73
            return "<?php if(! isset(\$__env->{$key})): \$__env->{$key} = 1; \$__env->startPush('{$pushName}'); ?>";
408
        });
409 73
410 73
        $blade->directive('endpushonce', function () {
411 73
            return '<?php $__env->stopPush(); endif; ?>';
412 73
        });
413 73
414 73
        $blade->component('twill::partials.form.utils._fieldset', 'formFieldset');
415
        $blade->component('twill::partials.form.utils._columns', 'formColumns');
416
        $blade->component('twill::partials.form.utils._collapsed_fields', 'formCollapsedFields');
417 73
        $blade->component('twill::partials.form.utils._connected_fields', 'formConnectedFields');
418
        $blade->component('twill::partials.form.utils._inline_checkboxes', 'formInlineCheckboxes');
419
420
        if (method_exists($blade, 'aliasComponent')) {
421
            $blade->aliasComponent('twill::partials.form.utils._fieldset', 'formFieldset');
422
            $blade->aliasComponent('twill::partials.form.utils._columns', 'formColumns');
423
            $blade->aliasComponent('twill::partials.form.utils._collapsed_fields', 'formCollapsedFields');
424 73
            $blade->aliasComponent('twill::partials.form.utils._connected_fields', 'formConnectedFields');
425
            $blade->aliasComponent('twill::partials.form.utils._inline_checkboxes', 'formInlineCheckboxes');
426 73
        }
427 73
428
    }
429
430 73
    /**
431 73
     * Registers the package additional View Composers.
432
     *
433
     * @return void
434 73
     */
435 73
    private function addViewComposers()
436
    {
437
        if (config('twill.enabled.users-management')) {
438 73
            View::composer(['admin.*', 'twill::*'], CurrentUser::class);
439
        }
440 73
441 52
        if (config('twill.enabled.media-library')) {
442 52
            View::composer('twill::layouts.main', MediasUploaderConfig::class);
443
        }
444 52
445
        if (config('twill.enabled.file-library')) {
446 52
            View::composer('twill::layouts.main', FilesUploaderConfig::class);
447 73
        }
448
449 73
        View::composer('twill::partials.navigation.*', ActiveNavigation::class);
450 73
451
        View::composer(['admin.*', 'templates.*', 'twill::*'], function ($view) {
452
            $with = array_merge([
453
                'renderForBlocks' => false,
454
                'renderForModal' => false,
455
            ], $view->getData());
456
457 73
            return $view->with($with);
458
        });
459 73
460
        View::composer(['admin.*', 'twill::*'], Localization::class);
461 73
    }
462 73
463 73
    /**
464
     * Registers and publishes the package additional translations.
465
     *
466
     * @return void
467
     */
468
    private function registerAndPublishTranslations()
469
    {
470 73
        $translationPath = __DIR__ . '/../lang';
471
472 73
        $this->loadTranslationsFrom($translationPath, 'twill');
473
        $this->publishes([$translationPath => resource_path('lang/vendor/twill')], 'translations');
474
    }
475
476
    /**
477
     * Get the version number of Twill.
478
     *
479
     * @return string
480
     */
481
    public function version()
482
    {
483
        return static::VERSION;
484
    }
485
486
    /**
487
     * In case 2FA is enabled, we need to check if a QRCode compatible package is
488
     * installed.
489
     */
490
    public function check2FA()
491
    {
492
        if (!config('twill.enabled.users-2fa')) {
493
            return;
494
        }
495
496
        if (blank((new Google2FAQRCode())->getQrCodeService()))
497
        {
498
            throw new Exception(
499
                "Twill ERROR: As you have 2FA enabled, you also need to install a QRCode service package, please check https://github.com/antonioribeiro/google2fa-qrcode#built-in-qrcode-rendering-services"
500
            );
501
        }
502
    }
503
}
504