Completed
Push — master ( 2d3850...962c91 )
by mw
10s
created

getBrowseLinkToCitationResourceVisibility()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
ccs 0
cts 0
cp 0
cc 1
eloc 2
nc 1
nop 0
crap 2
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 12
	 *
71 12
	 * @param CitationResourceMatchFinder $citationResourceMatchFinder
72 12
	 * @param CitationReferencePositionJournal $citationReferencePositionJournal
73 12
	 * @param HtmlColumnListRenderer $htmlColumnListRenderer
74 12
	 */
75
	public function __construct( CitationResourceMatchFinder $citationResourceMatchFinder, CitationReferencePositionJournal $citationReferencePositionJournal, HtmlColumnListRenderer $htmlColumnListRenderer ) {
76
		$this->citationResourceMatchFinder = $citationResourceMatchFinder;
77
		$this->citationReferencePositionJournal = $citationReferencePositionJournal;
78
		$this->htmlColumnListRenderer = $htmlColumnListRenderer;
79
	}
80
81 9
	/**
82 9
	 * @since 1.0
83 9
	 *
84
	 * @param integer $citationReferenceCaptionFormat
85
	 */
86
	public function setCitationReferenceCaptionFormat( $citationReferenceCaptionFormat ) {
87
		$this->citationReferenceCaptionFormat = (int)$citationReferenceCaptionFormat;
88
	}
89
90 11
	/**
91 11
	 * @since 1.2
92 11
	 *
93
	 * @param integer $responsiveMonoColumnCharacterBoundLength
94
	 */
95
	public function setResponsiveMonoColumnCharacterBoundLength( $responsiveMonoColumnCharacterBoundLength ) {
96
		$this->responsiveMonoColumnCharacterBoundLength = (int)$responsiveMonoColumnCharacterBoundLength;
97
	}
98
99 10
	/**
100 10
	 * @since 1.0
101
	 *
102
	 * @param integer $numberOfReferenceListColumns
103
	 */
104
	public function setNumberOfReferenceListColumns( $numberOfReferenceListColumns ) {
105
		$this->numberOfReferenceListColumns = (int)$numberOfReferenceListColumns;
106
	}
107
108 10
	/**
109 10
	 * @since 1.0
110 10
	 *
111
	 * @param integer
112
	 */
113
	public function getNumberOfReferenceListColumns() {
114
		return $this->numberOfReferenceListColumns;
115
	}
116
117 10
	/**
118 10
	 * @since 1.0
119
	 *
120
	 * @param string $referenceListType
121
	 */
122
	public function setReferenceListType( $referenceListType ) {
123
		$this->referenceListType = $referenceListType;
124
	}
125
126 11
	/**
127 11
	 * @since 1.0
128 11
	 *
129
	 * @param string
130
	 */
131
	public function getReferenceListType() {
132
		return $this->referenceListType;
133
	}
134
135 10
	/**
136 10
	 * @since 1.0
137
	 *
138
	 * @param boolean $browseLinkToCitationResourceVisibility
139
	 */
140
	public function setBrowseLinkToCitationResourceVisibility( $browseLinkToCitationResourceVisibility ) {
141
		$this->browseLinkToCitationResourceVisibility = (bool)$browseLinkToCitationResourceVisibility;
142
	}
143
144 5
	/**
145 5
	 * @since 1.0
146 5
	 *
147
	 * @param boolean
148
	 */
149
	public function getBrowseLinkToCitationResourceVisibility() {
150
		return $this->browseLinkToCitationResourceVisibility;
151
	}
152
153 5
	/**
154 5
	 * @since 1.0
155 5
	 *
156
	 * @param string $referenceListHeader
157
	 */
158
	public function setReferenceListHeader( $referenceListHeader ) {
159
		$this->referenceListHeader = (string)$referenceListHeader;
160
	}
161
162
	/**
163
	 * @since 1.0
164
	 *
165 10
	 * @param string $referenceListHeaderTocId
166
	 */
167 10
	public function setReferenceListHeaderTocId( $referenceListHeaderTocId ) {
168 2
		$this->referenceListHeaderTocId = (string)$referenceListHeaderTocId;
169
	}
170 2
171 2
	/**
172 9
	 * @since 1.0
173
	 *
174 9
	 * @param DIWikiPage $subject
175
	 * @param array|null $referenceList
176
	 *
177 10
	 * @return string
178 9
	 */
179
	public function doRenderReferenceListFor( DIWikiPage $subject, array $referenceList = null ) {
180
181 1
		if ( $referenceList !== null ) {
182
			$journal = $this->citationReferencePositionJournal->buildJournalForUnboundReferenceList(
183
				$referenceList
184
			);
185
		} else {
186
			$journal = $this->citationReferencePositionJournal->getJournalBySubject(
187
				$subject
188
			);
189
		}
190
191 9
		if ( $journal !== null ) {
192
			return $this->createHtmlFromJournal( $journal );
193 9
		}
194 9
195
		return '';
196 9
	}
197
198 9
	/**
199
	 * The journal is expected to contain:
200
	 *
201 9
	 * 'total' => a number
202
	 * 'reference-list' => array of hashes for references used
203 9
	 * '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 = array();
208
		$length = 0;
209 9
210 9
		foreach ( $journal['reference-pos'] as $referenceAsHash => $linkList ) {
211
212 9
			$citationText = '';
213
			// Get the "human" readable citation key/reference from the hashmap
214 9
			// intead of trying to access the DB/Store
215 9
			$reference = $journal['reference-list'][$referenceAsHash];
216 9
217
			list( $subjects, $citationText ) = $this->findCitationTextFor(
218 9
				$reference
219
			);
220 9
221 9
			$length += mb_strlen( $citationText );
222 9
223
			$flatHtmlReferenceLinks = $this->createFlatHtmlListForReferenceLinks(
224 9
				$linkList,
225
				$referenceAsHash
226 9
			);
227
228 9
			$browseLinks = $this->createBrowseLinksWith(
229 9
				$subjects,
230 9
				$reference,
231
				$citationText
232 9
			);
233
234 9
			$listOfFormattedReferences[] =
235 9
				Html::rawElement(
236 9
					'span',
237 9
					array(
238
						'id'    => 'scite-'. $referenceAsHash,
239 9
						'class' => 'scite-referencelinks'
240 9
					),
241 9
					$flatHtmlReferenceLinks
242
					) . ( $flatHtmlReferenceLinks !== '' ? '&nbsp;' : '' )  .
243 9
				Html::rawElement(
244
					'span',
245
					array(
246 9
						'id'    => 'scite-'. $referenceAsHash,
247
						'class' => 'scite-citation'
248 9
					),
249
					( $browseLinks !== '' ? $browseLinks . '&nbsp;' : '' ) . Html::rawElement(
250
						'span',
251 9
						array( 'class' => 'scite-citation-text' ),
252 9
						$citationText
253 9
					)
254
				);
255 9
		}
256 9
257
		return $this->doFinalizeHtmlForListOfReferences( $listOfFormattedReferences, $length );
258 9
	}
259 1
260 1
	private function doFinalizeHtmlForListOfReferences( $listOfFormattedReferences, $length ) {
261 8
262 8
		$monoClass = ( $length > $this->responsiveMonoColumnCharacterBoundLength ? '' : '-mono' );
263
264
		// #33, #32
265 9
		$this->htmlColumnListRenderer->setColumnListClass(
266 8
			'scite-referencelist' . ( $this->numberOfReferenceListColumns == 0 ? ' responsive-list' . $monoClass : '' )
267 8
		);
268
269 9
		$this->htmlColumnListRenderer->setListType( $this->referenceListType );
270 9
		$this->htmlColumnListRenderer->addContentsByNoIndex( $listOfFormattedReferences );
271 9
272
		if ( $this->numberOfReferenceListColumns == 0 ) {
273 9
			$this->htmlColumnListRenderer->setColumnClass( 'scite-referencelist-columns-responsive'. $monoClass );
274 9
		} else {
275
			$this->htmlColumnListRenderer->setNumberOfColumns( $this->numberOfReferenceListColumns );
276
			$this->htmlColumnListRenderer->setColumnClass( 'scite-referencelist-columns-fixed' );
277 9
		}
278 9
279 9
		if ( $this->referenceListHeader === '' ) {
280
			$this->referenceListHeader = wfMessage( 'sci-referencelist-header' )->text();
281 9
		}
282 9
283 9
		if ( $this->referenceListHeaderTocId === '' ) {
284 9
			$this->referenceListHeaderTocId = $this->referenceListHeader;
285 9
		}
286
287
		return Html::rawElement(
288 9
				'div',
289
				array(
290 9
					'class' => 'scite-content'
291
				),
292 9
				Html::element(
293
				'h2',
294
				array(
295
					'id' => $this->referenceListHeaderTocId
296
				),
297 9
				$this->referenceListHeader
298 9
			) . "\n" . $this->htmlColumnListRenderer->getHtml() . "\n"
299 9
		);
300
	}
301
302 9
	private function findCitationTextFor( $reference ) {
303
304 9
		list( $subjects, $text ) = $this->citationResourceMatchFinder->findCitationTextFor(
305 9
			$reference
306
		);
307 9
308
		// Using Message:parse as shortcut to ensure the text is appropriately
309 7
		// parsed and escaped which saves the trouble to deal with Parser stubobject
310
		return array(
311
			$subjects,
312 7
			wfMessage( 'sci-referencelist-text', $text )->parse()
313
		);
314
	}
315
316 7
	private function createFlatHtmlListForReferenceLinks( array $linkList, $referenceHash ) {
317 6
318 6
		$referenceLinks = array();
319 6
		$class = 'scite-backlinks';
320
321
		foreach ( $linkList as $value ) {
322 7
323 1
			$isOneLinkElement = count( $linkList ) == 1;
324 1
325
			// Split a value of 1-a, 1-b, 2-a into its parts
326 7
			list( $major, $minor ) = explode( '-', $value );
327 7
328
			// Show a simple link similar to what is done on en.wp
329 7
			// for a one-link-reference
330 7
			if ( $isOneLinkElement ) {
331 7
				$minor = '^';
332 7
				$class = 'scite-backlink';
333
			}
334 7
335 9
			// Only display the "full" number for the combination of UL/SCI_CITEREF_NUM
336
			if ( $this->referenceListType === 'ul' && $this->citationReferenceCaptionFormat === SCI_CITEREF_NUM ) {
337 9
				$minor = $isOneLinkElement ? $major : str_replace( '-', '.', $value );
338
			}
339
340 9
			$referenceLinks[] = Html::rawElement(
341
				'a',
342
				array(
343 9
					'href'  => "#scite-ref-{$referenceHash}-" . $value,
344 1
					'class' => $class,
345 1
					'data-citeref-format' => $this->citationReferenceCaptionFormat === SCI_CITEREF_NUM ? 'number' : 'key'
346
				),
347
				$minor
348 1
			);
349
		}
350 1
351
		return implode( ' ', $referenceLinks );
352
	}
353
354 8
	private function createBrowseLinksWith( array $subjects, $reference, $citationText ) {
355 8
356
		// If no text is available at least show the reference
357
		if ( $citationText === '' ) {
358 1
			return Html::rawElement(
359 1
				'span',
360
				array(
361 1
					'class' => 'scite-citation-key'
362
				),
363
				$reference
364
			);
365
		}
366 1
367
		// No browse links means nothing will be displayed
368
		if ( !$this->browseLinkToCitationResourceVisibility ) {
369
			return '';
370
		}
371
372
		$citationResourceLinks = $this->citationResourceMatchFinder->findCitationResourceLinks(
373
			$subjects,
374
			'scite-citation-resourcelink'
375
		);
376
377
		// Normally we should have only one subject to host a citation resource
378
		// for the reference in question but it might be that double assingments
379
		// did occur and therefore show them all
380
		return implode( ' | ', $citationResourceLinks );
381
	}
382
383
}
384