Completed
Push — master ( 95818c...eae1b4 )
by Ben
99:23 queued 32:03
created

TwitterBootstrap4::getInlineLabelClass()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
namespace Former\Framework;
3
4
use Former\Interfaces\FrameworkInterface;
5
use Former\Traits\Field;
6
use Former\Traits\Framework;
7
use HtmlObject\Element;
8
use Illuminate\Container\Container;
9
use Illuminate\Support\Str;
10
11
/**
12
 * The Twitter Bootstrap form framework
13
 */
14
class TwitterBootstrap4 extends Framework implements FrameworkInterface
15
{
16
	/**
17
	 * Form types that trigger special styling for this Framework
18
	 *
19
	 * @var array
20
	 */
21
	protected $availableTypes = array('horizontal', 'vertical', 'inline');
22
23
	/**
24
	 * The button types available
25
	 *
26
	 * @var array
27
	 */
28
	private $buttons = array(
0 ignored issues
show
Unused Code introduced by
The property $buttons is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
29
		'lg',
30
		'sm',
31
		'xs',
32
		'block',
33
		'link',
34
		'primary',
35
		'secondary',
36
		'warning',
37
		'danger',
38
		'success',
39
		'info',
40
		'light',
41
		'dark',
42
	);
43
44
	/**
45
	 * The field sizes available
46
	 *
47
	 * @var array
48
	 */
49
	private $fields = array(
50
		'lg',
51
		'sm',
52
		// 'col-xs-1', 'col-xs-2', 'col-xs-3', 'col-xs-4', 'col-xs-5', 'col-xs-6',
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
53
		// 'col-xs-7', 'col-xs-8', 'col-xs-9', 'col-xs-10', 'col-xs-11', 'col-xs-12',
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
54
		// 'col-sm-1', 'col-sm-2', 'col-sm-3', 'col-sm-4', 'col-sm-5', 'col-sm-6',
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
55
		// 'col-sm-7', 'col-sm-8', 'col-sm-9', 'col-sm-10', 'col-sm-11', 'col-sm-12',
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
56
		// 'col-md-1', 'col-md-2', 'col-md-3', 'col-md-4', 'col-md-5', 'col-md-6',
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
57
		// 'col-md-7', 'col-md-8', 'col-md-9', 'col-md-10', 'col-md-11', 'col-md-12',
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
58
		// 'col-lg-1', 'col-lg-2', 'col-lg-3', 'col-lg-4', 'col-lg-5', 'col-lg-6',
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
59
		// 'col-lg-7', 'col-lg-8', 'col-lg-9', 'col-lg-10', 'col-lg-11', 'col-lg-12',
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
60
	);
61
62
	/**
63
	 * The field states available
64
	 *
65
	 * @var array
66
	 */
67
	protected $states = array(
68
		'has-warning',
69
		'has-error',
70
		'has-success',
71
	);
72
73
	/**
74
	 * The default HTML tag used for icons
75
	 *
76
	 * @var string
77
	 */
78
	protected $iconTag = 'i';
79
80
	/**
81
	 * The default set for icon fonts
82
	 * By default Bootstrap 4 offers no fonts, but we'll add Font Awesome
83
	 *
84
	 * @var string
85
	 */
86
	protected $iconSet = 'fa';
87
88
	/**
89
	 * The default prefix icon names
90
	 * Using Font Awesome 5, this can be 'fa' or 'fas' for solid, 'far' for regular
91
	 *
92
	 * @var string
93
	 */
94
	protected $iconPrefix = 'fa';
95
96
	/**
97
	 * Create a new TwitterBootstrap instance
98
	 *
99
	 * @param \Illuminate\Container\Container $app
100
	 */
101
	public function __construct(Container $app)
102
	{
103
		$this->app = $app;
0 ignored issues
show
Documentation Bug introduced by
It seems like $app of type object<Illuminate\Container\Container> is incompatible with the declared type object<Former\Traits\Container> of property $app.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
104
		$this->setFrameworkDefaults();
105
	}
106
107
	////////////////////////////////////////////////////////////////////
108
	/////////////////////////// FILTER ARRAYS //////////////////////////
109
	////////////////////////////////////////////////////////////////////
110
111
	/**
112
	 * Filter buttons classes
113
	 *
114
	 * @param  array $classes An array of classes
115
	 *
116
	 * @return string[] A filtered array
117
	 */
118
	public function filterButtonClasses($classes)
119
	{
120
		// Filter classes
121
		// $classes = array_intersect($classes, $this->buttons);
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
122
123
		// Prepend button type
124
		$classes   = $this->prependWith($classes, 'btn-');
125
		$classes[] = 'btn';
126
127
		return $classes;
128
	}
129
130
	/**
131
	 * Filter field classes
132
	 *
133
	 * @param  array $classes An array of classes
134
	 *
135
	 * @return array A filtered array
136
	 */
137
	public function filterFieldClasses($classes)
138
	{
139
		// Filter classes
140
		$classes = array_intersect($classes, $this->fields);
141
142
		// Prepend field type
143
		$classes = array_map(function ($class) {
144
			return Str::startsWith($class, 'col') ? $class : 'input-'.$class;
145
		}, $classes);
146
147
		return $classes;
148
	}
149
150
	////////////////////////////////////////////////////////////////////
151
	///////////////////// EXPOSE FRAMEWORK SPECIFICS ///////////////////
152
	////////////////////////////////////////////////////////////////////
153
154
	/**
155
	 * Framework error state
156
	 *
157
	 * @return string
158
	 */
159
	public function errorState()
160
	{
161
		return 'has-error';
162
	}
163
164
	/**
165
	 * Returns corresponding inline class of a field
166
	 *
167
	 * @param Field $field
168
	 *
169
	 * @return string
170
	 */
171
	public function getInlineLabelClass($field)
172
	{
173
		$inlineClass = parent::getInlineLabelClass($field);
174
		if ($field->isOfType('checkbox', 'checkboxes', 'radio', 'radios')) {
175
			$inlineClass = 'form-check-label';
176
		}
177
178
		return $inlineClass;
179
	}
180
181
	/**
182
	 * Set the fields width from a label width
183
	 *
184
	 * @param array $labelWidths
185
	 */
186
	protected function setFieldWidths($labelWidths)
187
	{
188
		$labelWidthClass = $fieldWidthClass = $fieldOffsetClass = '';
189
190
		$viewports = $this->getFrameworkOption('viewports');
191
		foreach ($labelWidths as $viewport => $columns) {
192
			if ($viewport) {
193
				$labelWidthClass .= " col-$viewports[$viewport]-$columns";
194
				$fieldWidthClass .= " col-$viewports[$viewport]-".(12 - $columns);
195
				$fieldOffsetClass .= " col-$viewports[$viewport]-offset-$columns";
196
			}
197
		}
198
199
		$this->labelWidth  = ltrim($labelWidthClass);
200
		$this->fieldWidth  = ltrim($fieldWidthClass);
201
		$this->fieldOffset = ltrim($fieldOffsetClass);
202
	}
203
204
	////////////////////////////////////////////////////////////////////
205
	///////////////////////////// ADD CLASSES //////////////////////////
206
	////////////////////////////////////////////////////////////////////
207
208
	/**
209
	 * Add classes to a field
210
	 *
211
	 * @param Field $field
212
	 * @param array $classes The possible classes to add
213
	 *
214
	 * @return Field
215
	 */
216
	public function getFieldClasses(Field $field, $classes)
217
	{
218
		// Add inline class for checkables
219
		if ($field->isCheckable()) {
220
			$classes[] = 'form-check';
221
222
			if (in_array('inline', $classes)) {
223
				$field->inline();
0 ignored issues
show
Documentation Bug introduced by
The method inline does not exist on object<Former\Traits\Field>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
224
			}
225
		}
226
227
		// Filter classes according to field type
228
		if ($field->isButton()) {
229
			$classes = $this->filterButtonClasses($classes);
230
		} else {
231
			$classes = $this->filterFieldClasses($classes);
232
		}
233
234
		// Add form-control class for text-type, textarea and select fields
235
		// As text-type is open-ended we instead exclude those that shouldn't receive the class
236
		if (!$field->isCheckable() and !$field->isButton() and !in_array($field->getType(), array(
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
237
					'file',
238
					'plaintext',
239
				)) and !in_array('form-control', $classes)
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
240
		) {
241
			$classes[] = 'form-control';
242
		}
243
244
		return $this->addClassesToField($field, $classes);
245
	}
246
247
	/**
248
	 * Add group classes
249
	 *
250
	 * @return string A list of group classes
251
	 */
252
	public function getGroupClasses()
253
	{
254
		if ($this->app['former.form']->isOfType('horizontal')) {
255
			return 'form-group row';
256
		} else {
257
			return 'form-group';
258
		}
259
	}
260
261
	/**
262
	 * Add label classes
263
	 *
264
	 * @return string[] An array of attributes with the label class
265
	 */
266
	public function getLabelClasses()
267
	{
268
		if ($this->app['former.form']->isOfType('horizontal')) {
269
			return array('control-label', $this->labelWidth);
270
		} elseif ($this->app['former.form']->isOfType('inline')) {
271
			return array('sr-only');
272
		} else {
273
			return array('control-label');
274
		}
275
	}
276
277
	/**
278
	 * Add uneditable field classes
279
	 *
280
	 * @return string An array of attributes with the uneditable class
281
	 */
282
	public function getUneditableClasses()
283
	{
284
		return '';
0 ignored issues
show
Bug Best Practice introduced by
The return type of return ''; (string) is incompatible with the return type declared by the interface Former\Interfaces\Framew...e::getUneditableClasses of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
285
	}
286
287
	/**
288
	 * Add plain text field classes
289
	 *
290
	 * @return string An array of attributes with the plain text class
291
	 */
292
	public function getPlainTextClasses()
293
	{
294
		return 'form-control-static';
0 ignored issues
show
Bug Best Practice introduced by
The return type of return 'form-control-static'; (string) is incompatible with the return type declared by the interface Former\Interfaces\Framew...ce::getPlainTextClasses of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
295
	}
296
297
	/**
298
	 * Add form class
299
	 *
300
	 * @param  string $type The type of form to add
301
	 *
302
	 * @return string|null
303
	 */
304
	public function getFormClasses($type)
305
	{
306
		return $type ? 'form-'.$type : null;
0 ignored issues
show
Bug Compatibility introduced by
The expression $type ? 'form-' . $type : null; of type string|null adds the type string to the return on line 306 which is incompatible with the return type declared by the interface Former\Interfaces\Framew...terface::getFormClasses of type array.
Loading history...
307
	}
308
309
	/**
310
	 * Add actions block class
311
	 *
312
	 * @return string|null
313
	 */
314
	public function getActionClasses()
315
	{
316
		if ($this->app['former.form']->isOfType('horizontal') || $this->app['former.form']->isOfType('inline')) {
317
			return 'form-group row';
0 ignored issues
show
Bug Best Practice introduced by
The return type of return 'form-group row'; (string) is incompatible with the return type declared by the interface Former\Interfaces\Framew...rface::getActionClasses of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
318
		}
319
320
		return null;
321
	}
322
323
	////////////////////////////////////////////////////////////////////
324
	//////////////////////////// RENDER BLOCKS /////////////////////////
325
	////////////////////////////////////////////////////////////////////
326
327
	/**
328
	 * Render an help text
329
	 *
330
	 * @param string $text
331
	 * @param array  $attributes
332
	 *
333
	 * @return Element
334
	 */
335
	public function createHelp($text, $attributes = array())
336
	{
337
		return Element::create('span', $text, $attributes)->addClass('form-text text-muted');
338
	}
339
340
	/**
341
	 * Render an help text
342
	 *
343
	 * @param string $text
344
	 * @param array  $attributes
345
	 *
346
	 * @return Element
347
	 */
348
	public function createBlockHelp($text, $attributes = array())
349
	{
350
		return Element::create('p', $text, $attributes)->addClass('form-text text-muted');
351
	}
352
353
	/**
354
	 * Render a disabled field
355
	 *
356
	 * @param Field $field
357
	 *
358
	 * @return Element
359
	 */
360
	public function createDisabledField(Field $field)
361
	{
362
		return Element::create('span', $field->getValue(), $field->getAttributes());
363
	}
364
365
	/**
366
	 * Render a plain text field
367
	 *
368
	 * @param Field $field
369
	 *
370
	 * @return Element
371
	 */
372
	public function createPlainTextField(Field $field)
373
	{
374
		$label = $field->getLabel();
375
		if ($label) {
376
			$label->for('');
0 ignored issues
show
Bug introduced by
The method for cannot be called on $label (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
377
		}
378
379
		return Element::create('div', $field->getValue(), $field->getAttributes());
380
	}
381
382
	////////////////////////////////////////////////////////////////////
383
	//////////////////////////// WRAP BLOCKS ///////////////////////////
384
	////////////////////////////////////////////////////////////////////
385
386
	/**
387
	 * Wrap an item to be prepended or appended to the current field
388
	 *
389
	 * @return Element A wrapped item
390
	 */
391
	public function placeAround($item)
392
	{
393
		// Render object
394
		if (is_object($item) and method_exists($item, '__toString')) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
395
			$item = $item->__toString();
396
		}
397
398
		// Get class to use
399
		$class = (strpos($item, '<button') !== false) ? 'btn' : 'addon';
400
401
		return Element::create('span', $item)->addClass('input-group-'.$class);
402
	}
403
404
	/**
405
	 * Wrap a field with prepended and appended items
406
	 *
407
	 * @param  Field $field
408
	 * @param  array $prepend
409
	 * @param  array $append
410
	 *
411
	 * @return string A field concatented with prepended and/or appended items
412
	 */
413
	public function prependAppend($field, $prepend, $append)
414
	{
415
		$return = '<div class="input-group">';
416
		$return .= join(null, $prepend);
417
		$return .= $field->render();
418
		$return .= join(null, $append);
419
		$return .= '</div>';
420
421
		return $return;
422
	}
423
424
	/**
425
	 * Wrap a field with potential additional tags
426
	 *
427
	 * @param  Field $field
428
	 *
429
	 * @return Element A wrapped field
430
	 */
431
	public function wrapField($field)
432
	{
433
		if ($this->app['former.form']->isOfType('horizontal')) {
434
			return Element::create('div', $field)->addClass($this->fieldWidth);
435
		}
436
437
		return $field;
438
	}
439
440
	/**
441
	 * Wrap actions block with potential additional tags
442
	 *
443
	 * @param  Actions $actions
444
	 *
445
	 * @return string A wrapped actions block
446
	 */
447
	public function wrapActions($actions)
448
	{
449
		// For horizontal forms, we wrap the actions in a div
450
		if ($this->app['former.form']->isOfType('horizontal')) {
451
			return Element::create('div', $actions)->addClass(array($this->fieldOffset, $this->fieldWidth));
0 ignored issues
show
Documentation introduced by
array($this->fieldOffset, $this->fieldWidth) is of type array<integer,string,{"0":"string","1":"string"}>, but the function expects a string.

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...
452
		}
453
454
		return $actions;
455
	}
456
}
457