Completed
Push — master ( d0e318...ce486f )
by mw
60:23 queued 38:27
created

Store::getRedirectTarget()   D

Complexity

Conditions 9
Paths 10

Size

Total Lines 37
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 9.0101

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 9
eloc 22
c 1
b 1
f 0
nc 10
nop 1
dl 0
loc 37
ccs 19
cts 20
cp 0.95
crap 9.0101
rs 4.909
1
<?php
2
3
namespace SMW;
4
5
use SMWDataItem;
6
use SMWQuery;
7
use SMWQueryResult;
8
use SMWRequestOptions;
9
use SMWSemanticData;
10
use Title;
11
12
/**
13
 * This group contains all parts of SMW that relate to storing and retrieving
14
 * semantic data. SMW components that relate to semantic querying only have
15
 * their own group.
16
 *
17
 * @defgroup SMWStore SMWStore
18
 * @ingroup SMW
19
 */
20
21
/**
22
 * The abstract base class for all classes that implement access to some
23
 * semantic store. Besides the relevant interface, this class provides default
24
 * implementations for some optional methods, which inform the caller that
25
 * these methods are not implemented.
26
 *
27
 * @ingroup SMWStore
28
 *
29
 * @author Markus Krötzsch
30
 */
31
abstract class Store {
32
33
	/**
34
	 * @var boolean
35
	 */
36
	private $updateJobsEnabledState = true;
37
38
	/**
39
	 * @var ConnectionManager
40
	 */
41
	protected $connectionManager = null;
42
43
///// Reading methods /////
44
45
	/**
46
	 * Retrieve all data stored about the given subject and return it as a
47
	 * SMWSemanticData container. There are no options: it just returns all
48
	 * available data as shown in the page's Factbox.
49
	 * $filter is an array of strings that are datatype IDs. If given, the
50
	 * function will avoid any work that is not necessary if only
51
	 * properties of these types are of interest.
52
	 *
53
	 * @note There is no guarantee that the store does not retrieve more
54
	 * data than requested when a filter is used. Filtering just ensures
55
	 * that only necessary requests are made, i.e. it improves performance.
56
	 *
57
	 * @param DIWikiPage $subject
58
	 * @param string[]|bool $filter
59
	 */
60
	public abstract function getSemanticData( DIWikiPage $subject, $filter = false );
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
61
62
	/**
63
	 * Get an array of all property values stored for the given subject and
64
	 * property. The result is an array of DataItem objects.
65
	 *
66
	 * If called with $subject == null, all values for the given property
67
	 * are returned.
68
	 *
69
	 * @param $subject mixed SMWDIWikiPage or null
70
	 * @param $property DIProperty
71
	 * @param $requestoptions SMWRequestOptions
72
	 *
73
	 * @return array of SMWDataItem
74
	 */
75
	public abstract function getPropertyValues( $subject, DIProperty $property, $requestoptions = null );
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
76
77
	/**
78
	 * Get an array of all subjects that have the given value for the given
79
	 * property. The result is an array of DIWikiPage objects. If null
80
	 * is given as a value, all subjects having that property are returned.
81
	 *
82
	 * @return DIWikiPage[]
83
	 */
84
	public abstract function getPropertySubjects( DIProperty $property, $value, $requestoptions = null );
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
85
86
	/**
87
	 * Get an array of all subjects that have some value for the given
88
	 * property. The result is an array of DIWikiPage objects.
89
	 *
90
	 * @return DIWikiPage[]
91
	 */
92
	public abstract function getAllPropertySubjects( DIProperty $property, $requestoptions = null );
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
93
94
	/**
95
	 * Get an array of all properties for which the given subject has some
96
	 * value. The result is an array of DIProperty objects.
97
	 *
98
	 * @param DIWikiPage $subject denoting the subject
99
	 * @param SMWRequestOptions|null $requestOptions optionally defining further options
100
	 *
101
	 * @return SMWDataItem
102
	 */
103
	public abstract function getProperties( DIWikiPage $subject, $requestOptions = null );
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
104
105
	/**
106
	 * Get an array of all properties for which there is some subject that
107
	 * relates to the given value. The result is an array of SMWDIWikiPage
108
	 * objects.
109
	 * @note In some stores, this function might be implemented partially
110
	 * so that only values of type Page (_wpg) are supported.
111
	 */
112
	public abstract function getInProperties( SMWDataItem $object, $requestoptions = null );
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
113
114
	/**
115
	 * Convenience method to find the sortkey of an SMWDIWikiPage. The
116
	 * result is based on the contents of this store, and may differ from
117
	 * the MediaWiki database entry about a Title objects sortkey. If no
118
	 * sortkey is stored, the default sortkey (title string) is returned.
119
	 *
120
	 * @param $wikiPage DIWikiPage to find the sortkey for
121
	 * @return string sortkey
122
	 */
123 4
	public function getWikiPageSortKey( DIWikiPage $wikiPage ) {
124 4
		$sortkeyDataItems = $this->getPropertyValues( $wikiPage, new DIProperty( '_SKEY' ) );
125
126 4
		if ( count( $sortkeyDataItems ) > 0 ) {
127 4
			return end( $sortkeyDataItems )->getString();
128
		} else {
129
			return str_replace( '_', ' ', $wikiPage->getDBkey() );
130
		}
131
	}
132
133
	/**
134
	 * Convenience method to find last modified MW timestamp for a subject that
135
	 * has been added using the storage-engine.
136
	 *
137
	 * @since 2.3
138
	 *
139
	 * @param DIWikiPage $wikiPage
140
	 *
141
	 * @return integer
142
	 */
143
	public function getWikiPageLastModifiedTimestamp( DIWikiPage $wikiPage ) {
144
145
		$dataItems = $this->getPropertyValues( $wikiPage, new DIProperty( '_MDAT' ) );
146
147
		if ( $dataItems !== array() ) {
148
			return end( $dataItems )->getMwTimestamp( TS_MW );
149
		}
150
151
		return 0;
152
	}
153
154
	/**
155
	 * Convenience method to find the redirect target of a DIWikiPage
156
	 * or DIProperty object. Returns a dataitem of the same type that
157
	 * the input redirects to, or the input itself if there is no redirect.
158
	 *
159
	 * @param $dataItem SMWDataItem to find the redirect for.
160
	 * @return SMWDataItem
161
	 */
162 190
	public function getRedirectTarget( SMWDataItem $dataItem ) {
163 190
		if ( $dataItem->getDIType() == SMWDataItem::TYPE_PROPERTY ) {
164 186
			if ( !$dataItem->isUserDefined() ) {
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class SMWDataItem as the method isUserDefined() does only exist in the following sub-classes of SMWDataItem: SMWDIProperty, SMW\DIProperty. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
165 143
				return $dataItem;
166
			}
167 169
			$wikipage = $dataItem->getDiWikiPage();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class SMWDataItem as the method getDiWikiPage() does only exist in the following sub-classes of SMWDataItem: SMWDIProperty, SMW\DIProperty. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
168 27
		} elseif ( $dataItem->getDIType() == SMWDataItem::TYPE_WIKIPAGE ) {
169 27
			$wikipage = $dataItem;
170
		} else {
171
			throw new InvalidArgumentException( 'SMWStore::getRedirectTarget() expects an object of type IProperty or SMWDIWikiPage.' );
172
		}
173
174 174
		$hash = $wikipage->getHash();
175 174
		$poolCache = InMemoryPoolCache::getInstance()->getPoolCacheFor( 'store.redirectTarget.lookup' );
176
177
		// Ensure that the same type context is used
178 174
		if ( ( $di = $poolCache->fetch( $hash ) ) !== false && $di->getDIType() === $dataItem->getDIType() ) {
179 5
			return $di;
180
		}
181
182 173
		$redirectDataItems = $this->getPropertyValues( $wikipage, new DIProperty( '_REDI' ) );
183
184 173
		if ( count( $redirectDataItems ) > 0 ) {
185
186 8
			$redirectDataItem = end( $redirectDataItems );
187
188 8
			if ( $dataItem->getDIType() == SMWDataItem::TYPE_PROPERTY && $redirectDataItem instanceof DIWikiPage ) {
189 5
				$dataItem = DIProperty::newFromUserLabel( $redirectDataItem->getDBkey() );
190
			} else {
191 4
				$dataItem = $redirectDataItem;
192
			}
193
194 8
			$poolCache->save( $hash, $dataItem );
195
		}
196
197 173
		return $dataItem;
198
	}
199
200
///// Writing methods /////
201
202
	/**
203
	 * Delete all semantic properties that the given subject has. This
204
	 * includes relations, attributes, and special properties. This does
205
	 * not delete the respective text from the wiki, but only clears the
206
	 * stored data.
207
	 *
208
	 * @param Title $subject
209
	 */
210
	public abstract function deleteSubject( Title $subject );
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
211
212
	/**
213
	 * Update the semantic data stored for some individual. The data is
214
	 * given as a SemanticData object, which contains all semantic data
215
	 * for one particular subject.
216
	 *
217
	 * @param SemanticData $data
218
	 */
219
	protected abstract function doDataUpdate( SemanticData $data );
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
220
221
	/**
222
	 * Update the semantic data stored for some individual. The data is
223
	 * given as a SemanticData object, which contains all semantic data
224
	 * for one particular subject.
225
	 *
226
	 * @param SemanticData $semanticData
227
	 */
228 225
	public function updateData( SemanticData $semanticData ) {
229
230 225
		if ( !ApplicationFactory::getInstance()->getSettings()->get( 'smwgSemanticsEnabled' ) ) {
231
			return;
232
		}
233
234 225
		$subject = $semanticData->getSubject();
235
236 225
		$dispatchContext = EventHandler::getInstance()->newDispatchContext();
237 225
		$dispatchContext->set( 'subject', $subject );
238
239 225
		EventHandler::getInstance()->getEventDispatcher()->dispatch(
240 225
			'on.before.semanticdata.update.complete',
241
			$dispatchContext
242
		);
243
244
		/**
245
		 * @since 1.6
246
		 */
247 225
		\Hooks::run( 'SMWStore::updateDataBefore', array( $this, $semanticData ) );
248
249 225
		$this->doDataUpdate( $semanticData );
250
251
		/**
252
		 * @since 1.6
253
		 */
254 225
		\Hooks::run( 'SMWStore::updateDataAfter', array( $this, $semanticData ) );
255
256 225
		EventHandler::getInstance()->getEventDispatcher()->dispatch(
257 225
			'on.after.semanticdata.update.complete',
258
			$dispatchContext
259
		);
260 225
	}
261
262
	/**
263
	 * Clear all semantic data specified for some page.
264
	 *
265
	 * @param DIWikiPage $di
266
	 */
267 34
	public function clearData( DIWikiPage $di ) {
268 34
		$this->updateData( new SMWSemanticData( $di ) );
269 34
	}
270
271
	/**
272
	 * Update the store to reflect a renaming of some article. Normally
273
	 * this happens when moving pages in the wiki, and in this case there
274
	 * is also a new redirect page generated at the old position. The title
275
	 * objects given are only used to specify the name of the title before
276
	 * and after the move -- do not use their IDs for anything! The ID of
277
	 * the moved page is given in $pageid, and the ID of the newly created
278
	 * redirect, if any, is given by $redirid. If no new page was created,
279
	 * $redirid will be 0.
280
	 */
281
	public abstract function changeTitle( Title $oldtitle, Title $newtitle, $pageid, $redirid = 0 );
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
282
283
///// Query answering /////
284
285
	/**
286
	 * @note Change the signature in 3.* to avoid for subclasses to manage the
287
	 * hooks; keep the current signature to adhere semver for the 2.* branch
288
	 *
289
	 * Execute the provided query and return the result as an
290
	 * SMWQueryResult if the query was a usual instance retrieval query. In
291
	 * the case that the query asked for a plain string (querymode
292
	 * MODE_COUNT or MODE_DEBUG) a plain wiki and HTML-compatible string is
293
	 * returned.
294
	 *
295
	 * @param SMWQuery $query
296
	 *
297
	 * @return SMWQueryResult
298
	 */
299
	public abstract function getQueryResult( SMWQuery $query );
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
300
301
	/**
302
	 * @note Change the signature to abstract for the 3.* branch
303
	 *
304
	 * @since  2.1
305
	 *
306
	 * @param SMWQuery $query
307
	 *
308
	 * @return SMWQueryResult
309
	 */
310
	protected function fetchQueryResult( SMWQuery $query ) {
311
	}
312
313
///// Special page functions /////
314
315
	/**
316
	 * Return all properties that have been used on pages in the wiki. The
317
	 * result is an array of arrays, each containing a property data item
318
	 * and a count. The expected order is alphabetical w.r.t. to property
319
	 * names.
320
	 *
321
	 * If there is an error on creating some property object, then a
322
	 * suitable SMWDIError object might be returned in its place. Even if
323
	 * there are errors, the function should always return the number of
324
	 * results requested (otherwise callers might assume that there are no
325
	 * further results to ask for).
326
	 *
327
	 * @param SMWRequestOptions $requestoptions
328
	 *
329
	 * @return array of array( DIProperty|SMWDIError, integer )
330
	 */
331
	public abstract function getPropertiesSpecial( $requestoptions = null );
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
332
333
	/**
334
	 * Return all properties that have been declared in the wiki but that
335
	 * are not used on any page. Stores might restrict here to those
336
	 * properties that have been given a type if they have no efficient
337
	 * means of accessing the set of all pages in the property namespace.
338
	 *
339
	 * If there is an error on creating some property object, then a
340
	 * suitable SMWDIError object might be returned in its place. Even if
341
	 * there are errors, the function should always return the number of
342
	 * results requested (otherwise callers might assume that there are no
343
	 * further results to ask for).
344
	 *
345
	 * @param SMWRequestOptions $requestoptions
346
	 *
347
	 * @return array of DIProperty|SMWDIError
348
	 */
349
	public abstract function getUnusedPropertiesSpecial( $requestoptions = null );
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
350
351
	/**
352
	 * Return all properties that are used on some page but that do not
353
	 * have any page describing them. Stores that have no efficient way of
354
	 * accessing the set of all existing pages can extend this list to all
355
	 * properties that are used but do not have a type assigned to them.
356
	 *
357
	 * @param SMWRequestOptions $requestoptions
358
	 *
359
	 * @return array of array( DIProperty, int )
360
	 */
361
	public abstract function getWantedPropertiesSpecial( $requestoptions = null );
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
362
363
	/**
364
	 * Return statistical information as an associative array with the
365
	 * following keys:
366
	 * - 'PROPUSES': Number of property instances (value assignments) in the datatbase
367
	 * - 'USEDPROPS': Number of properties that are used with at least one value
368
	 * - 'DECLPROPS': Number of properties that have been declared (i.e. assigned a type)
369
	 * - 'OWNPAGE': Number of properties with their own page
370
	 * - 'QUERY': Number of inline queries
371
	 * - 'QUERYSIZE': Represents collective query size
372
	 * - 'CONCEPTS': Number of declared concepts
373
	 * - 'SUBOBJECTS': Number of declared subobjects
374
	 *
375
	 * @return array
376
	 */
377
	public abstract function getStatistics();
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
378
379
///// Setup store /////
380
381
	/**
382
	 * Setup all storage structures properly for using the store. This
383
	 * function performs tasks like creation of database tables. It is
384
	 * called upon installation as well as on upgrade: hence it must be
385
	 * able to upgrade existing storage structures if needed. It should
386
	 * return "true" if successful and return a meaningful string error
387
	 * message otherwise.
388
	 *
389
	 * The parameter $verbose determines whether the procedure is allowed
390
	 * to report on its progress. This is doen by just using print and
391
	 * possibly ob_flush/flush. This is also relevant for preventing
392
	 * timeouts during long operations. All output must be valid in an HTML
393
	 * context, but should preferrably be plain text, possibly with some
394
	 * linebreaks and weak markup.
395
	 *
396
	 * @param boolean $verbose
397
	 *
398
	 * @return boolean Success indicator
399
	 */
400
	public abstract function setup( $verbose = true );
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
401
402
	/**
403
	 * Drop (delete) all storage structures created by setup(). This will
404
	 * delete all semantic data and possibly leave the wiki uninitialised.
405
	 *
406
	 * @param boolean $verbose
407
	 */
408
	public abstract function drop( $verbose = true );
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
409
410
	/**
411
	 * Refresh some objects in the store, addressed by numerical ids. The
412
	 * meaning of the ids is private to the store, and does not need to
413
	 * reflect the use of IDs elsewhere (e.g. page ids). The store is to
414
	 * refresh $count objects starting from the given $index. Typically,
415
	 * updates are achieved by generating update jobs. After the operation,
416
	 * $index is set to the next index that should be used for continuing
417
	 * refreshing, or to -1 for signaling that no objects of higher index
418
	 * require refresh. The method returns a decimal number between 0 and 1
419
	 * to indicate the overall progress of the refreshing (e.g. 0.7 if 70%
420
	 * of all objects were refreshed).
421
	 *
422
	 * The optional parameter $namespaces may contain an array of namespace
423
	 * constants. If given, only objects from those namespaces will be
424
	 * refreshed. The default value FALSE disables this feature.
425
	 *
426
	 * The optional parameter $usejobs indicates whether updates should be
427
	 * processed later using MediaWiki jobs, instead of doing all updates
428
	 * immediately. The default is TRUE.
429
	 *
430
	 * @param $index integer
431
	 * @param $count integer
432
	 * @param $namespaces mixed array or false
433
	 * @param $usejobs boolean
434
	 *
435
	 * @return float between 0 and 1 to indicate the overall progress of the refreshing
436
	 */
437
	public abstract function refreshData( &$index, $count, $namespaces = false, $usejobs = true );
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
438
439
	/**
440
	 * Setup the store.
441
	 *
442
	 * @since 1.8
443
	 *
444
	 * @param bool $verbose
445
	 *
446
	 * @return boolean Success indicator
447
	 */
448 3
	public static function setupStore( $verbose = true ) {
449 3
		$result = StoreFactory::getStore()->setup( $verbose );
450 3
		\Hooks::run( 'smwInitializeTables' );
451 3
		return $result;
452
	}
453
454
	/**
455
	 * Returns the tables that should be added via the
456
	 * https://www.mediawiki.org/wiki/Manual:Hooks/ParserTestTables
457
	 * hook when it's run.
458
	 *
459
	 * @since 1.8
460
	 *
461
	 * @return array
462
	 */
463
	public function getParserTestTables() {
464
		return array();
465
	}
466
467
	/**
468
	 * @since 2.0
469
	 */
470 21
	public function clear() {
471 21
		$this->connectionManager->releaseConnections();
472 21
		InMemoryPoolCache::getInstance()->resetPoolCacheFor( 'store.redirectTarget.lookup' );
473 21
	}
474
475
	/**
476
	 * @since 2.1
477
	 *
478
	 * @param boolean $status
479
	 */
480 181
	public function setUpdateJobsEnabledState( $status ) {
481 181
		$this->updateJobsEnabledState = $status;
482 181
	}
483
484
	/**
485
	 * @since 2.1
486
	 *
487
	 * @return boolean
488
	 */
489 23
	public function getUpdateJobsEnabledState() {
0 ignored issues
show
Coding Style introduced by
getUpdateJobsEnabledState uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
490 23
		return $this->updateJobsEnabledState && $GLOBALS['smwgEnableUpdateJobs'];
491
	}
492
493
	/**
494
	 * @since 2.1
495
	 *
496
	 * @param ConnectionManager $connectionManager
497
	 *
498
	 * @return Store
499
	 */
500 15
	public function setConnectionManager( ConnectionManager $connectionManager ) {
501 15
		$this->connectionManager = $connectionManager;
502 15
		return $this;
503
	}
504
505
	/**
506
	 * @since 2.1
507
	 *
508
	 * @param string $connectionTypeId
509
	 *
510
	 * @return mixed
511
	 */
512 272
	public function getConnection( $connectionTypeId ) {
513
514 272
		if ( $this->connectionManager === null ) {
515 13
			$this->setConnectionManager( new ConnectionManager() );
516
		}
517
518 272
		return $this->connectionManager->getConnection( $connectionTypeId );
519
	}
520
521
}
522