Completed
Push — master ( b79151...a6cb7c )
by mw
91:56 queued 61:51
created

ApplicationFactory::getLoadBalancer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SMW;
4
5
use Closure;
6
use Onoi\CallbackContainer\CallbackLoader;
7
use Onoi\CallbackContainer\DeferredCallbackLoader;
8
use Parser;
9
use ParserOutput;
10
use SMW\Factbox\FactboxFactory;
11
use SMW\Maintenance\MaintenanceFactory;
12
use SMW\MediaWiki\Jobs\JobFactory;
13
use SMW\MediaWiki\MwCollaboratorFactory;
14
use SMW\MediaWiki\PageCreator;
15
use SMW\MediaWiki\TitleCreator;
16
use SMW\Query\ProfileAnnotator\QueryProfileAnnotatorFactory;
17
use SMWQueryParser as QueryParser;
18
use Title;
19
20
/**
21
 * Application instances access for internal and external use
22
 *
23
 * @license GNU GPL v2+
24
 * @since 2.0
25
 *
26
 * @author mwjames
27
 */
28
class ApplicationFactory {
29
30
	/**
31
	 * @var ApplicationFactory
32
	 */
33
	private static $instance = null;
34
35
	/**
36
	 * @var CallbackLoader
37
	 */
38
	private $callbackLoader = null;
39
40
	/**
41
	 * @since 2.0
42
	 */
43 321
	public function __construct( CallbackLoader $callbackLoader = null ) {
44 321
		$this->callbackLoader = $callbackLoader;
45 321
	}
46
47
	/**
48
	 * This method returns the global instance of the application factory.
49
	 *
50
	 * Reliance on global state is needed at entry points into SMW such as
51
	 * hook handlers, special pages and jobs, since there we tend to not
52
	 * have control over the object lifecycle. Pragmatically we might also
53
	 * want to use this when refactoring legacy code that already has the
54
	 * global state dependency. For new code very special justification is
55
	 * required to rely on global state.
56
	 *
57
	 * @since 2.0
58
	 *
59
	 * @return self
60
	 */
61 355
	public static function getInstance() {
62
63 355
		if ( self::$instance === null ) {
64 321
			self::$instance = new self( self::registerBuilder() );
65
		}
66
67 355
		return self::$instance;
68
	}
69
70
	/**
71
	 * @since 2.0
72
	 */
73 344
	public static function clear() {
74
75 344
		if ( self::$instance !== null ) {
76 344
			self::$instance->getSettings()->clear();
77
		}
78
79 344
		self::$instance = null;
80 344
	}
81
82
	/**
83
	 * @since 2.0
84
	 *
85
	 * @param string $objectName
86
	 * @param callable|array $objectSignature
87
	 */
88 298
	public function registerObject( $objectName, $objectSignature ) {
89 298
		$this->callbackLoader->registerObject( $objectName, $objectSignature );
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Onoi\CallbackContainer\CallbackLoader as the method registerObject() does only exist in the following implementations of said interface: Onoi\CallbackContainer\DeferredCallbackLoader.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
90 298
	}
91
92
	/**
93
	 * @private
94
	 *
95
	 * @since 2.4
96
	 *
97
	 * @return CallbackLoader
98
	 */
99 296
	public function getCallbackInstantiator() {
100 296
		return $this->callbackLoader;
101
	}
102
103
	/**
104
	 * @since 2.0
105
	 *
106
	 * @return SerializerFactory
107
	 */
108 208
	public function newSerializerFactory() {
109 208
		return new SerializerFactory();
110
	}
111
112
	/**
113
	 * @since 2.0
114
	 *
115
	 * @return FactboxFactory
116
	 */
117 4
	public function newFactboxFactory() {
118 4
		return $this->callbackLoader->load( 'FactboxFactory' );
0 ignored issues
show
Deprecated Code introduced by
The method Onoi\CallbackContainer\CallbackLoader::load() has been deprecated with message: since 1.1, use CallbackInstantiator::create

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
119
	}
120
121
	/**
122
	 * @since 2.0
123
	 *
124
	 * @return PropertyAnnotatorFactory
125
	 */
126 197
	public function getPropertyAnnotatorFactory() {
127 197
		return $this->callbackLoader->singleton( 'PropertyAnnotatorFactory' );
128
	}
129
130
	/**
131
	 * @since 2.0
132
	 *
133
	 * @return JobFactory
134
	 */
135 211
	public function newJobFactory() {
136 211
		return $this->callbackLoader->load( 'JobFactory' );
0 ignored issues
show
Deprecated Code introduced by
The method Onoi\CallbackContainer\CallbackLoader::load() has been deprecated with message: since 1.1, use CallbackInstantiator::create

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
137
	}
138
139
	/**
140
	 * @since 2.1
141
	 *
142
	 * @param Parser $parser
143
	 *
144
	 * @return ParserFunctionFactory
145
	 */
146 15
	public function newParserFunctionFactory( Parser $parser ) {
147 15
		return new ParserFunctionFactory( $parser );
148
	}
149
150
	/**
151
	 * @since 2.2
152
	 *
153
	 * @return MaintenanceFactory
154
	 */
155 9
	public function newMaintenanceFactory() {
156 9
		return new MaintenanceFactory();
157
	}
158
159
	/**
160
	 * @since 2.2
161
	 *
162
	 * @return CacheFactory
163
	 */
164 280
	public function newCacheFactory() {
165 280
		return $this->callbackLoader->load( 'CacheFactory', $this->getSettings()->get( 'smwgCacheType' ) );
0 ignored issues
show
Unused Code introduced by
The call to CallbackLoader::load() has too many arguments starting with $this->getSettings()->get('smwgCacheType').

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...
Deprecated Code introduced by
The method Onoi\CallbackContainer\CallbackLoader::load() has been deprecated with message: since 1.1, use CallbackInstantiator::create

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
166
	}
167
168
	/**
169
	 * @since 2.5
170
	 *
171
	 * @param string|null $source
172
	 *
173
	 * @return QueryEngine
174
	 */
175 82
	public function getQuerySource( $source = null ) {
176 82
		return $this->callbackLoader->singleton( 'QuerySourceFactory' )->getWithLocalFallback( $source );
177
	}
178
179
	/**
180
	 * @since 2.0
181
	 *
182
	 * @return Store
183
	 */
184 297
	public function getStore( $store = null ) {
185 297
		return $this->callbackLoader->singleton( 'Store', $store );
0 ignored issues
show
Unused Code introduced by
The call to CallbackLoader::singleton() has too many arguments starting with $store.

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...
186
	}
187
188
	/**
189
	 * @since 2.0
190
	 *
191
	 * @return Settings
192
	 */
193 349
	public function getSettings() {
194 349
		return $this->callbackLoader->singleton( 'Settings' );
195
	}
196
197
	/**
198
	 * @since 2.0
199
	 *
200
	 * @return TitleCreator
201
	 */
202 6
	public function newTitleCreator() {
203 6
		return $this->callbackLoader->load( 'TitleCreator', $this->newPageCreator() );
0 ignored issues
show
Unused Code introduced by
The call to CallbackLoader::load() has too many arguments starting with $this->newPageCreator().

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...
Deprecated Code introduced by
The method Onoi\CallbackContainer\CallbackLoader::load() has been deprecated with message: since 1.1, use CallbackInstantiator::create

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
204
	}
205
206
	/**
207
	 * @since 2.0
208
	 *
209
	 * @return PageCreator
210
	 */
211 201
	public function newPageCreator() {
212 201
		return $this->callbackLoader->load( 'PageCreator' );
0 ignored issues
show
Deprecated Code introduced by
The method Onoi\CallbackContainer\CallbackLoader::load() has been deprecated with message: since 1.1, use CallbackInstantiator::create

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
213
	}
214
215
	/**
216
	 * @since 2.5
217
	 *
218
	 * @return IteratorFactory
219
	 */
220 11
	public function getIteratorFactory() {
221 11
		return $this->callbackLoader->singleton( 'IteratorFactory' );
222
	}
223
224
	/**
225
	 * @since 2.5
226
	 *
227
	 * @return DataValueFactory
228
	 */
229 6
	public function getDataValueFactory() {
230 6
		return DataValueFactory::getInstance();
231
	}
232
233
	/**
234
	 * @since 2.0
235
	 *
236
	 * @return Cache
237
	 */
238 188
	public function getCache() {
239 188
		return $this->callbackLoader->singleton( 'Cache' );
240
	}
241
242
	/**
243
	 * @since 2.0
244
	 *
245
	 * @return InTextAnnotationParser
246
	 */
247 195
	public function newInTextAnnotationParser( ParserData $parserData ) {
248
249 195
		$mwCollaboratorFactory = $this->newMwCollaboratorFactory();
250
251 195
		$inTextAnnotationParser = new InTextAnnotationParser(
252
			$parserData,
253 195
			$mwCollaboratorFactory->newMagicWordsFinder(),
254 195
			$mwCollaboratorFactory->newRedirectTargetFinder()
255
		);
256
257 195
		$inTextAnnotationParser->setStrictModeState(
258 195
			$this->getSettings()->get( 'smwgEnabledInTextAnnotationParserStrictMode' )
259
		);
260
261 195
		return $inTextAnnotationParser;
262
	}
263
264
	/**
265
	 * @since 2.0
266
	 *
267
	 * @return ParserData
268
	 */
269 211
	public function newParserData( Title $title, ParserOutput $parserOutput ) {
270 211
		return $this->callbackLoader->load( 'ParserData', $title, $parserOutput );
0 ignored issues
show
Unused Code introduced by
The call to CallbackLoader::load() has too many arguments starting with $title.

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...
Deprecated Code introduced by
The method Onoi\CallbackContainer\CallbackLoader::load() has been deprecated with message: since 1.1, use CallbackInstantiator::create

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
271
	}
272
273
	/**
274
	 * @since 2.0
275
	 *
276
	 * @return ContentParser
277
	 */
278 29
	public function newContentParser( Title $title ) {
279 29
		return $this->callbackLoader->load( 'ContentParser', $title );
0 ignored issues
show
Unused Code introduced by
The call to CallbackLoader::load() has too many arguments starting with $title.

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...
Deprecated Code introduced by
The method Onoi\CallbackContainer\CallbackLoader::load() has been deprecated with message: since 1.1, use CallbackInstantiator::create

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
280
	}
281
282
	/**
283
	 * @since 2.1
284
	 *
285
	 * @param SemanticData $semanticData
286
	 *
287
	 * @return StoreUpdater
288
	 */
289 197
	public function newStoreUpdater( SemanticData $semanticData ) {
290 197
		return new StoreUpdater( $this->getStore(), $semanticData );
291
	}
292
293
	/**
294
	 * @since 2.1
295
	 *
296
	 * @return MwCollaboratorFactory
297
	 */
298 249
	public function newMwCollaboratorFactory() {
299 249
		return new MwCollaboratorFactory( $this );
300
	}
301
302
	/**
303
	 * @since 2.1
304
	 *
305
	 * @return NamespaceExaminer
306
	 */
307 198
	public function getNamespaceExaminer() {
308 198
		return $this->callbackLoader->load( 'NamespaceExaminer' );
0 ignored issues
show
Deprecated Code introduced by
The method Onoi\CallbackContainer\CallbackLoader::load() has been deprecated with message: since 1.1, use CallbackInstantiator::create

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
309
	}
310
311
	/**
312
	 * @since 2.4
313
	 *
314
	 * @return PropertySpecificationLookup
315
	 */
316 222
	public function getPropertySpecificationLookup() {
317 222
		return $this->callbackLoader->singleton( 'PropertySpecificationLookup' );
318
	}
319
320
	/**
321
	 * @since 2.4
322
	 *
323
	 * @return PropertyHierarchyLookup
324
	 */
325 120
	public function newPropertyHierarchyLookup() {
326 120
		return $this->callbackLoader->load( 'PropertyHierarchyLookup' );
0 ignored issues
show
Deprecated Code introduced by
The method Onoi\CallbackContainer\CallbackLoader::load() has been deprecated with message: since 1.1, use CallbackInstantiator::create

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
327
	}
328
329
	/**
330
	 * @since 2.5
331
	 *
332
	 * @return PropertyLabelFinder
333
	 */
334 258
	public function newPropertyLabelFinder() {
335 258
		return $this->callbackLoader->create( 'PropertyLabelFinder' );
336
	}
337
338
	/**
339
	 * @since 2.4
340
	 *
341
	 * @return CachedPropertyValuesPrefetcher
342
	 */
343 239
	public function getCachedPropertyValuesPrefetcher() {
344 239
		return $this->callbackLoader->singleton( 'CachedPropertyValuesPrefetcher' );
345
	}
346
347
	/**
348
	 * @since 2.4
349
	 *
350
	 * @return MediaWikiNsContentReader
351
	 */
352 219
	public function getMediaWikiNsContentReader() {
353 219
		return $this->callbackLoader->singleton( 'MediaWikiNsContentReader' );
354
	}
355
356
	/**
357
	 * @since 2.4
358
	 *
359
	 * @return InMemoryPoolCache
360
	 */
361 282
	public function getInMemoryPoolCache() {
362 282
		return $this->callbackLoader->singleton( 'InMemoryPoolCache' );
363
	}
364
365
	/**
366
	 * @since 2.5
367
	 *
368
	 * @return \LoadBalancer
369
	 */
370 1
	public function getLoadBalancer() {
371 1
		return $this->callbackLoader->singleton( 'DBLoadBalancer' );
372
	}
373
374
	/**
375
	 * @since 2.5
376
	 *
377
	 * @param \IDatabase $db
378
	 * @return string
379
	 */
380 1
	public function getDefaultSearchEngineTypeForDB( \IDatabase $db ) {
381 1
		return $this->callbackLoader->create( 'DefaultSearchEngineTypeForDB', $db );
0 ignored issues
show
Unused Code introduced by
The call to CallbackLoader::create() has too many arguments starting with $db.

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...
382
383
	}
384
385
	/**
386
	 * @since 2.4
387
	 *
388
	 * @param Closure $callback
389
	 *
390
	 * @return DeferredCallableUpdate
391
	 */
392 247
	public function newDeferredCallableUpdate( Closure $callback ) {
393
394 247
		$deferredCallableUpdate = $this->callbackLoader->create(
395 247
			'DeferredCallableUpdate',
396
			$callback
0 ignored issues
show
Unused Code introduced by
The call to CallbackLoader::create() has too many arguments starting with $callback.

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...
397
		);
398
399 247
		$deferredCallableUpdate->enabledDeferredUpdate(
400 247
			$this->getSettings()->get( 'smwgEnabledDeferredUpdate' )
401
		);
402
403 247
		return $deferredCallableUpdate;
404
	}
405
406
	/**
407
	 * @deprecated since 2.5, use QueryFactory::newQueryParser
408
	 * @since 2.1
409
	 *
410
	 * @return QueryParser
411
	 */
412
	public function newQueryParser() {
413
		return $this->getQueryFactory()->newQueryParser();
414
	}
415
416
	/**
417
	 * @since 2.5
418
	 *
419
	 * @return DataItemFactory
420
	 */
421 111
	public function getDataItemFactory() {
422 111
		return $this->callbackLoader->singleton( 'DataItemFactory' );
423
	}
424
425
	/**
426
	 * @since 2.5
427
	 *
428
	 * @return QueryFactory
429
	 */
430 222
	public function getQueryFactory() {
431 222
		return $this->callbackLoader->singleton( 'QueryFactory' );
432
	}
433
434 321
	private static function registerBuilder( CallbackLoader $callbackLoader = null ) {
435
436 321
		if ( $callbackLoader === null ) {
437 321
			$callbackLoader = new DeferredCallbackLoader( new SharedCallbackContainer() );
438
		}
439
440 321
		return $callbackLoader;
441
	}
442
443
}
444