Completed
Push — dev ( 607387...66849d )
by Marc
02:33
created

ArtificerServiceProvider::addPublishableFiles()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 1 Features 0
Metric Value
c 5
b 1
f 0
dl 0
loc 12
rs 9.4285
cc 1
eloc 8
nc 1
nop 0
1
<?php namespace Mascame\Artificer;
2
3
use App;
4
use Illuminate\Support\ServiceProvider;
5
use Illuminate\Support\Str;
6
use Mascame\Artificer\Extension\Booter;
7
use Mascame\Artificer\Model\ModelManager;
8
use Mascame\Artificer\Model\ModelObtainer;
9
use Mascame\Artificer\Model\ModelSchema;
10
use Mascame\Artificer\Widget\Manager as WidgetManager;
11
use Mascame\Artificer\Plugin\Manager as PluginManager;
12
use Mascame\Extender\Event\Event;
13
use Mascame\Extender\Installer\FileInstaller;
14
use Mascame\Extender\Installer\FileWriter;
15
16
17
class ArtificerServiceProvider extends ServiceProvider {
18
19
	use AutoPublishable, ServiceProviderLoader;
20
	
21
	protected $name = 'admin';
22
23
    protected $corePlugins = [
24
        \Mascame\Artificer\LoginPlugin::class
25
    ];
26
27
	/**
28
	 * Indicates if loading of the provider is deferred.
29
	 *
30
	 * @var bool
31
	 */
32
	protected $defer = false;
33
34
	/**
35
	 * @var bool
36
	 */
37
	protected $isBootable = false;
38
39
	/**
40
	 * Bootstrap the application events.
41
	 *
42
	 * @return void
43
	 */
44
	public function boot()
45
	{
46
		if (! $this->isBootable) return;
47
		
48
		$this->addPublishableFiles();
49
50
		// Wait until app is ready for config to be published
51
		if (! $this->isPublished()) return;
52
53
		$this->providers(config('admin.providers'));
54
		$this->aliases(config('admin.aliases'));
55
		$this->commands(config('admin.commands'));
56
57
        Artificer::pluginManager()->boot();
58
        Artificer::widgetManager()->boot();
59
60
        $this->manageCorePlugins();
61
62
        Artificer::assetManager()->add(config('admin.assets', []));
63
64
        $this->requireFiles();
65
	}
66
67
    /**
68
     * Ensure core plugins are installed
69
     *
70
     * @throws \Exception
71
     */
72
	protected function manageCorePlugins() {
73
	    // Avoid installing plugins when using CLI
74
        if (App::runningInConsole() || App::runningUnitTests()) return true;
75
76
        $pluginManager = Artificer::pluginManager();
77
        $needsRefresh = false;
78
79
        foreach ($this->corePlugins as $corePlugin) {
80
            if (! $pluginManager->isInstalled($corePlugin)) {
81
                $installed = $pluginManager->installer()->install($corePlugin);
82
83
                if (! $installed) {
84
                    throw new \Exception("Unable to install Artificer core plugin {$corePlugin}");
85
                }
86
87
                $needsRefresh = true;
88
            }
89
        }
90
91
        // Refresh to allow changes made by core plugins to take effect
92
        if ($needsRefresh) {
93
            /**
94
             * File driver is slow... wait some seconds (else we would have too many redirects)
95
             *
96
             * Fortunately we only do this in the first run. Ye, I don't like it either.
97
             */
98
            sleep(2);
99
100
            header('Location: '. \URL::current());
101
            die();
102
        }
103
    }
104
105
    /**
106
     * Determines if is on admin
107
     *
108
     * @return bool
109
     */
110
    public function isBootable($path, $routePrefix = null) {
111
        if (App::runningInConsole() || App::runningUnitTests()) return true;
112
113
        return (
114
            $path == $routePrefix || Str::startsWith($path, $routePrefix . '/')
115
        );
116
    }
117
118
	private function requireFiles()
119
	{
120
		require_once __DIR__ . '/../routes/admin.php';
121
	}
122
123
	protected function getConfigPath() {
124
		return config_path($this->name) . DIRECTORY_SEPARATOR;
125
	}
126
127
	private function addPublishableFiles()
128
    {
129
		$this->publishes([
130
			__DIR__.'/../resources/assets' => public_path('packages/mascame/' . $this->name),
131
		], 'public');
132
133
        $this->publishes([
134
            __DIR__.'/../config/' => $this->getConfigPath(),
135
        ], 'config');
136
137
        $this->loadTranslationsFrom(__DIR__.'/../resources/lang', $this->name);
138
    }
139
140
	private function addLocalization()
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
141
	{
142
		App::singleton('ArtificerLocalization', function () {
143
			return new Localization();
144
		});
145
	}
146
147
	private function getExtensionInstaller($type) {
148
        if (config('admin.extension_driver') == 'file') {
149
            $extensionConfig = $this->getConfigPath() . 'extensions/'. $type .'.php';
150
151
            return new FileInstaller(new FileWriter(), $extensionConfig);
152
        }
153
    }
154
155
	private function addManagers()
156
	{
157
        App::singleton('ArtificerModelManager', function () {
158
            return new ModelManager(new ModelSchema(new ModelObtainer()));
159
        });
160
161
		App::singleton('ArtificerWidgetManager', function() {
162
            return new WidgetManager(
163
                $this->getExtensionInstaller('widgets'),
0 ignored issues
show
Bug introduced by
It seems like $this->getExtensionInstaller('widgets') can be null; however, __construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
164
                new Booter(),
165
                new Event(app('events'))
166
            );
167
        });
168
169
		App::singleton('ArtificerPluginManager', function() {
170
            return new PluginManager(
171
                $this->getExtensionInstaller('plugins'),
0 ignored issues
show
Bug introduced by
It seems like $this->getExtensionInstaller('plugins') can be null; however, __construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
172
                new \Mascame\Artificer\Plugin\Booter(),
173
                new Event(app('events'))
174
            );
175
		});
176
177
        App::singleton('ArtificerAssetManager', function() {
178
            return \Assets::config(array_merge([
179
                // Reset those dirs to avoid wrong paths
180
                'css_dir' => '',
181
                'js_dir' => '',
182
            ], config('admin.assets')));
183
        });
184
	}
185
186
	/**
187
	 * Register the service provider.
188
	 *
189
	 * @return void
190
	 */
191
	public function register()
192
	{
193
		// We still haven't modified config, that's why 'admin.admin'
194
		$routePrefix = config('admin.admin.route_prefix');
195
196
		// Avoid bloating the App with files that will not be needed
197
		$this->isBootable = $this->isBootable(request()->path(), $routePrefix);
198
199
		if (! $this->isBootable) return;
200
201
		// We need the config published before we can use this package!
202
		if ($this->isPublished()) {
203
			$this->loadConfig();
204
205
            // Todo
206
//			$this->addLocalization();
207
			$this->addManagers();
208
		}
209
	}
210
211
	/**
212
	 * Moves admin/admin.php keys to the root level for commodity
213
	 */
214
	protected function loadConfig() {
215
		$config = config('admin');
216
		$config = ['admin' => array_merge($config, $config['admin'])];
217
		unset($config['admin']['admin']);
218
219
		config()->set($config);
220
	}
221
222
	/**
223
	 * Get the services provided by the provider.
224
	 *
225
	 * @return array
226
	 */
227
	public function provides()
228
	{
229
		return [];
230
	}
231
232
}
233