Passed
Pull Request — 1.2 (#558)
by
unknown
09:10
created

TwillServiceProvider   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 389
Duplicated Lines 0 %

Test Coverage

Coverage 92.61%

Importance

Changes 23
Bugs 0 Features 0
Metric Value
eloc 167
dl 0
loc 389
ccs 163
cts 176
cp 0.9261
rs 9.6
c 23
b 0
f 0
wmc 35

17 Methods

Rating   Name   Duplication   Size   Complexity  
A publishConfigs() 0 28 3
A registerAndPublishViews() 0 6 1
A registerAndPublishTranslations() 0 6 1
A publishAssets() 0 5 1
A registerAliases() 0 10 3
A mergeConfigs() 0 16 1
A publishOptionalMigration() 0 8 2
A includeView() 0 16 3
A registerProviders() 0 15 4
A addViewComposers() 0 23 4
A version() 0 3 1
A publishMigrations() 0 12 2
A requireHelpers() 0 8 1
A register() 0 15 1
A registerCommands() 0 10 1
A boot() 0 14 1
A extendBlade() 0 61 5
1
<?php
2
3
namespace A17\Twill;
4
5
use A17\Twill\Commands\Build;
6
use A17\Twill\Commands\CreateSuperAdmin;
7
use A17\Twill\Commands\GenerateBlocks;
8
use A17\Twill\Commands\Install;
9
use A17\Twill\Commands\ModuleMake;
10
use A17\Twill\Commands\RefreshLQIP;
11
use A17\Twill\Commands\Update;
12
use A17\Twill\Http\ViewComposers\ActiveNavigation;
13
use A17\Twill\Http\ViewComposers\CurrentUser;
14
use A17\Twill\Http\ViewComposers\FilesUploaderConfig;
15
use A17\Twill\Http\ViewComposers\MediasUploaderConfig;
16
use A17\Twill\Models\Block;
17
use A17\Twill\Models\File;
18
use A17\Twill\Models\Media;
19
use A17\Twill\Models\User;
20
use A17\Twill\Services\FileLibrary\FileService;
21
use A17\Twill\Services\MediaLibrary\ImageService;
22
use Astrotomic\Translatable\TranslatableServiceProvider;
23
use Cartalyst\Tags\TagsServiceProvider;
24
use Illuminate\Database\Eloquent\Relations\Relation;
25
use Illuminate\Foundation\AliasLoader;
26
use Illuminate\Support\Facades\View;
27
use Illuminate\Support\ServiceProvider;
28
use Illuminate\Support\Str;
29
use Spatie\Activitylog\ActivitylogServiceProvider;
30
31
class TwillServiceProvider extends ServiceProvider
32
{
33
34
    /**
35
     * The Twill version.
36
     *
37
     * @var string
38
     */
39
    const VERSION = '2.0.0';
40
41
    /**
42
     * Service providers to be registered.
43
     *
44
     * @var string[]
45
     */
46
    protected $providers = [
47
        RouteServiceProvider::class,
48
        AuthServiceProvider::class,
49
        ValidationServiceProvider::class,
50
        TranslatableServiceProvider::class,
51
        TagsServiceProvider::class,
52
        ActivitylogServiceProvider::class,
53
    ];
54
55
    private $migrationsCounter = 0;
0 ignored issues
show
introduced by
The private property $migrationsCounter is not used, and could be removed.
Loading history...
56
57
    /**
58
     * Bootstraps the package services.
59
     *
60
     * @return void
61
     */
62 59
    public function boot()
63
    {
64 59
        $this->requireHelpers();
65
66 59
        $this->publishConfigs();
67 59
        $this->publishMigrations();
68 59
        $this->publishAssets();
69
70 59
        $this->registerCommands();
71
72 59
        $this->registerAndPublishViews();
73
74 59
        $this->extendBlade();
75 59
        $this->addViewComposers();
76 59
    }
77
78
    /**
79
     * @return void
80
     */
81 59
    private function requireHelpers()
82
    {
83 59
        require_once __DIR__ . '/Helpers/routes_helpers.php';
84 59
        require_once __DIR__ . '/Helpers/i18n_helpers.php';
85 59
        require_once __DIR__ . '/Helpers/media_library_helpers.php';
86 59
        require_once __DIR__ . '/Helpers/frontend_helpers.php';
87 59
        require_once __DIR__ . '/Helpers/migrations_helpers.php';
88 59
        require_once __DIR__ . '/Helpers/helpers.php';
89 59
    }
90
91
    /**
92
     * Registers the package services.
93
     *
94
     * @return void
95
     */
96 59
    public function register()
97
    {
98 59
        $this->mergeConfigs();
99
100 59
        $this->registerProviders();
101 59
        $this->registerAliases();
102
103 59
        Relation::morphMap([
104 59
            'users' => User::class,
105
            'media' => Media::class,
106
            'files' => File::class,
107
            'blocks' => Block::class,
108
        ]);
109
110 59
        config(['twill.version' => $this->version()]);
111 59
    }
112
113
    /**
114
     * Registers the package service providers.
115
     *
116
     * @return void
117
     */
118 59
    private function registerProviders()
119
    {
120 59
        foreach ($this->providers as $provider) {
121 59
            $this->app->register($provider);
122
        }
123
124 59
        if (config('twill.enabled.media-library')) {
125
            $this->app->singleton('imageService', function () {
126 7
                return $this->app->make(config('twill.media_library.image_service'));
127 59
            });
128
        }
129
130 59
        if (config('twill.enabled.file-library')) {
131
            $this->app->singleton('fileService', function () {
132 3
                return $this->app->make(config('twill.file_library.file_service'));
133 59
            });
134
        }
135 59
    }
136
137
    /**
138
     * Registers the package facade aliases.
139
     *
140
     * @return void
141
     */
142 59
    private function registerAliases()
143
    {
144 59
        $loader = AliasLoader::getInstance();
145
146 59
        if (config('twill.enabled.media-library')) {
147 59
            $loader->alias('ImageService', ImageService::class);
148
        }
149
150 59
        if (config('twill.enabled.file-library')) {
151 59
            $loader->alias('FileService', FileService::class);
152
        }
153
154 59
    }
155
156
    /**
157
     * Defines the package configuration files for publishing.
158
     *
159
     * @return void
160
     */
161 59
    private function publishConfigs()
162
    {
163 59
        if (config('twill.enabled.users-management')) {
164 59
            config(['auth.providers.twill_users' => [
165 59
                'driver' => 'eloquent',
166
                'model' => User::class,
167
            ]]);
168
169 59
            config(['auth.guards.twill_users' => [
170 59
                'driver' => 'session',
171
                'provider' => 'twill_users',
172
            ]]);
173
174 59
            config(['auth.passwords.twill_users' => [
175 59
                'provider' => 'twill_users',
176 59
                'table' => config('twill.password_resets_table', 'twill_password_resets'),
177 59
                'expire' => 60,
178
            ]]);
179
        }
180
181 59
        config(['activitylog.enabled' => config('twill.enabled.dashboard') ? true : config('twill.enabled.activitylog')]);
182 59
        config(['activitylog.subject_returns_soft_deleted_models' => true]);
183
184 59
        config(['analytics.service_account_credentials_json' => config('twill.dashboard.analytics.service_account_credentials_json', storage_path('app/analytics/service-account-credentials.json'))]);
185
186 59
        $this->publishes([__DIR__ . '/../config/twill-publish.php' => config_path('twill.php')], 'config');
187 59
        $this->publishes([__DIR__ . '/../config/twill-navigation.php' => config_path('twill-navigation.php')], 'config');
188 59
        $this->publishes([__DIR__ . '/../config/translatable.php' => config_path('translatable.php')], 'config');
189 59
    }
190
191
    /**
192
     * Merges the package configuration files into the given configuration namespaces.
193
     *
194
     * @return void
195
     */
196 59
    private function mergeConfigs()
197
    {
198 59
        $this->mergeConfigFrom(__DIR__ . '/../config/twill.php', 'twill');
199 59
        $this->mergeConfigFrom(__DIR__ . '/../config/frontend.php', 'twill.frontend');
200 59
        $this->mergeConfigFrom(__DIR__ . '/../config/debug.php', 'twill.debug');
201 59
        $this->mergeConfigFrom(__DIR__ . '/../config/seo.php', 'twill.seo');
202 59
        $this->mergeConfigFrom(__DIR__ . '/../config/blocks.php', 'twill.block_editor');
203 59
        $this->mergeConfigFrom(__DIR__ . '/../config/enabled.php', 'twill.enabled');
204 59
        $this->mergeConfigFrom(__DIR__ . '/../config/file-library.php', 'twill.file_library');
205 59
        $this->mergeConfigFrom(__DIR__ . '/../config/media-library.php', 'twill.media_library');
206 59
        $this->mergeConfigFrom(__DIR__ . '/../config/imgix.php', 'twill.imgix');
207 59
        $this->mergeConfigFrom(__DIR__ . '/../config/glide.php', 'twill.glide');
208 59
        $this->mergeConfigFrom(__DIR__ . '/../config/dashboard.php', 'twill.dashboard');
209 59
        $this->mergeConfigFrom(__DIR__ . '/../config/oauth.php', 'twill.oauth');
210 59
        $this->mergeConfigFrom(__DIR__ . '/../config/disks.php', 'filesystems.disks');
211 59
        $this->mergeConfigFrom(__DIR__ . '/../config/services.php', 'services');
212 59
    }
213
214 59
    private function publishMigrations()
215
    {
216 59
        if (config('twill.load_default_migrations_from_twill', true)) {
217 59
            $this->loadMigrationsFrom(__DIR__ . '/../migrations/default');
218
        }
219
220 59
        $this->publishes([
221 59
            __DIR__ . '/../migrations/default' => database_path('migrations'),
222 59
        ], 'migrations');
223
224 59
        $this->publishOptionalMigration('users-2fa');
225 59
        $this->publishOptionalMigration('users-oauth');
226 59
    }
227
228 59
    private function publishOptionalMigration($feature)
229
    {
230 59
        if (config('twill.enabled.' . $feature, false)) {
231 55
            $this->loadMigrationsFrom(__DIR__ . '/../migrations/optional/' . $feature);
232
233 55
            $this->publishes([
234 55
                __DIR__ . '/../migrations/optional/' . $feature => database_path('migrations'),
235 55
            ], 'migrations');
236
        }
237 59
    }
238
239
    /**
240
     * @return void
241
     */
242 59
    private function publishAssets()
243
    {
244 59
        $this->publishes([
245 59
            __DIR__ . '/../dist' => public_path(),
246 59
        ], 'assets');
247 59
    }
248
249
    /**
250
     * @return void
251
     */
252 59
    private function registerAndPublishViews()
253
    {
254 59
        $viewPath = __DIR__ . '/../views';
255
256 59
        $this->loadViewsFrom($viewPath, 'twill');
257 59
        $this->publishes([$viewPath => resource_path('views/vendor/twill')], 'views');
258 59
    }
259
260
    /**
261
     * @return void
262
     */
263 59
    private function registerCommands()
264
    {
265 59
        $this->commands([
266 59
            Install::class,
267
            ModuleMake::class,
268
            CreateSuperAdmin::class,
269
            RefreshLQIP::class,
270
            GenerateBlocks::class,
271
            Build::class,
272
            Update::class,
273
        ]);
274 59
    }
275
276
    /**
277
     * @param string $view
278
     * @param string $expression
279
     * @return string
280
     */
281 5
    private function includeView($view, $expression)
282
    {
283 5
        list($name) = str_getcsv($expression, ',', '\'');
284
285 5
        $partialNamespace = view()->exists('admin.' . $view . $name) ? 'admin.' : 'twill::';
286
287 5
        $view = $partialNamespace . $view . $name;
288
289 5
        $expression = explode(',', $expression);
290 5
        array_shift($expression);
291 5
        $expression = "(" . implode(',', $expression) . ")";
292 5
        if ($expression === "()") {
293 3
            $expression = '([])';
294
        }
295
296 5
        return "<?php echo \$__env->make('{$view}', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->with{$expression}->render(); ?>";
297
    }
298
299
    /**
300
     * Defines the package additional Blade Directives.
301
     *
302
     * @return void
303
     */
304 59
    private function extendBlade()
305
    {
306 59
        $blade = $this->app['view']->getEngineResolver()->resolve('blade')->getCompiler();
307
308
        $blade->directive('dd', function ($param) {
309
            return "<?php dd({$param}); ?>";
310 59
        });
311
312
        $blade->directive('dumpData', function ($data) {
313
            return sprintf("<?php (new Symfony\Component\VarDumper\VarDumper)->dump(%s); exit; ?>",
314
                null != $data ? $data : "get_defined_vars()");
315 59
        });
316
317
        $blade->directive('formField', function ($expression) use ($blade) {
0 ignored issues
show
Unused Code introduced by
The import $blade is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
318 5
            return $this->includeView('partials.form._', $expression);
319 59
        });
320
321
        $blade->directive('partialView', function ($expression) use ($blade) {
0 ignored issues
show
Unused Code introduced by
The import $blade is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
322
323 2
            $expressionAsArray = str_getcsv($expression, ',', '\'');
324
325 2
            list($moduleName, $viewName) = $expressionAsArray;
326 2
            $partialNamespace = 'twill::partials';
327
328 2
            $viewModule = "'admin.'.$moduleName.'.{$viewName}'";
329 2
            $viewApplication = "'admin.partials.{$viewName}'";
330 2
            $viewModuleTwill = "'twill::'.$moduleName.'.{$viewName}'";
331 2
            $view = $partialNamespace . "." . $viewName;
332
333 2
            if (!isset($moduleName) || is_null($moduleName)) {
334
                $viewModule = $viewApplication;
335
            }
336
337 2
            $expression = explode(',', $expression);
338 2
            $expression = array_slice($expression, 2);
339 2
            $expression = "(" . implode(',', $expression) . ")";
340 2
            if ($expression === "()") {
341 1
                $expression = '([])';
342
            }
343
344
            return "<?php
345 2
            if( view()->exists($viewModule)) {
346 2
                echo \$__env->make($viewModule, \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->with{$expression}->render();
347 2
            } elseif( view()->exists($viewApplication)) {
348 2
                echo \$__env->make($viewApplication, \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->with{$expression}->render();
349 2
            } elseif( view()->exists($viewModuleTwill)) {
350 2
                echo \$__env->make($viewModuleTwill, \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->with{$expression}->render();
351 2
            } elseif( view()->exists('$view')) {
352 2
                echo \$__env->make('$view', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->with{$expression}->render();
353
            }
354
            ?>";
355 59
        });
356
357
        $blade->directive('pushonce', function ($expression) {
358
            list($pushName, $pushSub) = explode(':', trim(substr($expression, 1, -1)));
359
            $key = '__pushonce_' . $pushName . '_' . str_replace('-', '_', $pushSub);
360
            return "<?php if(! isset(\$__env->{$key})): \$__env->{$key} = 1; \$__env->startPush('{$pushName}'); ?>";
361 59
        });
362
363
        $blade->directive('endpushonce', function () {
364
            return '<?php $__env->stopPush(); endif; ?>';
365 59
        });
366 59
    }
367
368
    /**
369
     * Registers the package additional View Composers.
370
     *
371
     * @return void
372
     */
373 59
    private function addViewComposers()
374
    {
375 59
        if (config('twill.enabled.users-management')) {
376 59
            View::composer(['admin.*', 'twill::*'], CurrentUser::class);
377
        }
378
379 59
        if (config('twill.enabled.media-library')) {
380 59
            View::composer('twill::layouts.main', MediasUploaderConfig::class);
381
        }
382
383 59
        if (config('twill.enabled.file-library')) {
384 59
            View::composer('twill::layouts.main', FilesUploaderConfig::class);
385
        }
386
387 59
        View::composer('twill::partials.navigation.*', ActiveNavigation::class);
388
389
        View::composer(['admin.*', 'templates.*', 'twill::*'], function ($view) {
390 50
            $with = array_merge([
391 50
                'renderForBlocks' => false,
392
                'renderForModal' => false,
393 50
            ], $view->getData());
394
395 50
            return $view->with($with);
396 59
        });
397 59
    }
398
399
    /**
400
     * Registers and publishes the package additional translations.
401
     *
402
     * @return void
403
     */
404
    private function registerAndPublishTranslations()
405
    {
406
        $translationPath = __DIR__ . '/../lang';
407
408
        $this->loadTranslationsFrom($translationPath, 'twill');
409
        $this->publishes([$translationPath => resource_path('lang/vendor/twill')], 'translations');
410
    }
411
412
    /**
413
     * Get the version number of Twill.
414
     *
415
     * @return string
416
     */
417 59
    public function version()
418
    {
419 59
        return static::VERSION;
420
    }
421
}
422