Test Failed
Push — master ( fe7900...79d767 )
by Attila
11:12
created

BaseServiceProvider   A

Complexity

Total Complexity 41

Size/Duplication

Total Lines 257
Duplicated Lines 0 %

Importance

Changes 5
Bugs 2 Features 0
Metric Value
wmc 41
eloc 82
c 5
b 2
f 0
dl 0
loc 257
rs 9.1199

18 Methods

Rating   Name   Duplication   Size   Complexity  
A boot() 0 24 5
A __construct() 0 17 1
A register() 0 6 2
A getBasePath() 0 3 1
A registerViews() 0 7 2
A registerEnums() 0 5 3
A getKind() 0 3 1
A getConfigPath() 0 3 1
A loadConfiguration() 0 6 2
A getNamespaceRoot() 0 3 1
A registerModels() 0 5 3
A shortName() 0 6 2
A registerRoutes() 0 10 6
A getId() 0 3 1
A registerMigrations() 0 6 3
A registerEventServiceProvider() 0 10 2
A registerRequestTypes() 0 5 3
A getModuleId() 0 3 2

How to fix   Complexity   

Complex Class

Complex classes like BaseServiceProvider 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 BaseServiceProvider, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Contains the BaseServiceProvider class.
7
 *
8
 * @copyright   Copyright (c) 2016 Attila Fulop
9
 * @author      Attila Fulop
10
 * @license     MIT
11
 * @since       2016-12-29
12
 *
13
 */
14
15
namespace Konekt\Concord;
16
17
use Illuminate\Support\ServiceProvider;
18
use Konekt\Concord\Concerns\HasModuleConfig;
19
use Konekt\Concord\Contracts\Concord as ConcordContract;
20
use Konekt\Concord\Contracts\Convention;
21
use Konekt\Concord\Contracts\Module;
22
use Konekt\Concord\Module\Kind;
23
use Konekt\Concord\Routing\RouteRegistrar;
24
use ReflectionClass;
25
26
abstract class BaseServiceProvider extends ServiceProvider implements Module
27
{
28
    use HasModuleConfig;
29
30
    /** @var  string */
31
    protected $basePath;
32
33
    /** @var  string */
34
    protected $namespaceRoot;
35
36
    /** @var  string */
37
    protected $id;
38
39
    /** @var  array */
40
    protected $models = [];
41
42
    /** @var  array */
43
    protected $enums = [];
44
45
    /** @var  array */
46
    protected $requests = [];
47
48
    /** @var  ConcordContract */
49
    protected $concord;
50
51
    /** @var  Convention */
52
    protected $convention;
53
54
    /** @var  Kind */
55
    protected $kind;
56
57
    /**
58
     * ModuleServiceProvider class constructor
59
     *
60
     * @param \Illuminate\Contracts\Foundation\Application $app
61
     */
62
    public function __construct($app)
63
    {
64
        parent::__construct($app);
65
66
        $this->concord = $app->make(ConcordContract::class); // retrieve the concord singleton
67
        $this->convention = $this->concord->getConvention(); // storing to get rid of train wrecks
68
        $this->kind = Kind::create(static::$_kind);
69
        $this->basePath = dirname(dirname((new ReflectionClass(static::class))->getFileName()));
70
        $this->namespaceRoot = str_replace(
71
            sprintf(
72
                '\\%s\\ModuleServiceProvider',
73
                str_replace('/', '\\', $this->convention->providersFolder())
74
            ),
75
            '',
76
            static::class
77
        );
78
        $this->id = $this->getModuleId();
79
    }
80
81
    public function register()
82
    {
83
        $this->loadConfiguration();
84
85
        if (true === $this->config('event_listeners')) {
86
            $this->registerEventServiceProvider();
87
        }
88
    }
89
90
    /**
91
     * @inheritdoc
92
     */
93
    public function boot()
94
    {
95
        if ($this->areMigrationsEnabled()) {
96
            $this->registerMigrations();
97
        }
98
99
        if ($this->areModelsEnabled()) {
100
            $this->registerModels();
101
            $this->registerEnums();
102
            $this->registerRequestTypes();
103
        }
104
105
        if ($this->areViewsEnabled()) {
106
            $this->registerViews();
107
        }
108
109
        if ($routes = $this->config('routes', true)) {
110
            $this->registerRoutes($routes);
111
        }
112
113
        $this->publishes([
114
            $this->getBasePath() . '/' . $this->convention->migrationsFolder() =>
115
                database_path('migrations')
116
        ], 'migrations');
117
    }
118
119
    public function getId(): string
120
    {
121
        return $this->id;
122
    }
123
124
    /**
125
     * Returns the root folder on the filesystem containing the module
126
     *
127
     * @return string
128
     */
129
    public function getBasePath(): string
130
    {
131
        return $this->basePath;
132
    }
133
134
    /**
135
     * @inheritdoc
136
     */
137
    public function getKind(): Kind
138
    {
139
        return $this->kind;
140
    }
141
142
    /**
143
     * Returns the folder where the module/box configuration files are
144
     *
145
     * @return string
146
     */
147
    public function getConfigPath(): string
148
    {
149
        return $this->getBasePath() . '/' . $this->convention->configFolder();
150
    }
151
152
    /**
153
     * Returns the module's root (topmost) namespace
154
     *
155
     * @return string
156
     */
157
    public function getNamespaceRoot(): string
158
    {
159
        return $this->namespaceRoot;
160
    }
161
162
    /**
163
     * Returns the short (abbreviated) name of the module
164
     * E.g. Konekt\AppShell => app_shell
165
     */
166
    public function shortName()
167
    {
168
        $id = $this->getModuleId();
169
        $p = strrpos($id, '.');
170
171
        return $p ? substr($id, $p + 1) : $id;
172
    }
173
174
    /**
175
     * Returns a standard module name based on the module provider's classname
176
     *
177
     * Eg.: '\Vendor\Module\Services\ModuleServiceProvider' -> 'vendor.module'
178
     *
179
     * @param string    $classname
180
     *
181
     * @see concord_module_id
182
     *
183
     * @return string
184
     */
185
    protected function getModuleId($classname = null)
186
    {
187
        return concord_module_id($classname ?: static::class);
0 ignored issues
show
Bug introduced by
The function concord_module_id was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

187
        return /** @scrutinizer ignore-call */ concord_module_id($classname ?: static::class);
Loading history...
188
    }
189
190
    /**
191
     * Register the module's migrations
192
     */
193
    protected function registerMigrations()
194
    {
195
        $path = $this->getBasePath() . '/' . $this->convention->migrationsFolder();
196
197
        if ($this->app->runningInConsole() && is_dir($path)) {
198
            $this->loadMigrationsFrom($path);
199
        }
200
    }
201
202
    /**
203
     * Register models in a box/module
204
     */
205
    protected function registerModels()
206
    {
207
        foreach ($this->models as $key => $model) {
208
            $contract = is_string($key) ? $key : $this->convention->contractForModel($model);
209
            $this->concord->registerModel($contract, $model, config('concord.register_route_models', true));
210
        }
211
    }
212
213
    /**
214
     * Register enums in a box/module
215
     */
216
    protected function registerEnums()
217
    {
218
        foreach ($this->enums as $key => $enum) {
219
            $contract = is_string($key) ? $key : $this->convention->contractForEnum($enum);
220
            $this->concord->registerEnum($contract, $enum);
221
        }
222
    }
223
224
    /**
225
     * Register request types in a box/module
226
     */
227
    protected function registerRequestTypes()
228
    {
229
        foreach ($this->requests as $key => $requestType) {
230
            $contract = is_string($key) ? $key : $this->convention->contractForRequest($requestType);
231
            $this->concord->registerRequest($contract, $requestType);
232
        }
233
    }
234
235
    /**
236
     * Register the views folder, in a separate namespace
237
     */
238
    protected function registerViews()
239
    {
240
        $path = $this->getBasePath() . '/' . $this->convention->viewsFolder();
241
        $namespace = $this->config('views.namespace', $this->shortName());
242
243
        if (is_dir($path)) {
244
            $this->loadViewsFrom($path, $namespace);
245
        }
246
    }
247
248
    /**
249
     * Registers the event service provider of the module/config (ie. event-listener bindings)
250
     */
251
    protected function registerEventServiceProvider()
252
    {
253
        $eventServiceProviderClass = sprintf(
254
            '%s\\%s\\EventServiceProvider',
255
            $this->namespaceRoot,
256
            str_replace('/', '\\', $this->convention->providersFolder())
257
        );
258
259
        if (class_exists($eventServiceProviderClass)) {
260
            $this->app->register($eventServiceProviderClass);
261
        }
262
    }
263
264
    protected function loadConfiguration()
265
    {
266
        $cfgFile = sprintf('%s/%s', $this->getConfigPath(), $this->configFileName);
267
268
        if (file_exists($cfgFile)) {
269
            $this->mergeConfigFrom($cfgFile, $this->getId());
270
        }
271
    }
272
273
    protected function registerRoutes($routes): void
274
    {
275
        $routeRegistrar = new RouteRegistrar($this, $this->convention);
276
        if (true === $routes) {
277
            $routeRegistrar->registerAllRoutes();
278
        } elseif (isset($routes['files'])) {
279
            $routeRegistrar->registerRoutes($this->config('routes.files'), $this->config('routes'));
280
        } elseif (isset($routes[0]) && is_array($routes[0])) {
281
            foreach ($routes as $route) {
282
                $routeRegistrar->registerRoutes($route['files'], $route);
283
            }
284
        }
285
    }
286
}
287