Completed
Push — master ( 552173...c8702c )
by Tobias
12:00 queued 43s
created

Panel   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 181
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 98.78%

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 2
dl 0
loc 181
ccs 81
cts 82
cp 0.9878
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
B placeMe() 0 33 2
A calculateOuterClassAttribute() 0 6 1
A calculateInnerClassAttribute() 0 11 3
A getDataParent() 0 7 4
A isCollapsible() 0 3 1
A isInsideAccordion() 0 7 3
B processAdditionToPanel() 0 37 6
1
<?php
2
/**
3
 * Contains the component class for rendering a panel.
4
 *
5
 * @copyright (C) 2018, Tobias Oetterer, Paderborn University
6
 * @license       https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License, version 3 (or later)
7
 *
8
 * This file is part of the MediaWiki extension BootstrapComponents.
9
 * The BootstrapComponents extension is free software: you can redistribute it
10
 * and/or modify it under the terms of the GNU General Public License as published
11
 * by the Free Software Foundation, either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * The BootstrapComponents extension is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
21
 *
22
 * @file
23
 * @ingroup       BootstrapComponents
24
 * @author        Tobias Oetterer
25
 */
26
27
namespace BootstrapComponents\Components;
28
29
use BootstrapComponents\ComponentLibrary;
30
use BootstrapComponents\AbstractComponent;
31
use BootstrapComponents\NestingController;
32
use BootstrapComponents\ParserOutputHelper;
33
use \Html;
34
use \MWException;
35
36
/**
37
 * Class Panel
38
 *
39
 * Class for component 'panel'
40
 *
41
 * @see   https://github.com/oetterer/BootstrapComponents/blob/master/docs/components.md#Panel
42
 * @since 1.0
43
 */
44
class Panel extends AbstractComponent {
45
46
	/**
47
	 * Indicates, whether this panel is collapsible
48
	 *
49
	 * @var bool $collapsible
50
	 */
51
	private $collapsible;
52
53
	/**
54
	 * If true, indicates that we are inside an accordion
55
	 *
56
	 * @var bool $insideAccordion
57
	 */
58
	private $insideAccordion;
59
60
	/**
61
	 * Panel constructor.
62
	 *
63
	 * @param ComponentLibrary   $componentLibrary
64
	 * @param ParserOutputHelper $parserOutputHelper
65
	 * @param NestingController  $nestingController
66
	 *
67
	 * @throws MWException
68
	 */
69 12
	public function __construct( $componentLibrary, $parserOutputHelper, $nestingController ) {
70 12
		parent::__construct( $componentLibrary, $parserOutputHelper, $nestingController );
71 12
		$this->collapsible = false;
72 12
		$this->insideAccordion = $this->isInsideAccordion();
73 12
	}
74
75
	/**
76
	 * @inheritdoc
77
	 *
78
	 * @param string $input
79
	 */
80 11
	public function placeMe( $input ) {
81
82 11
		$this->collapsible = $this->getValueFor( 'collapsible' ) || $this->isInsideAccordion();
83
84 11
		$outerClass = $this->calculateOuterClassAttribute();
85 11
		$innerClass = $this->calculateInnerClassAttribute();
86
87 11
		list ( $outerClass, $style ) = $this->processCss( $outerClass, [] );
88
89 11
		return Html::rawElement(
90 11
			'div',
91
			[
92 11
				'class' => $this->arrayToString( $outerClass, ' ' ),
93 11
				'style' => $this->arrayToString( $style, ';' ),
94 11
			],
95 11
			$this->processAdditionToPanel( 'heading' )
96 11
			. Html::rawElement(
97 11
				'div',
98
				[
99 11
					'id'    => $this->getId(),
100 11
					'class' => $this->arrayToString( $innerClass, ' ' ),
101 11
				],
102 11
				Html::rawElement(
103 11
					'div',
104
					[
105 11
						'class' => 'panel-body',
106 11
					],
107
					$input
108 11
				)
109 11
				. $this->processAdditionToPanel( 'footer' )
110 11
			)
111 11
		);
112
	}
113
114
	/**
115
	 * Calculates the css class string from the attributes array
116
	 *
117
	 * @return string[]
118
	 */
119 11
	private function calculateOuterClassAttribute() {
120
121 11
		$class = [ 'panel' ];
122 11
		$class[] = 'panel-' . $this->getValueFor( 'color', 'default' );
123 11
		return $class;
124
	}
125
126
	/**
127
	 * Calculates the css class from the attributes array for the "inner" section (div around body and footer)
128
	 *
129
	 * @return bool|array
130
	 */
131 11
	private function calculateInnerClassAttribute() {
132
133 11
		$class = false;
134 11
		if ( $this->isCollapsible() ) {
135 7
			$class = [ 'panel-collapse', 'collapse', 'fade' ];
136 7
			if ( $this->getValueFor( 'active' ) ) {
137 2
				$class[] = 'in';
138 2
			}
139 7
		}
140 11
		return $class;
141
	}
142
143
	/**
144
	 * Returns my data parent attribute (the one to put in the heading toggle when inside an accordion).
145
	 *
146
	 * @return string
147
	 */
148 7
	private function getDataParent() {
149 7
		$parent = $this->getParentComponent();
150 7
		if ( $parent && $this->isInsideAccordion() && $parent->getId() ) {
151 5
			return '#' . $parent->getId();
152
		}
153 2
		return false;
154
	}
155
156
	/**
157
	 * Indicates, whether this panel is collapsible or not.
158
	 *
159
	 * @return bool
160
	 */
161 11
	private function isCollapsible() {
162 11
		return $this->collapsible;
163
	}
164
165
	/**
166
	 * Checks, whether this panel is directly inside an accordion.
167
	 *
168
	 * @return bool
169
	 */
170 12
	private function isInsideAccordion() {
171 12
		if ( !is_null( $this->insideAccordion ) ) {
172 10
			return $this->insideAccordion;
173
		}
174 12
		$parent = $this->getParentComponent();
175 12
		return $this->insideAccordion = ($parent && ($this->getParentComponent()->getComponentName() == 'accordion'));
176
	}
177
178
	/**
179
	 * Processes the addition heading or footer.
180
	 *
181
	 * This examines $attributes and produces an appropriate heading or footing if corresponding data is found.
182
	 *
183
	 * @param string $type
184
	 *
185
	 * @return string
186
	 */
187 11
	private function processAdditionToPanel( $type ) {
188 11
		$inside = $this->getValueFor( $type );
189
190 11
		if ( empty( $inside ) ) {
191 7
			if ( $type == 'heading' && $this->isInsideAccordion() ) {
192 2
				$inside = $this->getId();
193 2
			} else {
194 7
				return '';
195
			}
196 2
		}
197
		$newAttributes = [
198 8
			'class' => 'panel-' . $type,
199 8
		];
200 8
		if ( $type == 'heading' ) {
201 8
			if ( $this->isCollapsible() ) {
202
				$newAttributes += [
203 7
						'data-parent' => $this->getDataParent(),
204 7
						'data-toggle' => 'collapse',
205 7
						'href'        => '#' . $this->getId(),
206
					];
207 7
			}
208 8
			$inside = Html::rawElement(
209 8
				'h4',
210
				[
211 8
					'class' => 'panel-title',
212 8
					'style' => 'margin-top:0;padding-top:0;',
213 8
				],
214
				$inside
215 8
			);
216 8
		}
217
218 8
		return Html::rawElement(
219 8
			'div',
220 8
			$newAttributes,
221
			$inside
222 8
		);
223
	}
224
}