LockManagerGroup::getDefault()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Lock manager registration handling.
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License along
16
 * with this program; if not, write to the Free Software Foundation, Inc.,
17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
 * http://www.gnu.org/copyleft/gpl.html
19
 *
20
 * @file
21
 * @ingroup LockManager
22
 */
23
use MediaWiki\MediaWikiServices;
24
use MediaWiki\Logger\LoggerFactory;
25
26
/**
27
 * Class to handle file lock manager registration
28
 *
29
 * @ingroup LockManager
30
 * @author Aaron Schulz
31
 * @since 1.19
32
 */
33
class LockManagerGroup {
34
	/** @var LockManagerGroup[] (domain => LockManagerGroup) */
35
	protected static $instances = [];
36
37
	protected $domain; // string; domain (usually wiki ID)
38
39
	/** @var array Array of (name => ('class' => ..., 'config' => ..., 'instance' => ...)) */
40
	protected $managers = [];
41
42
	/**
43
	 * @param string $domain Domain (usually wiki ID)
44
	 */
45
	protected function __construct( $domain ) {
46
		$this->domain = $domain;
47
	}
48
49
	/**
50
	 * @param bool|string $domain Domain (usually wiki ID). Default: false.
51
	 * @return LockManagerGroup
52
	 */
53 View Code Duplication
	public static function singleton( $domain = false ) {
54
		$domain = ( $domain === false ) ? wfWikiID() : $domain;
55
		if ( !isset( self::$instances[$domain] ) ) {
56
			self::$instances[$domain] = new self( $domain );
0 ignored issues
show
Bug introduced by
It seems like $domain defined by $domain === false ? wfWikiID() : $domain on line 54 can also be of type boolean; however, LockManagerGroup::__construct() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
57
			self::$instances[$domain]->initFromGlobals();
58
		}
59
60
		return self::$instances[$domain];
61
	}
62
63
	/**
64
	 * Destroy the singleton instances
65
	 */
66
	public static function destroySingletons() {
67
		self::$instances = [];
68
	}
69
70
	/**
71
	 * Register lock managers from the global variables
72
	 */
73
	protected function initFromGlobals() {
74
		global $wgLockManagers;
75
76
		$this->register( $wgLockManagers );
77
	}
78
79
	/**
80
	 * Register an array of file lock manager configurations
81
	 *
82
	 * @param array $configs
83
	 * @throws Exception
84
	 */
85
	protected function register( array $configs ) {
86
		foreach ( $configs as $config ) {
87
			$config['domain'] = $this->domain;
88
			if ( !isset( $config['name'] ) ) {
89
				throw new Exception( "Cannot register a lock manager with no name." );
90
			}
91
			$name = $config['name'];
92
			if ( !isset( $config['class'] ) ) {
93
				throw new Exception( "Cannot register lock manager `{$name}` with no class." );
94
			}
95
			$class = $config['class'];
96
			unset( $config['class'] ); // lock manager won't need this
97
			$this->managers[$name] = [
98
				'class' => $class,
99
				'config' => $config,
100
				'instance' => null
101
			];
102
		}
103
	}
104
105
	/**
106
	 * Get the lock manager object with a given name
107
	 *
108
	 * @param string $name
109
	 * @return LockManager
110
	 * @throws Exception
111
	 */
112
	public function get( $name ) {
113
		if ( !isset( $this->managers[$name] ) ) {
114
			throw new Exception( "No lock manager defined with the name `$name`." );
115
		}
116
		// Lazy-load the actual lock manager instance
117
		if ( !isset( $this->managers[$name]['instance'] ) ) {
118
			$class = $this->managers[$name]['class'];
119
			$config = $this->managers[$name]['config'];
120
			if ( $class === 'DBLockManager' ) {
121
				$lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
122
				$lb = $lbFactory->newMainLB( $config['domain'] );
123
				$dbw = $lb->getLazyConnectionRef( DB_MASTER, [], $config['domain'] );
124
125
				$config['dbServers']['localDBMaster'] = $dbw;
126
				$config['srvCache'] = ObjectCache::getLocalServerInstance( 'hash' );
127
			}
128
			$config['logger'] = LoggerFactory::getInstance( 'LockManager' );
129
130
			$this->managers[$name]['instance'] = new $class( $config );
131
		}
132
133
		return $this->managers[$name]['instance'];
134
	}
135
136
	/**
137
	 * Get the config array for a lock manager object with a given name
138
	 *
139
	 * @param string $name
140
	 * @return array
141
	 * @throws Exception
142
	 */
143
	public function config( $name ) {
144
		if ( !isset( $this->managers[$name] ) ) {
145
			throw new Exception( "No lock manager defined with the name `$name`." );
146
		}
147
		$class = $this->managers[$name]['class'];
148
149
		return [ 'class' => $class ] + $this->managers[$name]['config'];
150
	}
151
152
	/**
153
	 * Get the default lock manager configured for the site.
154
	 * Returns NullLockManager if no lock manager could be found.
155
	 *
156
	 * @return LockManager
157
	 */
158
	public function getDefault() {
159
		return isset( $this->managers['default'] )
160
			? $this->get( 'default' )
161
			: new NullLockManager( [] );
162
	}
163
164
	/**
165
	 * Get the default lock manager configured for the site
166
	 * or at least some other effective configured lock manager.
167
	 * Throws an exception if no lock manager could be found.
168
	 *
169
	 * @return LockManager
170
	 * @throws Exception
171
	 */
172
	public function getAny() {
173
		return isset( $this->managers['default'] )
174
			? $this->get( 'default' )
175
			: $this->get( 'fsLockManager' );
176
	}
177
}
178