Completed
Push — master ( 079bf8...76aa3a )
by mw
04:39
created

HookRegistry::clear()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
ccs 5
cts 5
cp 1
cc 2
eloc 3
nc 2
nop 0
crap 2
1
<?php
2
3
namespace SCI;
4
5
use SMW\Store;
6
use Onoi\Cache\Cache;
7
use SMW\ApplicationFactory;
8
use SMW\DIWikiPage;
9
use SMWDataItem as DataItem;
10
use Hooks;
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 = array();
24
25
	/**
26
	 * @var Options
27
	 */
28
	private $options;
29
30
	/**
31
	 * @since 1.0
32
	 *
33
	 * @param Store $store
34
	 * @param Cache $cache
35
	 * @param Options $options
36
	 */
37 16
	public function __construct( Store $store, Cache $cache, Options $options ) {
38 16
		$this->options = $options;
39
40 16
		$this->addCallbackHandlers(
41 16
			$store,
42 16
			$cache,
43 16
			$this->options
44 16
		);
45 16
	}
46
47
	/**
48
	 * @note Usually only used during unit/integration testing
49
	 *
50
	 * @since  1.0
51
	 *
52
	 * @param string $key
53
	 * @param mixed $value
54
	 */
55 14
	public function setOption( $key, $value ) {
56 14
		$this->options->set( $key, $value );
57 14
	}
58
59
	/**
60
	 * @since  1.0
61
	 *
62
	 * @param string $name
63
	 *
64
	 * @return boolean
65
	 */
66 1
	public function isRegistered( $name ) {
67 1
		return Hooks::isRegistered( $name );
68
	}
69
70
	/**
71
	 * @since  1.0
72
	 */
73 14
	public function clear() {
74 14
		foreach ( $this->handlers as $name => $callback ) {
75 14
			Hooks::clear( $name );
76 14
		}
77 14
	}
78
79
	/**
80
	 * @since  1.0
81
	 *
82
	 * @param string $name
83
	 *
84
	 * @return Callable|false
85
	 */
86 1
	public function getHandlerFor( $name ) {
87 1
		return isset( $this->handlers[$name] ) ? $this->handlers[$name] : false;
88
	}
89
90
	/**
91
	 * @since  1.0
92
	 */
93 14
	public function register() {
94 14
		foreach ( $this->handlers as $name => $callback ) {
95 14
			Hooks::register( $name, $callback );
96 14
		}
97 14
	}
98
99
	/**
100
	 * @since  1.3
101
	 *
102
	 * @param array &$config
103
	 */
104 15
	public static function onBeforeConfigCompletion( &$config ) {
105
106 15
		if ( !isset( $config['smwgFulltextSearchPropertyExemptionList'] ) ) {
107
			return;
108
		}
109
110
		// Exclude those properties from indexing
111 15
		$config['smwgFulltextSearchPropertyExemptionList'] = array_merge(
112 15
			$config['smwgFulltextSearchPropertyExemptionList'],
113 15
			array( PropertyRegistry::SCI_CITE )
114 15
		);
115 15
	}
116
117 16
	private function addCallbackHandlers( $store, $cache, $options ) {
118
119 16
		$propertyRegistry = new PropertyRegistry();
120 16
		$namespaceExaminer = ApplicationFactory::getInstance()->getNamespaceExaminer();
121
122 16
		$cacheKeyProvider = new CacheKeyProvider();
123 16
		$cacheKeyProvider->setCachePrefix( $options->get( 'cachePrefix' ) );
124
125 16
		$citationReferencePositionJournal = new CitationReferencePositionJournal(
126 16
			$cache,
127
			$cacheKeyProvider
128 16
		);
129
130 16
		$referenceBacklinksLookup = new ReferenceBacklinksLookup( $store );
131
132
		/**
133
		 * @see https://www.semantic-mediawiki.org/wiki/Hooks/SMW::Property::initProperties
134
		 */
135
		$this->handlers['SMW::Property::initProperties'] = function ( $corePropertyRegistry ) use ( $propertyRegistry ) {
136 15
			return $propertyRegistry->registerTo( $corePropertyRegistry );
137
		};
138
139
		/**
140
		 * @see https://www.semantic-mediawiki.org/wiki/Hooks/SMW::DataType::initTypes
141
		 */
142
		$this->handlers['SMW::DataType::initTypes'] = function ( $dataTypeRegistry ) use( $citationReferencePositionJournal ) {
143
144 13
			$dataTypeRegistry->registerDatatype(
145 13
				'_sci_ref',
146 13
				'\SCI\DataValues\CitationReferenceValue',
147
				DataItem::TYPE_BLOB
148 13
			);
149
150
			$types = array(
151 13
				'_sci_doi',
152 13
				'_sci_pmcid',
153 13
				'_sci_pmid',
154 13
				'_sci_oclc',
155 13
				'_sci_viaf',
156
				'_sci_olid'
157 13
			);
158
159 13
			foreach ( $types as $type ) {
160 13
				$dataTypeRegistry->registerDatatype(
161 13
					$type,
162 13
					'\SCI\DataValues\ResourceIdentifierStringValue',
163
					DataItem::TYPE_BLOB
164 13
				);
165 13
			}
166
167 13
			$dataTypeRegistry->registerExtraneousFunction(
168 13
				'\SCI\CitationReferencePositionJournal',
169
				function() use( $citationReferencePositionJournal ) { return $citationReferencePositionJournal; }
170 13
			);
171
172 13
			return true;
173
		};
174
175
		/**
176
		 * @see https://www.semantic-mediawiki.org/wiki/Hooks/SMW::Browse::AfterIncomingPropertiesLookupComplete
177
		 */
178
		$this->handlers['SMW::Browse::AfterIncomingPropertiesLookupComplete'] = function ( $store, $semanticData, $requestOptions ) use ( $referenceBacklinksLookup ) {
179
180 1
			$referenceBacklinksLookup->setRequestOptions( $requestOptions );
181 1
			$referenceBacklinksLookup->setStore( $store );
182
183 1
			$referenceBacklinksLookup->addReferenceBacklinksTo(
184
				$semanticData
185 1
			);
186
187 1
			return true;
188
		};
189
190
		$this->handlers['SMW::Browse::BeforeIncomingPropertyValuesFurtherLinkCreate'] = function ( $property, $subject, &$html ) use ( $referenceBacklinksLookup ) {
191 1
			return $referenceBacklinksLookup->getSpecialPropertySearchFurtherLink( $property, $subject, $html );
192
		};
193
194
		/**
195
		 * @see https://www.semantic-mediawiki.org/wiki/Hooks/SMW::Parser::BeforeMagicWordsFinder
196
		 */
197
		$this->handlers['SMW::Parser::BeforeMagicWordsFinder'] = function( array &$magicWords ) {
198 15
			$magicWords = array_merge( $magicWords, array( 'SCI_NOREFERENCELIST' ) );
199 15
			return true;
200
		};
201
202
		/**
203
		 * @see https://www.semantic-mediawiki.org/wiki/Hooks/SMW::SQLStore::AddCustomFixedPropertyTables
204
		 */
205
		$this->handlers['SMW::SQLStore::AddCustomFixedPropertyTables'] = function( array &$customFixedProperties ) use( $propertyRegistry ) {
206
207
			$properties = array(
208 14
				$propertyRegistry::SCI_CITE_KEY,
209 14
				$propertyRegistry::SCI_CITE_REFERENCE,
210 14
				$propertyRegistry::SCI_CITE_TEXT,
211 14
				$propertyRegistry::SCI_CITE,
212 14
				$propertyRegistry::SCI_DOI,
213 14
				$propertyRegistry::SCI_PMCID,
214 14
				$propertyRegistry::SCI_PMID,
215 14
				$propertyRegistry::SCI_OCLC,
216 14
				$propertyRegistry::SCI_VIAF,
217
				$propertyRegistry::SCI_OLID
218 14
			);
219
220 14
			foreach ( $properties as $property ) {
221 14
				$customFixedProperties[$property] = str_replace( '__', '_', $property );
222 14
			}
223
224 14
			return true;
225
		};
226
227
		/**
228
		 * @see https://www.mediawiki.org/wiki/Manual:Hooks/BeforePageDisplay
229
		 */
230
		$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.

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

Loading history...
231
232 1
			if ( !$namespaceExaminer->isSemanticEnabled( $outputPage->getTitle()->getNamespace() ) ) {
233
				return true;
234
			}
235
236 1
			$outputPage->addModuleStyles( 'ext.scite.styles' );
237
238 1
			$outputPage->addModules(
239
				array(
240 1
					'ext.scite.styles',
241
					'ext.scite.tooltip'
242 1
				)
243 1
			);
244
245 1
			return true;
246
		};
247
248
		/**
249
		 * @note This is bit of a hack but there is no other way to get access to
250
		 * the ParserOutput so that it can be used in OutputPageBeforeHTML
251
		 *
252
		 * @see https://www.mediawiki.org/wiki/Manual:Hooks/OutputPageParserOutput
253
		 */
254
		$this->handlers['OutputPageParserOutput'] = function( &$outputPage, $parserOutput ) {
255 10
			$outputPage->smwmagicwords = $parserOutput->getExtensionData( 'smwmagicwords' );
256 10
			return true;
257
		};
258
259
		/**
260
		 * @see https://www.mediawiki.org/wiki/Manual:Hooks/OutputPageBeforeHTML
261
		 */
262
		$this->handlers['OutputPageBeforeHTML'] = function( &$outputPage, &$text ) use ( $store, $namespaceExaminer, $citationReferencePositionJournal, $cache, $cacheKeyProvider, $options ) {
263
264 10
			$referenceListFactory = new ReferenceListFactory(
265 10
				$store,
266 10
				$namespaceExaminer,
267
				$citationReferencePositionJournal
268 10
			);
269
270 10
			$cachedReferenceListOutputRenderer = $referenceListFactory->newCachedReferenceListOutputRenderer(
271 10
				new MediaWikiContextInteractor( $outputPage->getContext() ),
272 10
				$cache,
273 10
				$cacheKeyProvider,
274
				$options
275 10
			);
276
277 10
			$cachedReferenceListOutputRenderer->addReferenceListToText( $text );
278
279 10
			return true;
280
		};
281
282
		/**
283
		 * @see https://www.semantic-mediawiki.org/wiki/Hooks#SMWStore::updateDataBefore
284
		 */
285
		$this->handlers['SMWStore::updateDataBefore'] = function ( $store, $semanticData ) use ( $cache, $cacheKeyProvider, $citationReferencePositionJournal ) {
286
287 15
			$hash = $semanticData->getSubject()->getHash();
288
289
			// No remaining reference means it is time to purge the cache once
290
			// more because as long as a CiteRef exists, CitationReferencePositionJournal
291
			// is able recompute and update the entries but with no CiteRef left
292
			// the last entry will remain and needs to be purged at this point
293 15
			if ( !$citationReferencePositionJournal->hasCitationReference( $semanticData ) ) {
294 14
				$cache->delete(
295 14
					$cacheKeyProvider->getCacheKeyForCitationReference( $hash )
296 14
				);
297 14
			}
298
299 15
			$cache->delete(
300 15
				$cacheKeyProvider->getCacheKeyForReferenceList( $hash )
301 15
			);
302
303 15
			return true;
304
		};
305
306
		/**
307
		 * @see https://www.semantic-mediawiki.org/wiki/Hooks#SMW::SQLStore::AfterDeleteSubjectComplete
308
		 */
309
		$this->handlers['SMW::SQLStore::AfterDeleteSubjectComplete'] = function ( $store, $title ) use ( $cache, $cacheKeyProvider ) {
310
311 15
			$hash = DIWikiPage::newFromTitle( $title )->getHash();
312
313 15
			$cache->delete(
314 15
				$cacheKeyProvider->getCacheKeyForCitationReference( $hash )
315 15
			);
316
317 15
			$cache->delete(
318 15
				$cacheKeyProvider->getCacheKeyForReferenceList( $hash )
319 15
			);
320
321 15
			return true;
322
		};
323
324
		/**
325
		 * @see https://www.semantic-mediawiki.org/wiki/Hooks#SMW::SQLStore::AfterDataUpdateComplete
326
		 */
327
		$this->handlers['SMW::SQLStore::AfterDataUpdateComplete'] = function ( $store, $semanticData, $compositePropertyTableDiffIterator ) use ( $referenceBacklinksLookup, $options ) {
328
329 15
			$referenceBacklinksLookup->setStore( $store );
330
331 15
			$citationTextChangeUpdateJobDispatcher = new CitationTextChangeUpdateJobDispatcher(
332 15
				$store,
333
				$referenceBacklinksLookup
334 15
			);
335
336 15
			$citationTextChangeUpdateJobDispatcher->setEnabledUpdateJobState(
337 15
				$options->get( 'enabledCitationTextChangeUpdateJob' )
338 15
			);
339
340 15
			$citationTextChangeUpdateJobDispatcher->dispatchUpdateJobFor(
341 15
				$semanticData->getSubject(),
342
				$compositePropertyTableDiffIterator
343 15
			);
344
345 15
			return true;
346
		};
347
348
		/**
349
		 * @see https://www.mediawiki.org/wiki/Manual:Hooks/ResourceLoaderGetConfigVars
350
		 */
351
		$this->handlers['ResourceLoaderGetConfigVars'] = function ( &$vars ) use ( $options ) {
352
353 1
			$vars['ext.scite.config'] = array(
354 1
				'showTooltipForCitationReference' => $options->get( 'showTooltipForCitationReference' ),
355 1
				'tooltipRequestCacheTTL' => $options->get( 'tooltipRequestCacheTTL' ),
356 1
				'cachePrefix' => $options->get( 'cachePrefix' )
357 1
			);
358
359 1
			return true;
360
		};
361
362
		/**
363
		 * @see https://www.mediawiki.org/wiki/Manual:Hooks/ParserFirstCallInit
364
		 */
365 1
		$this->handlers['ParserFirstCallInit'] = function ( &$parser ) use ( $namespaceExaminer, $options ) {
366
367 1
			$parserFunctionFactory = new ParserFunctionFactory();
368
369 1
			list( $name, $definition, $flag ) = $parserFunctionFactory->newSciteParserFunctionDefinition(
370 1
				$namespaceExaminer,
371
				$options
372 1
			);
373
374 1
			$parser->setFunctionHook( $name, $definition, $flag );
375
376 1
			list( $name, $definition, $flag ) = $parserFunctionFactory->newReferenceListParserFunctionDefinition();
377
378 1
			$parser->setFunctionHook( $name, $definition, $flag );
379
380 1
			return true;
381
		};
382 16
	}
383
384
}
385