Completed
Pull Request — master (#10)
by mw
01:54
created

setHideSubpageParentState()   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 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 3
ccs 0
cts 3
cp 0
rs 10
cc 1
eloc 2
nc 1
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
	public function setHideSubpageParentState( $hideSubpageParent ) {
108
		$this->hideSubpageParent = $hideSubpageParent;
109
	}
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
		$dataValue = DataValueFactory::getInstance()->newDataItemValue(
198
			$subject
199 2
		);
200
201 2
		$dataValue->setCaption(
202 2
			$this->hideSubpageParent ? $subject->getTitle()->getSubpageText() : false
203 2
		);
204
205 2
		return $dataValue->getShortHtmlText( $linker );
206
	}
207
208 2
	private function wrapHtml( $subClass, $html = '' ) {
209 2
		return Html::rawElement( 'span', array(
210 2
				'class' => $this->breadcrumbDividerStyleClass . '-' . $subClass,
211 2
				'style' => $subClass === 'child' && $this->hasChildren ? 'font-style:italic;' : ''
212 2
			),
213
			$html
214 2
		);
215
	}
216
217 3
	private function findElementsForChildren( array $children ) {
218
219 3
		$child = '';
220 3
		$data = '';
221
222 3
		foreach ( $children as $breadcrumb ) {
223
224
			// The first child is added as visible element while others
225
			// are added as data-element
226 1
			if ( $child !== '' ) {
227 1
				$this->hasChildren = true;
228 1
				$data .=  $this->addHtmlListElement( $this->getDvShortHtmlText( $breadcrumb, $this->linker ) );
229 1
				continue;
230
			}
231
232 1
			$child .=  $this->wrapHtml( 'left' ) . $this->wrapHtml( 'child', $this->getDvShortHtmlText( $breadcrumb, $this->linker ) );
233 3
		}
234
235 3
		return array( $child, $data );
236
	}
237
238 1
	private function addHtmlListElement( $html = '' ) {
239 1
		return Html::rawElement( 'li', array(), $html );
240
	}
241
242 2
	private function addHtmlDataElement( $data = '' ) {
243
244 2
		if ( $data === '' ) {
245 1
			return '';
246
		}
247
248 1
		return Html::rawElement( 'span', array(
249 1
			'class' => 'sbl-breadcrumb-children',
250 1
			'data-children' => $data ),
251
			''
252 1
		);
253
	}
254
255
}
256