Passed
Branch master (0c09a6)
by Stephan
01:45
created

SetupAfterCache::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * File holding the SetupAfterCache class
4
 *
5
 * @copyright (C) 2013-2019, Stephan Gambke
6
 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License, version 3 (or later)
7
 *
8
 * This file is part of the MediaWiki extension Bootstrap.
9
 * The Bootstrap extension is free software: you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation, either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * The Bootstrap extension is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 * @file
23
 * @ingroup Bootstrap
24
 */
25
26
namespace Bootstrap\Hooks;
27
28
use RuntimeException;
29
use InvalidArgumentException;
30
31
/**
32
 * Handler for the SetupAfterCache hook.
33
 *
34
 * @see https://www.mediawiki.org/wiki/Manual:Hooks/SetupAfterCache
35
 *
36
 * @since 1.0
37
 *
38
 * @author mwjames
39
 * @author Stephan Gambke
40
 * @ingroup Bootstrap
41
 */
42
class SetupAfterCache {
43
44
	protected $configuration = [];
45
46
	/**
47
	 * @since  1.0
48
	 *
49
	 * @param mixed[] $configuration
50
	 */
51
	public function __construct( array $configuration ) {
52
		$this->configuration = $configuration;
53
	}
54
55
	/**
56
	 * Process the hook
57
	 *
58
	 * @callgraph
59
	 *
60
	 * @since 1.0
61
	 *
62
	 * @throws InvalidArgumentException
63
	 * @throws RuntimeException
64
	 */
65
	public function process() {
66
67
		$this->assertAcceptableConfiguration();
68
69
		$this->registerResourceLoaderModules(
70
			$this->isReadablePath( $this->configuration['localBasePath'] ),
71
			$this->configuration[ 'remoteBasePath' ]
72
		);
73
74
		$this->registerCacheTriggers();
75
76
		return true;
77
	}
78
79
	/**
80
	 * Add paths to resource modules if they are not there yet (e.g. set in LocalSettings.php)
81
	 *
82
	 * @param string $localBasePath
83
	 * @param string $remoteBasePath
84
	 */
85
	protected function registerResourceLoaderModules( $localBasePath, $remoteBasePath ) {
86
87
		$GLOBALS[ 'wgResourceModules' ][ 'ext.bootstrap.styles' ] = array_replace_recursive(
88
			[
89
				'localBasePath' => $localBasePath . '/scss',
90
				'remoteBasePath' => $remoteBasePath . '/scss',
91
				'class' => 'SCSS\\ResourceLoaderSCSSModule',
92
				'position' => 'top',
93
				'styles' => [],
94
				'variables' => [],
95
				'dependencies' => [],
96
				'cacheTriggers' => [
97
					'LocalSettings.php' => null,
98
					'composer.lock' => null,
99
				],
100
			],
101
			$GLOBALS[ 'wgResourceModules' ][ 'ext.bootstrap.styles' ]??[]
102
		);
103
104
		$GLOBALS[ 'wgResourceModules' ][ 'ext.bootstrap.scripts' ] = array_replace_recursive(
105
			[
106
				'localBasePath'  => $localBasePath . '/js',
107
				'remoteBasePath' => $remoteBasePath . '/js',
108
				'scripts' => [],
109
			],
110
			$GLOBALS[ 'wgResourceModules' ][ 'ext.bootstrap.scripts' ]??[]
111
		);
112
113
		$GLOBALS[ 'wgResourceModules' ][ 'ext.bootstrap' ] = [
114
			'dependencies' => [ 'ext.bootstrap.styles', 'ext.bootstrap.scripts' ],
115
		];
116
	}
117
118
	/**
119
	 * @param string $id
120
	 * @return bool
121
	 */
122
	protected function hasConfiguration( $id ) {
123
		return isset( $this->configuration[ $id ] );
124
	}
125
126
	/**
127
	 * @param string $localBasePath
128
	 * @return string
129
	 * @throws RuntimeException
130
	 */
131
	protected function isReadablePath( $localBasePath ) {
132
133
		$localBasePath = str_replace( [ '\\', '/' ], DIRECTORY_SEPARATOR, $localBasePath );
134
135
		if ( is_readable( $localBasePath ) ) {
136
			return $localBasePath;
137
		}
138
139
		throw new RuntimeException( "Expected an accessible {$localBasePath} path" );
140
	}
141
142
	protected function registerCacheTriggers() {
143
144
		$defaultRecacheTriggers = [
145
			'LocalSettings.php' => $this->configuration[ 'IP' ] . '/LocalSettings.php',
146
			'composer.lock' => $this->configuration[ 'IP' ] . '/composer.lock',
147
		];
148
149
		foreach ( $defaultRecacheTriggers as $key => $filename ) {
150
			if ( array_key_exists( $key, $GLOBALS[ 'wgResourceModules' ][ 'ext.bootstrap.styles' ][ 'cacheTriggers' ] ) &&
151
				$GLOBALS[ 'wgResourceModules' ][ 'ext.bootstrap.styles' ][ 'cacheTriggers' ][ $key ] === null ) {
152
				$GLOBALS[ 'wgResourceModules' ][ 'ext.bootstrap.styles' ][ 'cacheTriggers' ][ $key ] = $filename;
153
			}
154
		}
155
	}
156
157
	protected function assertAcceptableConfiguration() {
158
159
		$configElements = [
160
			'localBasePath' => 'Local base path to Bootstrap modules not found.',
161
			'remoteBasePath' => 'Remote base path to Bootstrap modules not found.',
162
			'IP' => 'Full path to working directory ($IP) not found.',
163
		];
164
165
		foreach ( $configElements as $key => $errorMessage ) {
166
			if ( !$this->hasConfiguration( $key ) ) {
167
				throw new InvalidArgumentException( $errorMessage );
168
			}
169
		}
170
	}
171
172
}
173