SciteParserFunction   A
last analyzed

Complexity

Total Complexity 27

Size/Duplication

Total Lines 293
Duplicated Lines 0 %

Test Coverage

Coverage 93.14%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 27
eloc 102
c 2
b 0
f 0
dl 0
loc 293
ccs 95
cts 102
cp 0.9314
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A setStrictParserValidationState() 0 2 1
A __construct() 0 7 1
B addPropertyValuesFor() 0 52 6
B tryToMatchCitationTextByPrecept() 0 46 8
A createErrorMessageFor() 0 5 1
B doProcess() 0 64 10
1
<?php
2
3
namespace SCI;
4
5
use SCI\Bibtex\BibtexProcessor;
6
use SMW\NamespaceExaminer;
0 ignored issues
show
Bug introduced by
The type SMW\NamespaceExaminer 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...
7
use SMW\ParserParameterProcessor;
0 ignored issues
show
Bug introduced by
The type SMW\ParserParameterProcessor 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\DataValueFactory;
0 ignored issues
show
Bug introduced by
The type SMW\DataValueFactory 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\DIProperty;
0 ignored issues
show
Bug introduced by
The type SMW\DIProperty 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 SMW\ParserData;
0 ignored issues
show
Bug introduced by
The type SMW\ParserData 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
use SMW\Subobject;
0 ignored issues
show
Bug introduced by
The type SMW\Subobject 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...
12
use Html;
0 ignored issues
show
Bug introduced by
The type Html 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...
13
14
/**
15
 * #scite: is used the create a citation resource with a reference to be
16
 * accessible wiki-wide trough a unique citation key.
17
 *
18
 * [[CiteRef: ... ]] | [[Citation reference:: ...]] is used to create an in-text
19
 * reference link to a citation resource.
20
 *
21
 * @license GNU GPL v2+
22
 * @since 1.0
23
 *
24
 * @author mwjames
25
 */
26
class SciteParserFunction {
27
28
	/**
29
	 * @var ParserData
30
	 */
31
	private $parserData;
32
33
	/**
34
	 * @var NamespaceExaminer
35
	 */
36
	private $namespaceExaminer;
37
38
	/**
39
	 * @var CitationTextTemplateRenderer
40
	 */
41
	private $citationTextTemplateRenderer;
42
43
	/**
44
	 * @var MediaWikiNsContentMapper
45
	 */
46
	private $mediaWikiNsContentMapper;
47
48
	/**
49
	 * @var BibtexProcessor
50
	 */
51
	private $bibtexProcessor;
52
53
	/**
54
	 * @var DataValueFactory
55
	 */
56
	private $dataValueFactory;
57
58
	/**
59
	 * @var boolean
60
	 */
61
	private $strictParserValidationState = true;
62
63
	/**
64
	 * @var array
65
	 */
66
	private $parameters = [];
0 ignored issues
show
introduced by
The private property $parameters is not used, and could be removed.
Loading history...
67
68
	/**
69
	 * @since 1.0
70
	 *
71
	 * @param ParserData $parserData
72
	 * @param NamespaceExaminer $namespaceExaminer
73
	 * @param CitationTextTemplateRenderer $citationTextTemplateRenderer
74
	 * @param MediaWikiNsContentMapper $mediaWikiNsContentMapper
75
	 * @param BibtexProcessor $bibtexProcessor
76
	 */
77 18
	public function __construct( ParserData $parserData, NamespaceExaminer $namespaceExaminer, CitationTextTemplateRenderer $citationTextTemplateRenderer, MediaWikiNsContentMapper $mediaWikiNsContentMapper, BibtexProcessor $bibtexProcessor ) {
78 18
		$this->parserData = $parserData;
79 18
		$this->namespaceExaminer = $namespaceExaminer;
80 18
		$this->citationTextTemplateRenderer = $citationTextTemplateRenderer;
81 18
		$this->mediaWikiNsContentMapper = $mediaWikiNsContentMapper;
82 18
		$this->bibtexProcessor = $bibtexProcessor;
83 18
		$this->dataValueFactory = DataValueFactory::getInstance();
84 18
	}
85
86
	/**
87
	 * @since 1.0
88
	 *
89
	 * @param boolean $strictParserValidationState
90
	 */
91 15
	public function setStrictParserValidationState ( $strictParserValidationState ) {
92 15
		$this->strictParserValidationState = (bool)$strictParserValidationState;
93 15
	}
94
95
	/**
96
	 * Identifiers that have a id-property mapping are to be annotated as semantic
97
	 * property. The property mapped to an identifier should be maintained
98
	 * accordantly with the the expected type it ought to represent
99
	 * (e.g. 'url' => 'Has url', with 'Has url' being of [[Has type::URL]])
100
	 *
101
	 * Only identifiers used in #scite: that have an appropriate mapping
102
	 * will be created as semantic annotation. For example, identifiers important
103
	 * for the citation output are not necessarily notable for a semantic
104
	 * assignment (e.g. 'pages', 'page reference', or 'available').
105
	 *
106
	 * {{#scite:Segon & Booth 2011
107
	 * |type=online
108
	 * |author=Segon, M;Booth, C|+sep=;
109
	 * |year=2011
110
	 * |title=Bribery: what do Australian managers know and what do they do?
111
	 * |journal=Journal of Business Systems, Governance and Ethics
112
	 * |volumn=vol. 6, no. 3
113
	 * |pages=15-29
114
	 * |url=http://www.jbsge.vu.edu.au/issues/vol06no3/Segon_&_Booth.pdf
115
	 * |available=20 October 2014
116
	 * |template=scite-formatter-online
117
	 * }}
118
	 *
119
	 * OR
120
	 *
121
	 * {{#scite:Einstein, Podolsky, and Nathan 1935
122
	 * |bibtex=@article{einstein1935can,
123
	 *  title={Can quantum-mechanical description of physical reality be considered complete?},
124
	 *  author={Einstein, Albert and Podolsky, Boris and Rosen, Nathan},
125
	 *  journal={Physical review},
126
	 *  volume={47},
127
	 *  number={10},
128
	 *  pages={777},
129
	 *  year={1935},
130
	 *  publisher={APS}
131
	 * }
132
	 * |authors=Albert Einstein, Boris Podolsky, Nathan Rosen|+sep=,
133
	 * }}
134
	 *
135
	 * The citation style is determined by the template assigned and stored in
136
	 * its own semantic property. To apply for individual formatting rules, use
137
	 * |template=
138
	 *
139
	 * For any free text assignment use,
140
	 * |citation text=
141
	 *
142
	 * @since 1.0
143
	 *
144
	 * @param ParserParameterProcessor $parserParameterProcessor
145
	 */
146 17
	public function doProcess( ParserParameterProcessor $parserParameterProcessor, PreTextFormatter $preTextFormatter = null ) {
147
148 17
		if ( !$this->namespaceExaminer->isSemanticEnabled( $this->parserData->getTitle()->getNamespace() ) ) {
149 1
			return $this->createErrorMessageFor( 'sci-scite-parser-not-enabled-namespace' );
150
		}
151
152
		// Hopefully the bibtex processor will add all required parameters and values
153 16
		if ( $parserParameterProcessor->hasParameter( 'bibtex' ) ) {
154 1
			$this->bibtexProcessor->doProcess( $parserParameterProcessor );
155
		}
156
157 16
		$reference = str_replace( '_', ' ', (string)$parserParameterProcessor->getFirstParameter() );
158 16
		$type = '';
159
160
		// Explicit reference precedes
161 16
		if ( $parserParameterProcessor->hasParameter( 'reference' ) ) {
162 2
			$reference = $parserParameterProcessor->getParameterValuesFor( 'reference' );
163 2
			$reference = end( $reference );
164
		}
165
166 16
		if ( $reference === '' ) {
167 1
			return $this->createErrorMessageFor( 'sci-scite-parser-no-reference' );
168
		}
169
170
		// Fixed identifier
171 15
		$parserParameterProcessor->addParameter(
172 15
			'reference',
173 15
			$reference
174
		);
175
176 15
		if ( $parserParameterProcessor->hasParameter( 'type' ) ) {
177 14
			$type = $parserParameterProcessor->getParameterValuesFor( 'type' );
178 14
			sort( $type );
179 14
			$type = end( $type );
180
		}
181
182 15
		$returnText = $this->tryToMatchCitationTextByPrecept(
183 15
			$parserParameterProcessor,
184 15
			$reference,
185 15
			$type
186
		);
187
188 15
		$this->addPropertyValuesFor(
189 15
			$parserParameterProcessor,
190 15
			$reference
191
		);
192
193
		// If the parser function returns an empty string then the MW Parser will
194
		// add a <br> section leaving the text around a #scite call adding extra
195
		// white space.
196
		// In order to mitigate the issue when several {{#scite:...}} calls are
197
		// placed next to each other, have the first occurrence to mark its
198
		// existence explicitly by outputting an empty paragraph and so avoid a
199
		// <br> element.
200 15
		if ( $returnText === '' && $this->parserData->getOutput()->getExtensionData( 'sci-parserfunction' ) === null ) {
201 14
			$this->parserData->getOutput()->setExtensionData( 'sci-parserfunction', true );
202 14
			$returnText = '<p></p>';
203
		}
204
205 15
		if ( $parserParameterProcessor->hasParameter( '@show' ) && $preTextFormatter !== null ) {
206
			$returnText = $preTextFormatter->getFormattedSciteFuncFrom( $parserParameterProcessor->getRaw() ) . $returnText;
207
		}
208
209 15
		return $returnText; //array( '', 'noparse' => true, 'isHTML' => true );
210
	}
211
212 15
	private function tryToMatchCitationTextByPrecept( ParserParameterProcessor $parserParameterProcessor, $reference, $type = '' ) {
213
214 15
		$template = '';
215
216 15
		if ( $this->strictParserValidationState && $type === '' ) {
217
218 1
			$parserParameterProcessor->addParameter(
219 1
				DIProperty::TYPE_ERROR,
220 1
				PropertyRegistry::SCI_CITE
221
			);
222
223 1
			return $this->createErrorMessageFor( 'sci-scite-parser-no-type', $reference );
224
		}
225
226
		// An injected text trumps a template
227 14
		if ( $parserParameterProcessor->hasParameter( 'citation text' ) ) {
228 13
			return '';
229
		}
230
231
		// An explicit template precedes the assignment found for the type
232 2
		if ( $parserParameterProcessor->hasParameter( 'template' ) ) {
233 2
			$template = $parserParameterProcessor->getParameterValuesFor( 'template' );
234 2
			$template = trim( end( $template ) );
235 2
		} elseif ( $this->mediaWikiNsContentMapper->findTemplateForType( $type ) !== null ) {
0 ignored issues
show
introduced by
The condition $this->mediaWikiNsConten...ForType($type) !== null is always true.
Loading history...
236 2
			$template = $this->mediaWikiNsContentMapper->findTemplateForType( $type );
237
		}
238
239 2
		if ( $template !== '' ) {
240 2
			$this->citationTextTemplateRenderer->packFieldsForTemplate( $template );
241
242
			// Fixed identifier
243 2
			$parserParameterProcessor->addParameter(
244 2
				'citation text',
245 2
				$this->citationTextTemplateRenderer->renderFor( $parserParameterProcessor->toArray() )
246
			);
247
		} elseif ( $this->strictParserValidationState ) {
248
249
			$parserParameterProcessor->addParameter(
250
				DIProperty::TYPE_ERROR,
251
				PropertyRegistry::SCI_CITE_TEXT
252
			);
253
254
			return $this->createErrorMessageFor( 'sci-scite-parser-no-citation-text', $reference, $type );
255
		}
256
257 2
		return '';
258
	}
259
260 15
	private function addPropertyValuesFor( ParserParameterProcessor $parserParameterProcessor, $reference ) {
261
262 15
		$subobject = new Subobject( $this->parserData->getTitle() );
263 15
		$subobject->setEmptyContainerForId( '_SCITE' . md5( $reference ) );
264
265 15
		$subject = $this->parserData->getSemanticData()->getSubject();
266
267 15
		foreach ( $parserParameterProcessor->toArray() as $key => $values ) {
268
269 15
			if ( $key === DIProperty::TYPE_ERROR ) {
270
271 1
				$value = new DIProperty( end( $values ) );
272
273 1
				$subobject->getSemanticData()->addPropertyObjectValue(
274 1
					new DIProperty( DIProperty::TYPE_ERROR ),
275 1
					$value->getDiWikiPage()
276
				);
277
278 1
				continue;
279
			}
280
281 14
			$property = $this->mediaWikiNsContentMapper->findPropertyForId( $key );
282
283
			// No mapping, no annotation
284 14
			if ( $property === null ) {
285 13
				continue;
286
			}
287
288 14
			foreach ( $values as $value ) {
289
290 14
				$dataValue = $this->dataValueFactory->newPropertyValue(
291 14
						$property,
292 14
						trim( $value ),
293 14
						false,
294 14
						$subject
295
					);
296
297 14
				$subobject->addDataValue( $dataValue );
298
			}
299
		}
300
301 15
		if ( $subobject->getSemanticData()->isEmpty() ) {
302
			return;
303
		}
304
305 15
		$this->parserData->getSemanticData()->addPropertyObjectValue(
306 15
			new DIProperty( PropertyRegistry::SCI_CITE ),
307 15
			$subobject->getContainer()
308
		);
309
310 15
		$this->parserData->getSubject()->setContextReference( 'scitep:' . uniqid() );
311 15
		$this->parserData->pushSemanticDataToParserOutput();
312 15
	}
313
314 3
	private function createErrorMessageFor( $messageKey, $arg1 = '',  $arg2 = '' ) {
315 3
		return \Html::rawElement(
316 3
			'div',
317 3
			[ 'class' => 'smw-callout smw-callout-error' ],
318 3
			wfMessage( $messageKey, $arg1, $arg2 )->inContentLanguage()->text()
0 ignored issues
show
Bug introduced by
The function wfMessage was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

318
			/** @scrutinizer ignore-call */ 
319
   wfMessage( $messageKey, $arg1, $arg2 )->inContentLanguage()->text()
Loading history...
319
		);
320
	}
321
322
}
323