Completed
Push — develop ( 5e199b...b70cbe )
by Nicolas
02:56
created

CoreServiceProvider::registerLanguageNamespace()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 1 Features 1
Metric Value
c 5
b 1
f 1
dl 0
loc 21
rs 8.7624
cc 5
eloc 13
nc 5
nop 1
1
<?php namespace Modules\Core\Providers;
2
3
use Illuminate\Contracts\Bus\Dispatcher;
4
use Illuminate\Routing\Router;
5
use Illuminate\Support\Facades\DB;
6
use Illuminate\Support\Facades\Schema;
7
use Illuminate\Support\ServiceProvider;
8
use Maatwebsite\Sidebar\SidebarManager;
9
use Modules\Core\Console\PublishModuleAssetsCommand;
10
use Modules\Core\Console\PublishThemeAssetsCommand;
11
use Modules\Core\Foundation\Theme\ThemeManager;
12
use Modules\Core\Sidebar\AdminSidebar;
13
use Pingpong\Modules\Module;
14
15
class CoreServiceProvider extends ServiceProvider
16
{
17
    /**
18
     * Indicates if loading of the provider is deferred.
19
     *
20
     * @var bool
21
     */
22
    protected $defer = false;
23
24
    /**
25
     * @var string
26
     */
27
    protected $prefix = 'asgard';
28
29
    /**
30
     * The filters base class name.
31
     *
32
     * @var array
33
     */
34
    protected $middleware = [
35
        'Core' => [
36
            'permissions'           => 'PermissionMiddleware',
37
            'auth.admin'            => 'AdminMiddleware',
38
            'public.checkLocale'    => 'PublicMiddleware',
39
            'localizationRedirect'  => 'LocalizationMiddleware',
40
        ],
41
    ];
42
43
    public function boot(Dispatcher $dispatcher, SidebarManager $manager)
44
    {
45
        $dispatcher->mapUsing(function ($command) {
46
            $command = str_replace('Commands\\', 'Commands\\Handlers\\', get_class($command));
47
48
            return trim($command, '\\') . 'Handler@handle';
49
        });
50
51
        $manager->register(AdminSidebar::class);
52
53
        $this->registerMiddleware($this->app['router']);
54
        $this->registerModuleResourceNamespaces();
55
        $this->setLocalesConfigurations();
56
    }
57
58
    /**
59
     * Register the service provider.
60
     *
61
     * @return void
62
     */
63
    public function register()
64
    {
65
        $this->app->singleton('asgard.isInstalled', function ($app) {
66
            try {
67
                $hasTable = Schema::hasTable('setting__settings');
68
            } catch (\Exception $e) {
69
                $hasTable = false;
70
            }
71
72
            return $app['files']->isFile(base_path('.env')) && $hasTable;
73
        });
74
75
        $this->registerCommands();
76
        $this->registerServices();
77
    }
78
79
    /**
80
     * Get the services provided by the provider.
81
     *
82
     * @return array
83
     */
84
    public function provides()
85
    {
86
        return array();
87
    }
88
89
    /**
90
     * Register the filters.
91
     *
92
     * @param  Router $router
93
     * @return void
94
     */
95
    public function registerMiddleware(Router $router)
96
    {
97
        foreach ($this->middleware as $module => $middlewares) {
98
            foreach ($middlewares as $name => $middleware) {
99
                $class = "Modules\\{$module}\\Http\\Middleware\\{$middleware}";
100
101
                $router->middleware($name, $class);
102
            }
103
        }
104
    }
105
106
    /**
107
     * Register the console commands
108
     */
109
    private function registerCommands()
110
    {
111
        $this->registerInstallCommand();
112
        $this->registerThemeCommand();
113
        $this->registerPublishModuleAssetsCommand();
114
115
        $this->commands([
116
            'command.asgard.install',
117
            'command.asgard.publish.theme',
118
            'command.asgard.publish.module.assets',
119
        ]);
120
    }
121
122
    /**
123
     * Register the installation command
124
     */
125
    private function registerInstallCommand()
126
    {
127
        $this->app->bind(
128
            'command.asgard.install',
129
            'Modules\Core\Console\InstallCommand'
130
        );
131
    }
132
133
    private function registerThemeCommand()
134
    {
135
        $this->app->bindShared('command.asgard.publish.theme', function ($app) {
136
            return new PublishThemeAssetsCommand(new ThemeManager($app, $app['config']->get('themify.themes_path')));
0 ignored issues
show
Unused Code introduced by
The call to PublishThemeAssetsCommand::__construct() has too many arguments starting with new \Modules\Core\Founda...'themify.themes_path')).

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
137
        });
138
    }
139
140
    private function registerPublishModuleAssetsCommand()
141
    {
142
        $this->app->bindShared('command.asgard.publish.module.assets', function () {
143
            return new PublishModuleAssetsCommand();
144
        });
145
    }
146
147
    private function registerServices()
148
    {
149
        $this->app->bindShared('Modules\Core\Foundation\Theme\ThemeManager', function ($app) {
150
            $path = $app['config']->get('asgard.core.core.themes_path');
151
152
            return new ThemeManager($app, $path);
153
        });
154
    }
155
156
    /**
157
     * Register the modules aliases
158
     */
159
    private function registerModuleResourceNamespaces()
160
    {
161
        foreach ($this->app['modules']->getOrdered() as $module) {
162
            $this->registerViewNamespace($module);
163
            $this->registerLanguageNamespace($module);
164
            $this->registerConfigNamespace($module);
165
        }
166
    }
167
168
    /**
169
     * Register the view namespaces for the modules
170
     * @param Module $module
171
     */
172
    protected function registerViewNamespace(Module $module)
173
    {
174
        if ($module->getName() == 'user') {
175
            return;
176
        }
177
        $this->app['view']->addNamespace(
178
            $module->getName(),
179
            $module->getPath() . '/Resources/views'
180
        );
181
    }
182
183
    /**
184
     * Register the language namespaces for the modules
185
     * @param Module $module
186
     */
187
    protected function registerLanguageNamespace(Module $module)
188
    {
189
        $moduleName = $module->getName();
190
191
        $langPath = base_path("resources/lang/$moduleName");
192
        $secondPath = base_path("resources/lang/translation/$moduleName");
193
194
        if ($moduleName === 'translation') {
195
            return $this->loadTranslationsFrom($langPath . '/translation', $moduleName);
196
        }
197
        if ($this->hasPublishedTranslations($langPath)) {
198
            return $this->loadTranslationsFrom($langPath, $moduleName);
199
        }
200
        if ($this->hasPublishedTranslations($secondPath)) {
201
            return $this->loadTranslationsFrom($secondPath, $moduleName);
202
        }
203
        if ($this->moduleHasCentralisedTranslations($module)) {
204
            return $this->loadTranslationsFrom($this->getCentralisedTranslationPath($module), $moduleName);
205
        }
206
        return $this->loadTranslationsFrom($module->getPath() . '/Resources/lang', $moduleName);
207
    }
208
209
    /**
210
     * Register the config namespace
211
     * @param Module $module
212
     */
213
    private function registerConfigNamespace(Module $module)
214
    {
215
        $files = $this->app['files']->files($module->getPath() . '/Config');
216
217
        $package = $module->getName();
218
219
        foreach ($files as $file) {
220
            $filename = $this->getConfigFilename($file, $package);
221
222
            $this->mergeConfigFrom(
223
                $file,
224
                $filename
225
            );
226
227
            $this->publishes([
228
                $file => config_path($filename . '.php'),
229
            ], 'config');
230
        }
231
    }
232
233
    /**
234
     * @param $file
235
     * @param $package
236
     * @return string
237
     */
238
    private function getConfigFilename($file, $package)
239
    {
240
        $name = preg_replace('/\\.[^.\\s]{3,4}$/', '', basename($file));
241
242
        $filename = $this->prefix . '.' . $package . '.' . $name;
243
244
        return $filename;
245
    }
246
247
    /**
248
     * Set the locale configuration for
249
     * - laravel localization
250
     * - laravel translatable
251
     */
252
    private function setLocalesConfigurations()
253
    {
254
        if (! $this->app['asgard.isInstalled']) {
255
            return;
256
        }
257
258
        $localeConfig = $this->app['cache']
259
            ->tags('setting.settings', 'global')
260
            ->remember("asgard.locales", 120,
261
                function () {
262
                    return DB::table('setting__settings')->whereName('core::locales')->first();
263
                }
264
            );
265
266
        if ($localeConfig) {
267
            $locales = json_decode($localeConfig->plainValue);
268
            $availableLocales = [];
269
            foreach ($locales as $locale) {
270
                $availableLocales = array_merge($availableLocales, [$locale => config("asgard.core.available-locales.$locale")]);
271
            }
272
273
            $laravelDefaultLocale = $this->app->config->get('app.locale');
0 ignored issues
show
Bug introduced by
Accessing config on the interface Illuminate\Contracts\Foundation\Application suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
274
            if (! in_array($laravelDefaultLocale, array_keys($availableLocales))) {
275
                $this->app->config->set('app.locale', array_keys($availableLocales)[0]);
0 ignored issues
show
Bug introduced by
Accessing config on the interface Illuminate\Contracts\Foundation\Application suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
276
            }
277
            $this->app->config->set('laravellocalization.supportedLocales', $availableLocales);
0 ignored issues
show
Bug introduced by
Accessing config on the interface Illuminate\Contracts\Foundation\Application suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
278
            $this->app->config->set('translatable.locales', $locales);
0 ignored issues
show
Bug introduced by
Accessing config on the interface Illuminate\Contracts\Foundation\Application suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
279
        }
280
    }
281
282
    /**
283
     * @param string $path
284
     * @return bool
285
     */
286
    private function hasPublishedTranslations($path)
287
    {
288
        return is_dir($path);
289
    }
290
291
    /**
292
     * Does a Module have it's Translations centralised in the Translation module?
293
     * @param Module $module
294
     * @return bool
295
     */
296
    private function moduleHasCentralisedTranslations(Module $module)
297
    {
298
        if (! array_has($this->app['modules']->enabled(), 'Translation')) {
299
            return false;
300
        }
301
302
        return is_dir($this->getCentralisedTranslationPath($module));
303
    }
304
305
    /**
306
     * Get the absolute path to the Centralised Translations for a Module (via the Translations module)
307
     * @param Module $module
308
     * @return string
309
     */
310
    private function getCentralisedTranslationPath(Module $module)
311
    {
312
        return $this->app['modules']->find('Translation')->getPath() . "/Resources/lang/{$module->getName()}";
313
    }
314
}
315
316