Completed
Push — master ( 1b8948...05c133 )
by mw
20:16
created

createHtmlFromJournal()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 65
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 39
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 65
ccs 39
cts 39
cp 1
rs 8.6195
c 0
b 0
f 0
cc 5
eloc 39
nc 5
nop 1
crap 5

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 Parser;
6
use Html;
7
use SMW\MediaWiki\Renderer\HtmlColumnListRenderer;
8
use SMW\DIWikiPage;
9
10
/**
11
 * @license GNU GPL v2+
12
 * @since 1.0
13
 *
14
 * @author mwjames
15
 */
16
class ReferenceListOutputRenderer {
17
18
	/**
19
	 * @var CitationResourceMatchFinder
20
	 */
21
	private $citationResourceMatchFinder;
22
23
	/**
24
	 * @var CitationReferencePositionJournal
25
	 */
26
	private $citationReferencePositionJournal;
27
28
	/**
29
	 * @var HtmlColumnListRenderer
30
	 */
31
	private $htmlColumnListRenderer;
32
33
	/**
34
	 * @var integer
35
	 */
36
	private $numberOfReferenceListColumns = 0;
37
38
	/**
39
	 * @var boolean
40
	 */
41
	private $browseLinkToCitationResourceVisibility = true;
42
43
	/**
44
	 * @var string
45
	 */
46
	private $referenceListType = 'ol';
47
48
	/**
49
	 * @var string
50
	 */
51
	private $referenceListHeader = '';
52
53
	/**
54
	 * @var string
55
	 */
56
	private $referenceListHeaderTocId = '';
57
58
	/**
59
	 * @var integer
60
	 */
61
	private $citationReferenceCaptionFormat = SCI_CITEREF_NUM;
62
63
	/**
64
	 * @var integer
65
	 */
66
	private $responsiveMonoColumnCharacterBoundLength = 400;
67
68
	/**
69
	 * @since  1.0
70
	 *
71
	 * @param CitationResourceMatchFinder $citationResourceMatchFinder
72
	 * @param CitationReferencePositionJournal $citationReferencePositionJournal
73
	 * @param HtmlColumnListRenderer $htmlColumnListRenderer
74
	 */
75 12
	public function __construct( CitationResourceMatchFinder $citationResourceMatchFinder, CitationReferencePositionJournal $citationReferencePositionJournal, HtmlColumnListRenderer $htmlColumnListRenderer ) {
76 12
		$this->citationResourceMatchFinder = $citationResourceMatchFinder;
77 12
		$this->citationReferencePositionJournal = $citationReferencePositionJournal;
78 12
		$this->htmlColumnListRenderer = $htmlColumnListRenderer;
79 12
	}
80
81
	/**
82
	 * @since 1.0
83
	 *
84
	 * @param integer $citationReferenceCaptionFormat
85
	 */
86 9
	public function setCitationReferenceCaptionFormat( $citationReferenceCaptionFormat ) {
87 9
		$this->citationReferenceCaptionFormat = (int)$citationReferenceCaptionFormat;
88 9
	}
89
90
	/**
91
	 * @since 1.2
92
	 *
93
	 * @param integer $responsiveMonoColumnCharacterBoundLength
94
	 */
95 10
	public function setResponsiveMonoColumnCharacterBoundLength( $responsiveMonoColumnCharacterBoundLength ) {
96 10
		$this->responsiveMonoColumnCharacterBoundLength = (int)$responsiveMonoColumnCharacterBoundLength;
97 10
	}
98
99
	/**
100
	 * @since 1.0
101
	 *
102
	 * @param integer $numberOfReferenceListColumns
103
	 */
104 11
	public function setNumberOfReferenceListColumns( $numberOfReferenceListColumns ) {
105 11
		$this->numberOfReferenceListColumns = (int)$numberOfReferenceListColumns;
106 11
	}
107
108
	/**
109
	 * @since 1.0
110
	 *
111
	 * @param integer
112
	 */
113 10
	public function getNumberOfReferenceListColumns() {
114 10
		return $this->numberOfReferenceListColumns;
115
	}
116
117
	/**
118
	 * @since 1.0
119
	 *
120
	 * @param string $referenceListType
121
	 */
122 10
	public function setReferenceListType( $referenceListType ) {
123 10
		$this->referenceListType = $referenceListType;
124 10
	}
125
126
	/**
127
	 * @since 1.0
128
	 *
129
	 * @param string
130
	 */
131 10
	public function getReferenceListType() {
132 10
		return $this->referenceListType;
133
	}
134
135
	/**
136
	 * @since 1.0
137
	 *
138
	 * @param boolean $browseLinkToCitationResourceVisibility
139
	 */
140 11
	public function setBrowseLinkToCitationResourceVisibility( $browseLinkToCitationResourceVisibility ) {
141 11
		$this->browseLinkToCitationResourceVisibility = (bool)$browseLinkToCitationResourceVisibility;
142 11
	}
143
144
	/**
145
	 * @since 1.0
146
	 *
147
	 * @param boolean
148
	 */
149 10
	public function getBrowseLinkToCitationResourceVisibility() {
150 10
		return $this->browseLinkToCitationResourceVisibility;
151
	}
152
153
	/**
154
	 * @since 1.0
155
	 *
156
	 * @param string $referenceListHeader
157
	 */
158 5
	public function setReferenceListHeader( $referenceListHeader ) {
159 5
		$this->referenceListHeader = (string)$referenceListHeader;
160 5
	}
161
162
	/**
163
	 * @since 1.0
164
	 *
165
	 * @param string $referenceListHeaderTocId
166
	 */
167 5
	public function setReferenceListHeaderTocId( $referenceListHeaderTocId ) {
168 5
		$this->referenceListHeaderTocId = (string)$referenceListHeaderTocId;
169 5
	}
170
171
	/**
172
	 * @since 1.0
173
	 *
174
	 * @param DIWikiPage $subject
175
	 * @param array|null $referenceList
176
	 *
177
	 * @return string
178
	 */
179 10
	public function doRenderReferenceListFor( DIWikiPage $subject, array $referenceList = null ) {
180
181 10
		if ( $referenceList !== null ) {
182 2
			$journal = $this->citationReferencePositionJournal->buildJournalForUnboundReferenceList(
183
				$referenceList
184 2
			);
185 2
		} else {
186 9
			$journal = $this->citationReferencePositionJournal->getJournalBySubject(
187
				$subject
188 9
			);
189
		}
190
191 10
		if ( $journal !== null ) {
192 9
			return $this->createHtmlFromJournal( $journal );
193
		}
194
195 1
		return '';
196
	}
197
198
	/**
199
	 * The journal is expected to contain:
200
	 *
201
	 * 'total' => a number
202
	 * 'reference-list' => array of hashes for references used
203
	 * 'reference-pos'  => individual reference links (1-a, 1-b) assigned to a hash
204
	 */
205 9
	private function createHtmlFromJournal( array $journal ) {
206
207 9
		$listOfFormattedReferences = [];
208 9
		$targetList = [];
209
		$length = 0;
210 9
211
		foreach ( $journal['reference-pos'] as $hash => $linkList ) {
212 9
213
			$citationText = '';
214
			// Get the "human" readable citation key/reference from the hashmap
215 9
			// intead of trying to access the DB/Store
216
			$reference = $journal['reference-list'][$hash];
217 9
218
			list( $subjects, $citationText ) = $this->findCitationTextFor(
219 9
				$reference
220
			);
221 9
222
			$length += mb_strlen( $citationText );
223 9
224 9
			$flatHtmlReferenceLinks = $this->createFlatHtmlListForReferenceLinks(
225
				$linkList,
226 9
				$hash
227
			);
228 9
229 9
			$browseLinks = $this->createBrowseLinksWith(
230 9
				$subjects,
231
				$reference,
232 9
				$citationText
233
			);
234 9
235 9
			if ( method_exists( $this->htmlColumnListRenderer, 'setItemAttributes' ) ) {
236 9
				$attribs = [
237
					'class' => 'scite-referencelinks'
238 9
				];
239
			} else {
240 9
				$attribs = [
241
					'id' => 'scite-'. $hash,
242 9
					'class' => 'scite-referencelinks'
243 9
				];
244 9
			}
245
246 9
			$ref = Html::rawElement(
247
				'span',
248 9
				$attribs,
249 9
				$flatHtmlReferenceLinks
250 9
			) .
251 9
			( $flatHtmlReferenceLinks !== '' ? '&nbsp;' : '' )  .
252
			Html::rawElement(
253 9
				'span',
254 9
				[
255 9
					'class' => 'scite-citation'
256
				],
257 9
				( $browseLinks !== '' ? $browseLinks . '&nbsp;' : '' ) . Html::rawElement(
258
					'span',
259
					[ 'class' => 'scite-citation-text' ],
260 9
					$citationText
261
				)
262 9
			);
263
264
			$listOfFormattedReferences[] = $ref;
265 9
			$targetList[md5($ref)] = [ 'id' => 'scite-'. $hash ];
266 9
		}
267 9
268
		return $this->makeList( $listOfFormattedReferences, $targetList, $length );
269 9
	}
270 9
271
	private function makeList( $listOfFormattedReferences, $targetList, $length ) {
272 9
273 1
		$monoClass = ( $length > $this->responsiveMonoColumnCharacterBoundLength ? '' : '-mono' );
274 1
275 8
		// #33, #32
276 8
		$this->htmlColumnListRenderer->setColumnListClass(
277
			'scite-referencelist' . ( $this->numberOfReferenceListColumns == 0 ? ' responsive-list' . $monoClass : '' )
278
		);
279 9
280 8
		$this->htmlColumnListRenderer->setListType( $this->referenceListType );
281 8
		$this->htmlColumnListRenderer->addContentsByNoIndex( $listOfFormattedReferences );
282
283 9
		if ( method_exists( $this->htmlColumnListRenderer, 'setItemAttributes' ) ) {
284 9
			$this->htmlColumnListRenderer->setItemAttributes( $targetList );
0 ignored issues
show
Bug introduced by
The method setItemAttributes() does not seem to exist on object<SMW\MediaWiki\Ren...HtmlColumnListRenderer>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
285 9
		}
286
287 9
		if ( $this->numberOfReferenceListColumns == 0 ) {
288 9
			$this->htmlColumnListRenderer->setColumnClass( 'scite-referencelist-columns-responsive'. $monoClass );
289
		} else {
290
			$this->htmlColumnListRenderer->setNumberOfColumns( $this->numberOfReferenceListColumns );
291 9
			$this->htmlColumnListRenderer->setColumnClass( 'scite-referencelist-columns-fixed' );
292 9
		}
293 9
294
		if ( $this->referenceListHeader === '' ) {
295 9
			$this->referenceListHeader = wfMessage( 'sci-referencelist-header' )->text();
296 9
		}
297 9
298 9
		if ( $this->referenceListHeaderTocId === '' ) {
299 9
			$this->referenceListHeaderTocId = $this->referenceListHeader;
300
		}
301
302 9
		return Html::rawElement(
303
				'div',
304 9
				[
305
					'class' => 'scite-content'
306 9
				],
307
				Html::element(
308
				'h2',
309
				[
310
					'id' => $this->referenceListHeaderTocId
311 9
				],
312 9
				$this->referenceListHeader
313 9
			) . "\n" . $this->htmlColumnListRenderer->getHtml() . "\n"
314
		);
315
	}
316 9
317
	private function findCitationTextFor( $reference ) {
318 9
319 9
		list( $subjects, $text ) = $this->citationResourceMatchFinder->findCitationTextFor(
320
			$reference
321 9
		);
322
323 7
		// Using Message:parse as shortcut to ensure the text is appropriately
324
		// parsed and escaped which saves the trouble to deal with Parser stubobject
325
		return [
326 7
			$subjects,
327
			wfMessage( 'sci-referencelist-text', $text )->parse()
328
		];
329
	}
330 7
331 6
	private function createFlatHtmlListForReferenceLinks( array $linkList, $referenceHash ) {
332 6
333 6
		$referenceLinks = [];
334
		$class = 'scite-backlinks';
335
336 7
		foreach ( $linkList as $value ) {
337 1
338 1
			$isOneLinkElement = count( $linkList ) == 1;
339
340 7
			// Split a value of 1-a, 1-b, 2-a into its parts
341 7
			list( $major, $minor ) = explode( '-', $value );
342
343 7
			// Show a simple link similar to what is done on en.wp
344 7
			// for a one-link-reference
345 7
			if ( $isOneLinkElement ) {
346 7
				$minor = '^';
347
				$class = 'scite-backlink';
348 7
			}
349 9
350
			// Only display the "full" number for the combination of UL/SCI_CITEREF_NUM
351 9
			if ( $this->referenceListType === 'ul' && $this->citationReferenceCaptionFormat === SCI_CITEREF_NUM ) {
352
				$minor = $isOneLinkElement ? $major : str_replace( '-', '.', $value );
353
			}
354 9
355
			$referenceLinks[] = Html::rawElement(
356
				'a',
357 9
				[
358 1
					'href'  => "#scite-ref-{$referenceHash}-" . $value,
359 1
					'class' => $class,
360
					'data-citeref-format' => $this->citationReferenceCaptionFormat === SCI_CITEREF_NUM ? 'number' : 'key'
361
				],
362 1
				$minor
363
			);
364 1
		}
365
366
		return implode( '&nbsp;', $referenceLinks );
367
	}
368 8
369 8
	private function createBrowseLinksWith( array $subjects, $reference, $citationText ) {
370
371
		// If no text is available at least show the reference
372 1
		if ( $citationText === '' ) {
373 1
			return Html::rawElement(
374
				'span',
375 1
				[
376
					'class' => 'scite-citation-key'
377
				],
378
				$reference
379
			);
380 1
		}
381
382
		// No browse links means nothing will be displayed
383
		if ( !$this->browseLinkToCitationResourceVisibility ) {
384
			return '';
385
		}
386
387
		$citationResourceLinks = $this->citationResourceMatchFinder->findCitationResourceLinks(
388
			$subjects,
389
			'scite-citation-resourcelink'
390
		);
391
392
		// Normally we should have only one subject to host a citation resource
393
		// for the reference in question but it might be that double assingments
394
		// did occur and therefore show them all
395
		return implode( ' | ', $citationResourceLinks );
396
	}
397
398
}
399