Completed
Push — master ( 5bb2ae...adea1c )
by Terzi
04:11
created

ContainersServiceProvider   A

Complexity

Total Complexity 40

Size/Duplication

Total Lines 253
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 0
loc 253
ccs 0
cts 113
cp 0
rs 9.2
c 0
b 0
f 0
eloc 98
wmc 40

32 Methods

Rating   Name   Duplication   Size   Complexity  
A hp$0 ➔ readonly() 0 7 2
A hp$0 ➔ setReadonly() 0 5 1
A hp$0 ➔ __construct() 0 3 1
A registerAdminAnnotations() 0 9 1
A hp$0 ➔ registerAdminActions() 0 5 2
A registerAdminConfig() 0 6 1
registerAdminFinder() 0 16 ?
A register() 0 10 2
A hp$0 ➔ registerAdminTranslations() 0 51 2
registerAdminActions() 0 5 ?
registerAdminSchema() 0 10 ?
registerAdminModel() 0 7 ?
registerAdminTemplate() 0 12 ?
A hp$0 ➔ registerAdminForm() 0 5 2
registerAdminTranslations() 0 51 ?
registerAdminResource() 0 12 ?
A hp$0 ➔ registerAdminModel() 0 7 3
A hp$0 ➔ registerAdminTemplate() 0 12 3
A hp$0 ➔ registerAdminSchema() 0 10 2
A hp$0 ➔ registerAdminResource() 0 12 5
A hp$0 ➔ registerAdminWidgets() 0 8 2
A hp$0 ➔ registerAdminSortable() 0 7 4
registerAdminSortable() 0 7 ?
A hp$0 ➔ registerAdminBreadcrumbs() 0 7 2
registerAdminWidgets() 0 8 ?
A hp$0 ➔ registerAdminColumns() 0 5 2
registerAdminFilter() 0 8 ?
registerAdminBreadcrumbs() 0 7 ?
A hp$0 ➔ registerAdminFilter() 0 8 4
registerAdminForm() 0 5 ?
A hp$0 ➔ registerAdminFinder() 0 16 3
registerAdminColumns() 0 5 ?

How to fix   Complexity   

Complex Class

Complex classes like ContainersServiceProvider often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ContainersServiceProvider, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Terranet\Administrator\Providers;
4
5
use Doctrine\Common\Annotations\AnnotationRegistry;
6
use Doctrine\Common\Annotations\SimpleAnnotationReader;
7
use Illuminate\Config\Repository as Config;
8
use Illuminate\Support\ServiceProvider;
9
use Terranet\Administrator\Collection\Mutable;
10
use Terranet\Administrator\Contracts\Module;
11
use Terranet\Administrator\Contracts\Module\Filtrable;
12
use Terranet\Administrator\Contracts\Module\Sortable;
13
use Terranet\Administrator\Contracts\Services\Finder;
14
use Terranet\Administrator\Contracts\Services\TemplateProvider;
15
use Terranet\Administrator\Dashboard\Manager;
16
use Terranet\Administrator\Exception;
17
use Terranet\Administrator\Filter;
18
use Terranet\Administrator\Schema;
19
use Terranet\Administrator\Services\Sorter;
20
use Terranet\Administrator\Services\Template;
21
use Terranet\Localizer\Locale;
22
23
class ContainersServiceProvider extends ServiceProvider
24
{
25
    protected $containers = [
26
        'AdminConfig' => 'scaffold.config',
27
        'AdminResource' => 'scaffold.module',
28
        'AdminModel' => 'scaffold.model',
29
        'AdminWidgets' => 'scaffold.widgets',
30
        'AdminSchema' => 'scaffold.schema',
31
        'AdminSortable' => 'scaffold.sortable',
32
        'AdminFilter' => 'scaffold.filter',
33
        'AdminColumns' => 'scaffold.columns',
34
        'AdminActions' => 'scaffold.actions',
35
        'AdminTemplate' => 'scaffold.template',
36
        'AdminForm' => 'scaffold.form',
37
        'AdminFinder' => 'scaffold.finder',
38
        'AdminBreadcrumbs' => 'scaffold.breadcrumbs',
39
        'AdminTranslations' => 'scaffold.translations',
40
        'AdminAnnotations' => 'scaffold.annotations',
41
    ];
42
43
    public function register()
44
    {
45
        foreach (array_keys($this->containers) as $container) {
46
            $method = "register{$container}";
47
48
            \call_user_func_array([$this, $method], []);
49
        }
50
51
        $this->app->bind(Module::class, function ($app) {
52
            return $app['scaffold.module'];
53
        });
54
    }
55
56
    protected function registerAdminAnnotations()
57
    {
58
        $this->app->singleton('scaffold.annotations', function () {
59
            AnnotationRegistry::registerUniqueLoader('class_exists');
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\Common\Annotati...:registerUniqueLoader() has been deprecated: this method is deprecated and will be removed in doctrine/annotations 2.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

59
            /** @scrutinizer ignore-deprecated */ AnnotationRegistry::registerUniqueLoader('class_exists');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
60
61
            $reader = new SimpleAnnotationReader();
62
            $reader->addNamespace("\\Terranet\\Administrator\\Annotations");
63
64
            return $reader;
65
        });
66
    }
67
68
    protected function registerAdminConfig()
69
    {
70
        $this->app->singleton('scaffold.config', function ($app) {
71
            $config = $app['config']['administrator'];
72
73
            return new Config((array) $config);
74
        });
75
    }
76
77
    protected function registerAdminTranslations()
78
    {
79
        // Draft: Mui configuration
80
        // Goal: sometimes there is a case when few content managers (admins) override the same translatable content (files, db, etc...)
81
        // This service allows to make some locales readonly:
82
        //  1. they are available in UI in order to preserve the context
83
        //  2. they are protected from saving process
84
        // Making locale(s) Readonly remains for Dev's side: the recommended way - use a custom Middleware.
85
        // ex.: app('scaffold.translations')->setReadonly([1, 2, 3])
86
        $this->app->singleton('scaffold.translations', function ($app) {
87
            $service = new class()
88
            {
89
                protected $readonly = [];
90
91
                public function __construct()
92
                {
93
                    $this->setReadonly(config('administrator.translations.readonly', []));
94
                }
95
96
                /**
97
                 * Set ReadOnly locales.
98
                 *
99
                 * @param array $readonly
100
                 *
101
                 * @return self
102
                 */
103
                public function setReadonly(array $readonly = []): self
104
                {
105
                    $this->readonly = (array) $readonly;
106
107
                    return $this;
108
                }
109
110
                /**
111
                 * Check if a Locale is ReadOnly.
112
                 *
113
                 * @param $locale
114
                 *
115
                 * @return bool
116
                 */
117
                public function readonly($locale)
118
                {
119
                    if ($locale instanceof Locale) {
120
                        $locale = $locale->id();
121
                    }
122
123
                    return \in_array((int) $locale, $this->readonly, true);
124
                }
125
            };
126
127
            return $service;
128
        });
129
    }
130
131
    protected function registerAdminResource()
132
    {
133
        $this->app->singleton('scaffold.module', function ($app) {
134
            if (\in_array($app['router']->currentRouteName(), ['scaffold.settings.edit', 'scaffold.settings.update'], true)) {
135
                return $app['scaffold.module.settings'];
136
            }
137
138
            if (($router = $app['router']->current()) &&
139
                ($module = $router->parameter('module')) &&
140
                array_has($app, $key = "scaffold.module.{$module}")
141
            ) {
142
                return array_get($app, $key);
143
            }
144
        });
145
    }
146
147
    protected function registerAdminModel()
148
    {
149
        $this->app->singleton('scaffold.model', function ($app) {
150
            if (($finder = app('scaffold.finder'))
151
                && ($id = $app['router']->current()->parameter('id'))
152
            ) {
153
                return $finder->find($id);
154
            }
155
        });
156
    }
157
158
    protected function registerAdminWidgets()
159
    {
160
        $this->app->singleton('scaffold.widgets', function () {
161
            if (($module = app('scaffold.module'))) {
162
                return $module->widgets(new Manager());
0 ignored issues
show
Bug introduced by
The method widgets() does not exist on Illuminate\Foundation\Application. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

162
                return $module->/** @scrutinizer ignore-call */ widgets(new Manager());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
163
            }
164
165
            return new Manager();
166
        });
167
    }
168
169
    protected function registerAdminSchema()
170
    {
171
        $this->app->singleton('scaffold.schema', function ($app) {
172
            if ($schema = $app['db']->connection()->getDoctrineSchemaManager()) {
173
                // fix dbal missing types
174
                $platform = $schema->getDatabasePlatform();
175
                $platform->registerDoctrineTypeMapping('enum', 'string');
176
                $platform->registerDoctrineTypeMapping('set', 'string');
177
178
                return new Schema($schema);
179
            }
180
        });
181
    }
182
183
    protected function registerAdminSortable()
184
    {
185
        $this->app->singleton('scaffold.sortable', function ($app) {
186
            if ($module = $app['scaffold.module']) {
187
                return new Sorter(
188
                    $module instanceof Sortable ? $module->sortable() : [],
189
                    method_exists($module, 'sortDirection') ? $module->sortDirection() : 'desc'
190
                );
191
            }
192
        });
193
    }
194
195
    protected function registerAdminColumns()
196
    {
197
        $this->app->singleton('scaffold.columns', function ($app) {
198
            if ($module = $app['scaffold.module']) {
199
                return $module->columns();
200
            }
201
        });
202
    }
203
204
    protected function registerAdminActions()
205
    {
206
        $this->app->singleton('scaffold.actions', function ($app) {
207
            if ($module = $app['scaffold.module']) {
208
                return $module->actionsManager();
209
            }
210
        });
211
    }
212
213
    protected function registerAdminTemplate()
214
    {
215
        $this->app->singleton('scaffold.template', function ($app) {
216
            // check for resource template
217
            $handler = ($module = $app['scaffold.module']) ? $module->template() : Template::class;
218
            $handler = new $handler();
219
220
            if (!$handler instanceof TemplateProvider) {
221
                throw new Exception('Templates handler must implement '.TemplateProvider::class.' contract');
222
            }
223
224
            return $handler;
225
        });
226
    }
227
228
    protected function registerAdminForm()
229
    {
230
        $this->app->singleton('scaffold.form', function ($app) {
231
            if ($module = $app['scaffold.module']) {
232
                return $module->form();
233
            }
234
        });
235
    }
236
237
    protected function registerAdminFilter()
238
    {
239
        $this->app->singleton('scaffold.filter', function ($app) {
240
            if ($module = $app['scaffold.module']) {
241
                $filters = $module instanceof Filtrable ? $module->filters() : null;
242
                $scopes = $module instanceof Filtrable ? $module->scopes() : null;
243
244
                return new Filter($app['request'], $filters, $scopes);
0 ignored issues
show
Bug introduced by
It seems like $scopes can also be of type array; however, parameter $scopes of Terranet\Administrator\Filter::__construct() does only seem to accept Terranet\Administrator\Collection\Mutable|null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

244
                return new Filter($app['request'], $filters, /** @scrutinizer ignore-type */ $scopes);
Loading history...
Bug introduced by
It seems like $filters can also be of type array; however, parameter $filters of Terranet\Administrator\Filter::__construct() does only seem to accept Terranet\Administrator\Collection\Mutable|null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

244
                return new Filter($app['request'], /** @scrutinizer ignore-type */ $filters, $scopes);
Loading history...
245
            }
246
        });
247
    }
248
249
    protected function registerAdminFinder()
250
    {
251
        $this->app->singleton('scaffold.finder', function ($app) {
252
            if ($module = $app['scaffold.module']) {
253
                // in order to register sortable columns,
254
                // resolve columns service before finder.
255
                $app->make('scaffold.columns');
256
257
                $finder = $module->finder();
258
                $finder = new $finder($module);
259
260
                if (!$finder instanceof Finder) {
261
                    throw new Exception('Items Finder must implement '.Finder::class.' contract');
262
                }
263
264
                return $finder;
265
            }
266
        });
267
    }
268
269
    protected function registerAdminBreadcrumbs()
270
    {
271
        $this->app->singleton('scaffold.breadcrumbs', function ($app) {
272
            if ($module = $app['scaffold.module']) {
273
                $provider = $module->breadcrumbs();
274
275
                return new $provider($app->make('breadcrumbs'), $app->make('scaffold.module'));
276
            }
277
        });
278
    }
279
}
280