Completed
Push — master ( 619e6f...3384d3 )
by mw
8s
created

HtmlBreadcrumbLinksBuilder::addHtmlDataElement()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 12
ccs 7
cts 7
cp 1
rs 9.4285
cc 2
eloc 7
nc 2
nop 1
crap 2
1
<?php
2
3
namespace SBL;
4
5
use SMW\DIWikiPage;
6
use SMW\DataValueFactory;
7
use Title;
8
use Html;
9
use DummyLinker;
10
11
/**
12
 * @license GNU GPL v2+
13
 * @since 1.0
14
 *
15
 * @author mwjames
16
 */
17
class HtmlBreadcrumbLinksBuilder {
18
19
	/**
20
	 * @var ByPropertyHierarchicalLinksFinder
21
	 */
22
	private $byPropertyHierarchicalLinksFinder;
23
24
	/**
25
	 * @var BySubpageLinksFinder
26
	 */
27
	private $bySubpageLinksFinder;
28
29
	/**
30
	 * @var DummyLinker|null
31
	 */
32
	private $linker = null;
33
34
	/**
35
	 * @var string
36
	 */
37
	private $breadcrumbs = '';
38
39
	/**
40
	 * @var string
41
	 */
42
	private $breadcrumbTrailStyleClass = 'sbl-breadcrumb-trail-boxed';
43
44
	/**
45
	 * @var string
46
	 */
47
	private $breadcrumbDividerStyleClass = 'sbl-breadcrumb-arrow';
48
49
	/**
50
	 * @var boolean
51
	 */
52
	private $isRTL = false;
53
54
	/**
55
	 * @var boolean
56
	 */
57
	private $hasChildren = false;
58
59
	/**
60
	 * @var boolean
61
	 */
62
	private $hideSubpageParent = false;
63
64
	/**
65
	 * @since 1.0
66
	 *
67
	 * @param ByPropertyHierarchicalLinksFinder $byPropertyHierarchicalLinksFinder
68
	 * @param BySubpageLinksFinder $bySubpageLinksFinder
69
	 */
70 6
	public function __construct( ByPropertyHierarchicalLinksFinder $byPropertyHierarchicalLinksFinder, BySubpageLinksFinder $bySubpageLinksFinder ) {
71 6
		$this->byPropertyHierarchicalLinksFinder = $byPropertyHierarchicalLinksFinder;
72 6
		$this->bySubpageLinksFinder = $bySubpageLinksFinder;
73 6
	}
74
75
	/**
76
	 * @since 1.0
77
	 *
78
	 * @param DummyLinker $linker
79
	 */
80 1
	public function setLinker( DummyLinker $linker ) {
81 1
		$this->linker = $linker;
82 1
	}
83
84
	/**
85
	 * @since 1.0
86
	 *
87
	 * @param string $breadcrumbTrailStyleClass
88
	 */
89 1
	public function setBreadcrumbTrailStyleClass( $breadcrumbTrailStyleClass ) {
90 1
		$this->breadcrumbTrailStyleClass = $breadcrumbTrailStyleClass;
91 1
	}
92
93
	/**
94
	 * @since 1.0
95
	 *
96
	 * @param string $breadcrumbDividerStyleClass
97
	 */
98 1
	public function setBreadcrumbDividerStyleClass( $breadcrumbDividerStyleClass ) {
99 1
		$this->breadcrumbDividerStyleClass = $breadcrumbDividerStyleClass;
100 1
	}
101
102
	/**
103
	 * @since 1.3
104
	 *
105
	 * @param boolean $hideSubpageParent
106
	 */
107 1
	public function setHideSubpageParentState( $hideSubpageParent ) {
108 1
		$this->hideSubpageParent = $hideSubpageParent;
109 1
	}
110
111
	/**
112
	 * @since 1.0
113
	 *
114
	 * @param boolean $isRTL
115
	 */
116 1
	public function setRTLDirectionalityState( $isRTL ) {
117 1
		$this->isRTL = $isRTL;
118 1
	}
119
120
	/**
121
	 * @since  1.0
122
	 *
123
	 * @param Title $title
124
	 */
125 4
	public function buildBreadcrumbs( Title $title ) {
126
127 4
		if ( $title->isRedirect() ) {
128 1
			return;
129
		}
130
131
		// Ensure no subobject is used by replacing the fragment
132 3
		$title->setFragment( '' );
133 3
		$subject = DIWikiPage::newFromTitle( $title );
134
135 3
		$this->byPropertyHierarchicalLinksFinder->tryToFindLinksFor( $subject );
136
137 3
		$parents = $this->byPropertyHierarchicalLinksFinder->getParents();
138 3
		$children = $this->byPropertyHierarchicalLinksFinder->getChildren();
139
140 3
		$parents = $this->tryToUseSubpageHierarchyFallback(
141 3
			$subject,
142
			$parents
143 3
		);
144
145 3
		$this->formatToFlatList( $subject, $parents, $children );
146 3
	}
147
148
	/**
149
	 * @since 1.0
150
	 *
151
	 * @return string
152
	 */
153 3
	public function getHtml() {
154
155 3
		if ( $this->breadcrumbs === '' ) {
156 1
			return $this->breadcrumbs;
157
		}
158
159 2
		return Html::rawElement( 'div', array(
160 2
			'id'    => 'sbl-breadcrumbs',
161 2
			'class' => $this->breadcrumbTrailStyleClass,
162 2
			'dir'   => $this->isRTL ? 'rtl' : 'ltr' ),
163 2
			$this->breadcrumbs
164 2
		);
165
	}
166
167 3
	private function tryToUseSubpageHierarchyFallback( $subject, $parents ) {
168
169 3
		if ( $parents !== array() || !$this->bySubpageLinksFinder->canUseSubpageDiscoveryForFallback() ) {
170 2
			return $parents;
171
		}
172
173 1
		$this->bySubpageLinksFinder->tryToFindLinksFor( $subject );
174
175 1
		return $this->bySubpageLinksFinder->getParents();
176
	}
177
178 3
	private function formatToFlatList( DIWikiPage $subject, $parents, $children ) {
179
180 3
		$parent = '';
181
182 3
		foreach ( $parents as $breadcrumb ) {
183 2
			$parent .= $this->wrapHtml( 'parent', $this->getDvShortHtmlText( $breadcrumb, $this->linker ) ) .  $this->wrapHtml( 'right' );
184 3
		}
185
186 3
		$this->hasChildren = count( $children ) > 1;
187
188 3
		list( $child, $data ) = $this->findElementsForChildren( $children  );
189
190 3
		if ( $parent !== '' || $child !== '' ) {
191 2
			$this->breadcrumbs = $parent . $this->wrapHtml( 'location', $this->getDvShortHtmlText( $subject ) ) . $child . $this->addHtmlDataElement( $data );
192 2
		}
193 3
	}
194
195 2
	private function getDvShortHtmlText( $subject, $linker = null ) {
196
197 2
		$displayTitle = '';
198 2
		$dataValue = DataValueFactory::getInstance()->newDataItemValue(
199
			$subject
200 2
		);
201
202
		// 2.4+
203 2
		if ( method_exists( $dataValue , 'getDisplayTitle' ) ) {
204 2
			$displayTitle = $dataValue->getDisplayTitle();
205 2
		}
206
207 2
		$dataValue->setCaption(
208 2
			$this->hideSubpageParent && $displayTitle === '' ? $subject->getTitle()->getSubpageText() : false
209 2
		);
210
211 2
		return $dataValue->getShortHtmlText( $linker );
212
	}
213
214 2
	private function wrapHtml( $subClass, $html = '' ) {
215 2
		return Html::rawElement( 'span', array(
216 2
				'class' => $this->breadcrumbDividerStyleClass . '-' . $subClass,
217 2
				'style' => $subClass === 'child' && $this->hasChildren ? 'font-style:italic;' : ''
218 2
			),
219
			$html
220 2
		);
221
	}
222
223 3
	private function findElementsForChildren( array $children ) {
224
225 3
		$child = '';
226 3
		$data = '';
227
228 3
		foreach ( $children as $breadcrumb ) {
229
230
			// The first child is added as visible element while others
231
			// are added as data-element
232 1
			if ( $child !== '' ) {
233 1
				$this->hasChildren = true;
234 1
				$data .=  $this->addHtmlListElement( $this->getDvShortHtmlText( $breadcrumb, $this->linker ) );
235 1
				continue;
236
			}
237
238 1
			$child .=  $this->wrapHtml( 'left' ) . $this->wrapHtml( 'child', $this->getDvShortHtmlText( $breadcrumb, $this->linker ) );
239 3
		}
240
241 3
		return array( $child, $data );
242
	}
243
244 1
	private function addHtmlListElement( $html = '' ) {
245 1
		return Html::rawElement( 'li', array(), $html );
246
	}
247
248 2
	private function addHtmlDataElement( $data = '' ) {
249
250 2
		if ( $data === '' ) {
251 1
			return '';
252
		}
253
254 1
		return Html::rawElement( 'span', array(
255 1
			'class' => 'sbl-breadcrumb-children',
256 1
			'data-children' => '<ul class="sbl-breadcrumb-children-list">' . $data . '</ul>' ),
257
			''
258 1
		);
259
	}
260
261
}
262