Completed
Pull Request — master (#604)
by Tortue
07:26
created

Group::getFormattedLabel()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
namespace Former\Form;
3
4
use BadMethodCallException;
5
use Former\Helpers;
6
use HtmlObject\Element;
7
use HtmlObject\Traits\Tag;
8
use Illuminate\Container\Container;
9
use Illuminate\Support\Arr;
10
11
/**
12
 * Helper class to build groups
13
 */
14
class Group extends Tag
15
{
16
	/**
17
	 * The Container
18
	 *
19
	 * @var Container
20
	 */
21
	protected $app;
22
23
	/**
24
	 * The current state of the group
25
	 *
26
	 * @var string
27
	 */
28
	protected $state = null;
29
30
	/**
31
	 * Whether the field should be displayed raw or not
32
	 *
33
	 * @var boolean
34
	 */
35
	protected $raw = false;
36
37
	/**
38
	 * The group label
39
	 *
40
	 * @var Element
41
	 */
42
	protected $label;
43
44
	/**
45
	 * The group help
46
	 *
47
	 * @var array
48
	 */
49
	protected $help = array();
50
51
	/**
52
	 * An array of elements to preprend the field
53
	 *
54
	 * @var array
55
	 */
56
	protected $prepend = array();
57
58
	/**
59
	 * An array of elements to append the field
60
	 *
61
	 * @var array
62
	 */
63
	protected $append = array();
64
65
	/**
66
	 * The field validations to be checked for errors
67
	 *
68
	 * @var array
69
	 */
70
	protected $validations = array();
71
72
	/**
73
	 * The group's element
74
	 *
75
	 * @var string
76
	 */
77
	protected $element = 'div';
78
79
	/**
80
	 * Whether a custom group is opened or not
81
	 *
82
	 * @var boolean
83
	 */
84
	public static $opened = false;
85
86
	/**
87
	 * The custom group that is open
88
	 *
89
	 * @var Former\Form\Group
90
	 */
91
	public static $openGroup = null;
92
93
	////////////////////////////////////////////////////////////////////
94
	/////////////////////////// CORE METHODS ///////////////////////////
95
	////////////////////////////////////////////////////////////////////
96
97
	/**
98
	 * Creates a group
99
	 *
100
	 * @param string $label Its label
101
	 */
102
	public function __construct(Container $app, $label, $validations = null)
103
	{
104
		// Get special classes
105
		$this->app = $app;
106
		$this->addClass($this->app['former.framework']->getGroupClasses());
107
108
		// Invisible if Nude
109
		if ($this->app['former.framework']->is('Nude')) {
110
			$this->element = '';
111
		}
112
113
		// Set group label
114
		if ($label) {
115
			$this->setLabel($label);
116
		}
117
118
		// Set validations used to override groups own conclusions
119
		$this->validations = (array) $validations;
120
	}
121
122
	/**
123
	 * Prints out the opening of the Control Group
124
	 *
125
	 * @return string A control group opening tag
126
	 */
127
	public function __toString()
128
	{
129
		return $this->open().$this->getFormattedLabel();
130
	}
131
132
	/**
133
	 * Opens a group
134
	 *
135
	 * @return string Opening tag
136
	 */
137
	public function open()
138
	{
139
		if ($this->getErrors()) {
140
			$this->state($this->app['former.framework']->errorState());
141
		}
142
143
		// Retrieve state and append it to classes
144
		if ($this->state) {
145
			$this->addClass($this->state);
146
		}
147
148
		// Required state
149
		if ($this->app->bound('former.field') and $this->app['former.field']->isRequired()) {
150
			$this->addClass($this->app['former']->getOption('required_class'));
151
		}
152
153
		return parent::open();
154
	}
155
156
	/**
157
	 * Set the contents of the current group
158
	 *
159
	 * @param string $contents The group contents
160
	 *
161
	 * @return string A group
162
	 */
163
	public function contents($contents)
164
	{
165
		return $this->wrap($contents, $this->getFormattedLabel());
0 ignored issues
show
Documentation introduced by
$this->getFormattedLabel() is of type false|object<HtmlObject\Element>, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
166
	}
167
168
	/**
169
	 * Wrap a Field with the current group
170
	 *
171
	 * @param  \Former\Traits\Field $field A Field instance
172
	 *
173
	 * @return string        A group
174
	 */
175
	public function wrapField($field)
176
	{
177
		$label = $this->getLabel($field);
178
		$field = $this->prependAppend($field);
0 ignored issues
show
Documentation introduced by
$field is of type object<Former\Traits\Field>, but the function expects a object<Former\Form\Field>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
179
		$field .= $this->getHelp();
180
181
		return $this->wrap($field, $label);
182
	}
183
184
	////////////////////////////////////////////////////////////////////
185
	//////////////////////////// FIELD METHODS /////////////////////////
186
	////////////////////////////////////////////////////////////////////
187
188
	/**
189
	 * Set the state of the group
190
	 *
191
	 * @param  string $state A Bootstrap state class
192
	 */
193
	public function state($state)
194
	{
195
		// Filter state
196
		$state = $this->app['former.framework']->filterState($state);
197
198
		$this->state = $state;
199
	}
200
201
	/**
202
	 * Set a class on the Group
203
	 *
204
	 * @param string $class The class to add
205
	 */
206
	public function addGroupClass($class)
207
	{
208
		$this->addClass($class);
209
	}
210
211
	/**
212
	 * Set a class on the Label
213
	 *
214
	 * @param string $class The class to add on the Label
215
	 */
216
	public function addLabelClass($class)
217
	{
218
		// Don't add a label class if it isn't an Element instance
219
		if (!$this->label instanceof Element) {
220
			return $this;
221
		}
222
223
		$this->label->addClass($class);
224
225
		return $this;
226
	}
227
228
	/**
229
	 * Adds a label to the group
230
	 *
231
	 * @param  string $label A label
232
	 */
233
	public function setLabel($label)
234
	{
235
		if (!$label instanceof Element) {
236
			$label = Helpers::translate($label);
237
			$label = Element::create('label', $label)->for($label);
238
		}
239
240
		$this->label = $label;
241
	}
242
243
	/**
244
	 * Get the formatted group label
245
	 *
246
	 * @return string|null
247
	 */
248
	public function getFormattedLabel()
249
	{
250
		if (!$this->label) {
251
			return false;
252
		}
253
254
		return $this->label->addClass($this->app['former.framework']->getLabelClasses());
255
	}
256
257
	/**
258
	 * Disables the control group for the current field
259
	 */
260
	public function raw()
261
	{
262
		$this->raw = true;
263
	}
264
265
	/**
266
	 * Check if the current group is to be displayed or not
267
	 *
268
	 * @return boolean
269
	 */
270
	public function isRaw()
271
	{
272
		return (bool) $this->raw;
273
	}
274
275
	////////////////////////////////////////////////////////////////////
276
	///////////////////////////// HELP BLOCKS //////////////////////////
277
	////////////////////////////////////////////////////////////////////
278
279
	/**
280
	 * Alias for inlineHelp
281
	 *
282
	 * @param  string $help       The help text
283
	 * @param  array  $attributes Facultative attributes
284
	 */
285
	public function help($help, $attributes = array())
286
	{
287
		return $this->inlineHelp($help, $attributes);
288
	}
289
290
	/**
291
	 * Add an inline help
292
	 *
293
	 * @param  string $help       The help text
294
	 * @param  array  $attributes Facultative attributes
295
	 */
296
	public function inlineHelp($help, $attributes = array())
297
	{
298
		// If no help text, do nothing
299
		if (!$help) {
300
			return false;
301
		}
302
303
		$this->help['inline'] = $this->app['former.framework']->createHelp($help, $attributes);
304
	}
305
306
	/**
307
	 * Add an block help
308
	 *
309
	 * @param  string $help       The help text
310
	 * @param  array  $attributes Facultative attributes
311
	 */
312
	public function blockHelp($help, $attributes = array())
313
	{
314
		// Reserved method
315
		if ($this->app['former.framework']->isnt('TwitterBootstrap') &&
316
		    $this->app['former.framework']->isnt('TwitterBootstrap3') &&
317
		    $this->app['former.framework']->isnt('TwitterBootstrap4')
318
		) {
319
			throw new BadMethodCallException('This method is only available on the Bootstrap framework');
320
		}
321
322
		// If no help text, do nothing
323
		if (!$help) {
324
			return false;
325
		}
326
327
		$this->help['block'] = $this->app['former.framework']->createBlockHelp($help, $attributes);
328
	}
329
330
	////////////////////////////////////////////////////////////////////
331
	///////////////////////// PREPEND/APPEND METHODS ///////////////////
332
	////////////////////////////////////////////////////////////////////
333
334
	/**
335
	 * Prepend elements to the field
336
	 */
337
	public function prepend()
338
	{
339
		$this->placeAround(func_get_args(), 'prepend');
340
	}
341
342
	/**
343
	 * Append elements to the field
344
	 */
345
	public function append()
346
	{
347
		$this->placeAround(func_get_args(), 'append');
348
	}
349
350
	/**
351
	 * Prepends an icon to a field
352
	 *
353
	 * @param string $icon       The icon to prepend
354
	 * @param array  $attributes Its attributes
355
	 */
356
	public function prependIcon($icon, $attributes = array(), $iconSettings = array())
357
	{
358
		$icon = $this->app['former.framework']->createIcon($icon, $attributes, $iconSettings);
359
360
		$this->prepend($icon);
361
	}
362
363
	/**
364
	 * Append an icon to a field
365
	 *
366
	 * @param string $icon       The icon to prepend
367
	 * @param array  $attributes Its attributes
368
	 */
369
	public function appendIcon($icon, $attributes = array(), $iconSettings = array())
370
	{
371
		$icon = $this->app['former.framework']->createIcon($icon, $attributes, $iconSettings);
372
373
		$this->append($icon);
374
	}
375
376
	////////////////////////////////////////////////////////////////////
377
	//////////////////////////////// HELPERS ///////////////////////////
378
	////////////////////////////////////////////////////////////////////
379
380
	/**
381
	 * Get the errors for the group
382
	 *
383
	 * @return string
384
	 */
385
	public function getErrors()
386
	{
387
		$errors = '';
388
389
		if (!self::$opened) {
390
391
			// for non-custom groups, normal error handling applies
392
			$errors = $this->app['former']->getErrors();
393
		} elseif (!empty($this->validations)) {
394
395
			// error handling only when validations specified for custom groups
396
			foreach ($this->validations as $validation) {
397
				$errors .= $this->app['former']->getErrors($validation);
398
			}
399
		}
400
401
		return $errors;
402
	}
403
404
	/**
405
	 * Wraps content in a group
406
	 *
407
	 * @param string $contents The content
408
	 * @param string $label    The label to add
409
	 *
410
	 * @return string A group
411
	 */
412
	public function wrap($contents, $label = null)
413
	{
414
		$group = $this->open();
415
		$group .= $label;
416
		$group .= $this->app['former.framework']->wrapField($contents);
417
		$group .= $this->close();
418
419
		return $group;
420
	}
421
422
	/**
423
	 * Prints out the current label
424
	 *
425
	 * @param  string $field The field to create a label for
426
	 *
427
	 * @return string        A <label> tag
428
	 */
429
	protected function getLabel($field = null)
430
	{
431
		// Don't create a label if none exist
432
		if (!$field or !$this->label) {
433
			return null;
434
		}
435
436
		// Wrap label in framework classes
437
		$this->label->addClass($this->app['former.framework']->getLabelClasses());
438
		$this->label = $this->app['former.framework']->createLabelOf($field, $this->label);
439
		$this->label = $this->app['former.framework']->wrapLabel($this->label);
440
441
		return $this->label;
442
	}
443
444
	/**
445
	 * Prints out the current help
446
	 *
447
	 * @return string A .help-block or .help-inline
448
	 */
449
	protected function getHelp()
450
	{
451
		$inline = Arr::get($this->help, 'inline');
452
		$block  = Arr::get($this->help, 'block');
453
454
		// Replace help text with error if any found
455
		$errors = $this->app['former']->getErrors();
456
		if ($errors and $this->app['former']->getOption('error_messages')) {
457
			$inline = $this->app['former.framework']->createValidationError($errors);
458
		}
459
460
		return join(null, array($inline, $block));
461
	}
462
463
	/**
464
	 * Format the field with prepended/appended elements
465
	 *
466
	 * @param  Field $field The field to format
467
	 *
468
	 * @return string        Field plus supplementary elements
469
	 */
470
	protected function prependAppend($field)
471
	{
472
		if (!$this->prepend and !$this->append) {
473
			return $field->render();
474
		}
475
476
		return $this->app['former.framework']->prependAppend($field, $this->prepend, $this->append);
477
	}
478
479
	/**
480
	 * Place elements around the field
481
	 *
482
	 * @param  array  $items An array of items to place
483
	 * @param  string $place Where they should end up (prepend|append)
484
	 */
485
	protected function placeAround($items, $place)
486
	{
487
		// Iterate over the items and place them where they should
488
		foreach ((array) $items as $item) {
489
			$item             = $this->app['former.framework']->placeAround($item);
490
			$this->{$place}[] = $item;
491
		}
492
	}
493
}
494