HookRegistry::addCallbackHandlers()   B
last analyzed

Complexity

Conditions 4
Paths 1

Size

Total Lines 233
Code Lines 101

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 95
CRAP Score 4.001

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 101
c 4
b 0
f 0
dl 0
loc 233
ccs 95
cts 99
cp 0.9596
rs 8
cc 4
nc 1
nop 3
crap 4.001

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace SCI;
4
5
use SMW\Store;
0 ignored issues
show
Bug introduced by
The type SMW\Store was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use Onoi\Cache\Cache;
7
use SMW\Services\ServicesFactory as ApplicationFactory;
0 ignored issues
show
Bug introduced by
The type SMW\Services\ServicesFactory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use SMW\DataTypeRegistry;
0 ignored issues
show
Bug introduced by
The type SMW\DataTypeRegistry was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use SMW\DIWikiPage;
0 ignored issues
show
Bug introduced by
The type SMW\DIWikiPage was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use SMWDataItem as DataItem;
0 ignored issues
show
Bug introduced by
The type SMWDataItem was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
12
/**
13
 * @license GNU GPL v2+
14
 * @since 1.0
15
 *
16
 * @author mwjames
17
 */
18
class HookRegistry {
19
20
	/**
21
	 * @var array
22
	 */
23
	private $handlers = [];
24
25
	/**
26
	 * @var Options
27
	 */
28
	private $options;
29
30
	/**
31
	 * @var CitationReferencePositionJournal
32
	 */
33
	private $citationReferencePositionJournal;
34
35
	/**
36
	 * @since 1.0
37
	 *
38
	 * @param Store $store
39
	 * @param Cache $cache
40
	 * @param Options $options
41
	 */
42 16
	public function __construct( Store $store, Cache $cache, Options $options ) {
43 16
		$this->options = $options;
44
45 16
		$this->addCallbackHandlers(
46 16
			$store,
47 16
			$cache,
48 16
			$this->options
49
		);
50 16
	}
51
52
	/**
53
	 * @note Usually only used during unit/integration testing
54
	 *
55
	 * @since  1.0
56
	 *
57
	 * @param string $key
58
	 * @param mixed $value
59
	 */
60 14
	public function setOption( $key, $value ) {
61 14
		$this->options->set( $key, $value );
62 14
	}
63
64
	/**
65
	 * @since  1.0
66
	 *
67
	 * @param string $name
68
	 *
69
	 * @return boolean
70
	 */
71 1
	public function isRegistered( $name ) {
72 1
		return \MediaWiki\MediaWikiServices::getInstance()->getHookContainer()->isRegistered( $name );
0 ignored issues
show
Bug introduced by
The type MediaWiki\MediaWikiServices was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
73
	}
74
75
	/**
76
	 * @since  1.0
77
	 */
78 14
	public function clear() {
79
80 14
		if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
81
			return;
82
		}
83
84 14
		foreach ( $this->handlers as $name => $callback ) {
85
			\MediaWiki\MediaWikiServices::getInstance()->getHookContainer()->clear( $name );
86 14
		}
87 14
	}
88 14
89
	/**
90 14
	 * @since  1.0
91
	 *
92
	 * @param string $name
93 14
	 *
94
	 * @return Callable|false
95
	 */
96
	public function getHandlerFor( $name ) {
97
		return isset( $this->handlers[$name] ) ? $this->handlers[$name] : false;
98
	}
99
100
	/**
101
	 * @since  1.0
102 1
	 */
103 1
	public function register() {
104
		// *** not clear why this has been added
105
		//if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
106
		//	return;
107
		//}
108
109 14
		foreach ( $this->handlers as $name => $callback ) {
110
			\MediaWiki\MediaWikiServices::getInstance()->getHookContainer()->register( $name, $callback );
111 14
		}
112
	}
113
114
	/**
115 14
	 * @since  1.3
116
	 *
117 14
	 * @param array &$config
118 14
	 */
119 14
	public static function onBeforeConfigCompletion( &$config ) {
120
121 14
		if ( !isset( $config['smwgFulltextSearchPropertyExemptionList'] ) ) {
122
			return;
123
		}
124 14
125
		// Exclude those properties from indexing
126
		$config['smwgFulltextSearchPropertyExemptionList'] = array_merge(
127
			$config['smwgFulltextSearchPropertyExemptionList'],
128
			[ PropertyRegistry::SCI_CITE ]
129
		);
130
	}
131
132
	/**
133
	 * @since 2.0
134
	 */
135
	public static function initExtension() {
136
137
		$GLOBALS['wgHooks']['SMW::Config::BeforeCompletion'][] = function( &$config ) {
138
139
			$exemptionlist = [
140
				PropertyRegistry::SCI_CITE
141
			];
142
143
			// Exclude listed properties from indexing
144
			if ( isset( $config['smwgFulltextSearchPropertyExemptionList'] ) ) {
145
				$config['smwgFulltextSearchPropertyExemptionList'] = array_merge(
146
					$config['smwgFulltextSearchPropertyExemptionList'],
147
					$exemptionlist
148
				);
149
			}
150
151 15
			// Exclude listed properties from dependency detection as each of the
152
			// selected object would trigger an automatic change without the necessary
153
			// human intervention and can therefore produce unwanted query updates
154 15
155
			if ( isset( $config['smwgQueryDependencyPropertyExemptionList'] ) ) {
156
				$config['smwgQueryDependencyPropertyExemptionList'] = array_merge(
157
					$config['smwgQueryDependencyPropertyExemptionList'],
158 15
					$exemptionlist
159 15
				);
160 15
			}
161 15
162
			return true;
163
		};
164
	}
165
166
	public function onDataTypeInit() {
167
		$dataTypeRegistry = DataTypeRegistry::getInstance();
168
169 15
		$dataTypeRegistry->registerDatatype(
170 15
			'_sci_ref',
171 15
			'\SCI\DataValues\CitationReferenceValue',
172 15
			DataItem::TYPE_BLOB
173
		);
174
175
		$types = [
176 15
			'_sci_doi',
177
			'_sci_pmcid',
178 1
			'_sci_pmid',
179
			'_sci_oclc',
180 15
			'_sci_viaf',
181
			'_sci_olid'
182 15
		];
183 15
184 15
		foreach ( $types as $type ) {
185 15
			$dataTypeRegistry->registerDatatype(
186
				$type,
187
				'\SCI\DataValues\ResourceIdentifierStringValue',
188
				DataItem::TYPE_BLOB
189 15
			);
190
		}
191
192
		$callback = function() {
193
			return $this->citationReferencePositionJournal;
194
		};
195
196
		// SMW 3.1+
197 15
		if ( method_exists( $dataTypeRegistry, 'registerCallable' ) ) {
198 15
			$dataTypeRegistry->registerCallable( '_sci_ref', 'sci.citationreferencepositionjournal', $callback );
199 15
		} else {
200 15
			$dataTypeRegistry->registerExtraneousFunction(
201 15
				'\SCI\CitationReferencePositionJournal',
202
				$callback
203
			);
204
		}
205 15
206 8
		return true;
207 15
	}
208
209
	private function addCallbackHandlers( $store, $cache, $options ) {
210 15
211 15
		$propertyRegistry = new PropertyRegistry();
212
		$namespaceExaminer = ApplicationFactory::getInstance()->getNamespaceExaminer();
213
214
		$cacheKeyProvider = new CacheKeyProvider();
215
		$cacheKeyProvider->setCachePrefix( $options->get( 'cachePrefix' ) );
216
217
		$this->citationReferencePositionJournal = new CitationReferencePositionJournal(
218
			$cache,
219 15
			$cacheKeyProvider
220
		);
221
222 16
		$referenceBacklinksLookup = new ReferenceBacklinksLookup( $store );
223
224 16
		/**
225 16
		 * @see https://www.semantic-mediawiki.org/wiki/Hooks/SMW::Property::initProperties
226
		 */
227 16
		$this->handlers['SMW::Property::initProperties'] = function ( $corePropertyRegistry ) use ( $propertyRegistry ) {
228 16
			return $propertyRegistry->registerTo( $corePropertyRegistry );
229
		};
230 16
231 16
		/**
232 16
		 * @see https://www.semantic-mediawiki.org/wiki/Hooks/SMW::DataType::initTypes
233
		 */
234
		$this->handlers['SMW::DataType::initTypes'] = [ $this, 'onDataTypeInit' ];
235 16
236
		/**
237
		 * @see https://www.semantic-mediawiki.org/wiki/Hooks/SMW::Browse::AfterIncomingPropertiesLookupComplete
238
		 */
239
		$this->handlers['SMW::Browse::AfterIncomingPropertiesLookupComplete'] = function ( $store, $semanticData, $requestOptions ) use ( $referenceBacklinksLookup ) {
240 15
241 15
			$referenceBacklinksLookup->setRequestOptions( $requestOptions );
242
			$referenceBacklinksLookup->setStore( $store );
243
244
			$referenceBacklinksLookup->addReferenceBacklinksTo(
245
				$semanticData
246
			);
247 16
248
			return true;
249
		};
250
251
		$this->handlers['SMW::Browse::BeforeIncomingPropertyValuesFurtherLinkCreate'] = function ( $property, $subject, &$html ) use ( $referenceBacklinksLookup ) {
252 1
			return $referenceBacklinksLookup->getSpecialPropertySearchFurtherLink( $property, $subject, $html );
253
		};
254 1
255 1
		/**
256
		 * @see https://www.semantic-mediawiki.org/wiki/Hooks/SMW::Parser::BeforeMagicWordsFinder
257 1
		 */
258 1
		$this->handlers['SMW::Parser::BeforeMagicWordsFinder'] = function( array &$magicWords ) {
259
			$magicWords = array_merge( $magicWords, [ 'SCI_NOREFERENCELIST' ] );
260
			return true;
261 1
		};
262
263
		/**
264 1
		 * @see https://www.semantic-mediawiki.org/wiki/Hooks/SMW::SQLStore::AddCustomFixedPropertyTables
265 1
		 */
266
		$this->handlers['SMW::SQLStore::AddCustomFixedPropertyTables'] = function( array &$customFixedProperties ) use( $propertyRegistry ) {
267
268
			$properties = [
269
				$propertyRegistry::SCI_CITE_KEY,
270
				$propertyRegistry::SCI_CITE_REFERENCE,
271 15
				$propertyRegistry::SCI_CITE_TEXT,
272 15
				$propertyRegistry::SCI_CITE,
273 15
				$propertyRegistry::SCI_DOI,
274
				$propertyRegistry::SCI_PMCID,
275
				$propertyRegistry::SCI_PMID,
276
				$propertyRegistry::SCI_OCLC,
277
				$propertyRegistry::SCI_VIAF,
278
				$propertyRegistry::SCI_OLID
279 14
			];
280
281
			foreach ( $properties as $property ) {
282 14
				$customFixedProperties[$property] = str_replace( '__', '_', $property );
283 14
			}
284 14
285 14
			return true;
286 14
		};
287 14
288 14
		/**
289 14
		 * @see https://www.mediawiki.org/wiki/Manual:Hooks/BeforePageDisplay
290 14
		 */
291 14
		$this->handlers['BeforePageDisplay'] = function ( &$outputPage, &$skin ) use( $namespaceExaminer ) {
0 ignored issues
show
Unused Code introduced by
The parameter $skin is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

291
		$this->handlers['BeforePageDisplay'] = function ( &$outputPage, /** @scrutinizer ignore-unused */ &$skin ) use( $namespaceExaminer ) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
292
293
			if ( !$namespaceExaminer->isSemanticEnabled( $outputPage->getTitle()->getNamespace() ) ) {
294 14
				return true;
295 14
			}
296
297
			$outputPage->addModuleStyles( 'ext.scite.styles' );
298 14
299
			$outputPage->addModules(
300
				[
301
					'ext.scite.styles',
302
					'ext.scite.tooltip'
303
				]
304 1
			);
305
306 1
			return true;
307
		};
308
309
		/**
310 1
		 * @note This is bit of a hack but there is no other way to get access to
311
		 * the ParserOutput so that it can be used in OutputPageBeforeHTML
312 1
		 *
313
		 * @see https://www.mediawiki.org/wiki/Manual:Hooks/OutputPageParserOutput
314 1
		 */
315
		$this->handlers['OutputPageParserOutput'] = function( &$outputPage, $parserOutput ) {
316
			$outputPage->smwmagicwords = $parserOutput->getExtensionData( 'smwmagicwords' );
317
			return true;
318
		};
319 1
320
		/**
321
		 * @see https://www.mediawiki.org/wiki/Manual:Hooks/OutputPageBeforeHTML
322
		 */
323
		$this->handlers['OutputPageBeforeHTML'] = function( &$outputPage, &$text ) use ( $store, $namespaceExaminer, $cache, $cacheKeyProvider, $options ) {
324
325
			$referenceListFactory = new ReferenceListFactory(
326
				$store,
327
				$namespaceExaminer,
328 10
				$this->citationReferencePositionJournal
329 10
			);
330 10
331
			$cachedReferenceListOutputRenderer = $referenceListFactory->newCachedReferenceListOutputRenderer(
332
				new MediaWikiContextInteractor( $outputPage->getContext() ),
333
				$cache,
334
				$cacheKeyProvider,
335
				$options
336 10
			);
337
338 10
			$cachedReferenceListOutputRenderer->addReferenceListToText( $text );
339 10
340 10
			return true;
341 10
		};
342
343
		/**
344 10
		 * @see https://www.semantic-mediawiki.org/wiki/Hooks#SMWStore::updateDataBefore
345 10
		 */
346 10
		$this->handlers['SMWStore::updateDataBefore'] = function ( $store, $semanticData ) use ( $cache, $cacheKeyProvider ) {
347 10
348 10
			$hash = $semanticData->getSubject()->getHash();
349
350
			// No remaining reference means it is time to purge the cache once
351 10
			// more because as long as a CiteRef exists, CitationReferencePositionJournal
352
			// is able recompute and update the entries but with no CiteRef left
353 10
			// the last entry will remain and needs to be purged at this point
354
			if ( !$this->citationReferencePositionJournal->hasCitationReference( $semanticData ) ) {
355
				$cache->delete(
356
					$cacheKeyProvider->getCacheKeyForCitationReference( $hash )
357
				);
358
			}
359 15
360
			$cache->delete(
361 15
				$cacheKeyProvider->getCacheKeyForReferenceList( $hash )
362
			);
363
364
			return true;
365
		};
366
367 15
		/**
368 14
		 * @see https://www.semantic-mediawiki.org/wiki/Hooks#SMW::SQLStore::AfterDeleteSubjectComplete
369 14
		 */
370
		$this->handlers['SMW::SQLStore::AfterDeleteSubjectComplete'] = function ( $store, $title ) use ( $cache, $cacheKeyProvider ) {
371
372
			$hash = DIWikiPage::newFromTitle( $title )->getHash();
373 15
374 15
			$cache->delete(
375
				$cacheKeyProvider->getCacheKeyForCitationReference( $hash )
376
			);
377 15
378
			$cache->delete(
379
				$cacheKeyProvider->getCacheKeyForReferenceList( $hash )
380
			);
381
382
			return true;
383 15
		};
384
385 15
		/**
386
		 * @see https://www.semantic-mediawiki.org/wiki/Hooks#SMW::SQLStore::AfterDataUpdateComplete
387 15
		 */
388 15
		$this->handlers['SMW::SQLStore::AfterDataUpdateComplete'] = function ( $store, $semanticData, $compositePropertyTableDiffIterator ) use ( $referenceBacklinksLookup, $options ) {
389
390
			$referenceBacklinksLookup->setStore( $store );
391 15
392 15
			$citationTextChangeUpdateJobDispatcher = new CitationTextChangeUpdateJobDispatcher(
393
				$store,
394
				$referenceBacklinksLookup
395 15
			);
396
397
			$citationTextChangeUpdateJobDispatcher->setEnabledUpdateJobState(
398
				$options->get( 'enabledCitationTextChangeUpdateJob' )
399
			);
400
401 15
			$citationTextChangeUpdateJobDispatcher->dispatchUpdateJobFor(
402
				$semanticData->getSubject(),
403 15
				$compositePropertyTableDiffIterator
404
			);
405 15
406 15
			return true;
407 15
		};
408
409
		/**
410 15
		 * @see https://www.mediawiki.org/wiki/Manual:Hooks/ResourceLoaderGetConfigVars
411 15
		 */
412
		$this->handlers['ResourceLoaderGetConfigVars'] = function ( &$vars ) use ( $options ) {
413
414 15
			$vars['ext.scite.config'] = [
415 15
				'showTooltipForCitationReference' => $options->get( 'showTooltipForCitationReference' ),
416 15
				'tooltipRequestCacheTTL' => $options->get( 'tooltipRequestCacheTTL' ),
417
				'cachePrefix' => $options->get( 'cachePrefix' )
418
			];
419 15
420
			return true;
421
		};
422
423
		/**
424
		 * @see https://www.mediawiki.org/wiki/Manual:Hooks/ParserFirstCallInit
425 1
		 */
426
		$this->handlers['ParserFirstCallInit'] = function ( &$parser ) use ( $namespaceExaminer, $options ) {
427 1
428 1
			$parserFunctionFactory = new ParserFunctionFactory();
429 1
430 1
			list( $name, $definition, $flag ) = $parserFunctionFactory->newSciteParserFunctionDefinition(
431
				$namespaceExaminer,
432
				$options
433 1
			);
434
435
			$parser->setFunctionHook( $name, $definition, $flag );
436
437
			list( $name, $definition, $flag ) = $parserFunctionFactory->newReferenceListParserFunctionDefinition();
438
439 1
			$parser->setFunctionHook( $name, $definition, $flag );
440
441 1
			return true;
442
		};
443 1
	}
444 1
445
}
446