Completed
Push — master ( 95818c...eae1b4 )
by Ben
99:23 queued 32:03
created
src/Former/Framework/TwitterBootstrap4.php 2 patches
Indentation   +440 added lines, -440 removed lines patch added patch discarded remove patch
@@ -13,444 +13,444 @@
 block discarded – undo
13 13
  */
14 14
 class TwitterBootstrap4 extends Framework implements FrameworkInterface
15 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(
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',
53
-		// 'col-xs-7', 'col-xs-8', 'col-xs-9', 'col-xs-10', 'col-xs-11', 'col-xs-12',
54
-		// 'col-sm-1', 'col-sm-2', 'col-sm-3', 'col-sm-4', 'col-sm-5', 'col-sm-6',
55
-		// 'col-sm-7', 'col-sm-8', 'col-sm-9', 'col-sm-10', 'col-sm-11', 'col-sm-12',
56
-		// 'col-md-1', 'col-md-2', 'col-md-3', 'col-md-4', 'col-md-5', 'col-md-6',
57
-		// 'col-md-7', 'col-md-8', 'col-md-9', 'col-md-10', 'col-md-11', 'col-md-12',
58
-		// 'col-lg-1', 'col-lg-2', 'col-lg-3', 'col-lg-4', 'col-lg-5', 'col-lg-6',
59
-		// 'col-lg-7', 'col-lg-8', 'col-lg-9', 'col-lg-10', 'col-lg-11', 'col-lg-12',
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;
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);
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();
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(
237
-					'file',
238
-					'plaintext',
239
-				)) and !in_array('form-control', $classes)
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 '';
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';
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;
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';
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('');
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')) {
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));
452
-		}
453
-
454
-		return $actions;
455
-	}
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(
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',
53
+        // 'col-xs-7', 'col-xs-8', 'col-xs-9', 'col-xs-10', 'col-xs-11', 'col-xs-12',
54
+        // 'col-sm-1', 'col-sm-2', 'col-sm-3', 'col-sm-4', 'col-sm-5', 'col-sm-6',
55
+        // 'col-sm-7', 'col-sm-8', 'col-sm-9', 'col-sm-10', 'col-sm-11', 'col-sm-12',
56
+        // 'col-md-1', 'col-md-2', 'col-md-3', 'col-md-4', 'col-md-5', 'col-md-6',
57
+        // 'col-md-7', 'col-md-8', 'col-md-9', 'col-md-10', 'col-md-11', 'col-md-12',
58
+        // 'col-lg-1', 'col-lg-2', 'col-lg-3', 'col-lg-4', 'col-lg-5', 'col-lg-6',
59
+        // 'col-lg-7', 'col-lg-8', 'col-lg-9', 'col-lg-10', 'col-lg-11', 'col-lg-12',
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;
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);
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();
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(
237
+                    'file',
238
+                    'plaintext',
239
+                )) and !in_array('form-control', $classes)
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 '';
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';
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;
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';
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('');
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')) {
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));
452
+        }
453
+
454
+        return $actions;
455
+    }
456 456
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -139,7 +139,7 @@
 block discarded – undo
139 139
 		$classes = array_intersect($classes, $this->fields);
140 140
 
141 141
 		// Prepend field type
142
-		$classes = array_map(function ($class) {
142
+		$classes = array_map(function($class) {
143 143
 			return Str::startsWith($class, 'col') ? $class : 'input-'.$class;
144 144
 		}, $classes);
145 145
 
Please login to merge, or discard this patch.
src/Former/Traits/Checkable.php 2 patches
Indentation   +553 added lines, -553 removed lines patch added patch discarded remove patch
@@ -12,558 +12,558 @@
 block discarded – undo
12 12
  */
13 13
 abstract class Checkable extends Field
14 14
 {
15
-	/**
16
-	 * Renders the checkables as inline
17
-	 *
18
-	 * @var boolean
19
-	 */
20
-	protected $inline = false;
21
-
22
-	/**
23
-	 * Add a text to a single element
24
-	 *
25
-	 * @var string
26
-	 */
27
-	protected $text = null;
28
-
29
-	/**
30
-	 * Renders the checkables as grouped
31
-	 *
32
-	 * @var boolean
33
-	 */
34
-	protected $grouped = false;
35
-
36
-	/**
37
-	 * The checkable items currently stored
38
-	 *
39
-	 * @var array
40
-	 */
41
-	protected $items = array();
42
-
43
-	/**
44
-	 * The type of checkable item
45
-	 *
46
-	 * @var string
47
-	 */
48
-	protected $checkable = null;
49
-
50
-	/**
51
-	 * An array of checked items
52
-	 *
53
-	 * @var array
54
-	 */
55
-	protected $checked = array();
56
-
57
-	/**
58
-	 * The checkable currently being focused on
59
-	 *
60
-	 * @var integer
61
-	 */
62
-	protected $focus = null;
63
-
64
-	/**
65
-	 * Whether this particular checkable is to be pushed
66
-	 *
67
-	 * @var boolean
68
-	 */
69
-	protected $isPushed = null;
70
-
71
-	////////////////////////////////////////////////////////////////////
72
-	//////////////////////////// CORE METHODS //////////////////////////
73
-	////////////////////////////////////////////////////////////////////
74
-
75
-	/**
76
-	 * Build a new checkable
77
-	 *
78
-	 * @param Container $app
79
-	 * @param string    $type
80
-	 * @param array     $name
81
-	 * @param           $label
82
-	 * @param           $value
83
-	 * @param           $attributes
84
-	 */
85
-	public function __construct(Container $app, $type, $name, $label, $value, $attributes)
86
-	{
87
-		// Unify auto and chained methods of grouping checkboxes
88
-		if (ends_with($name, '[]')) {
89
-			$name = substr($name, 0, -2);
90
-			$this->grouped();
91
-		}
92
-		parent::__construct($app, $type, $name, $label, $value, $attributes);
93
-
94
-		if (is_array($this->value)) {
95
-			$this->items($this->value);
96
-		}
97
-	}
98
-
99
-	/**
100
-	 * Apply methods to focused checkable
101
-	 *
102
-	 * @param string $method
103
-	 * @param array  $parameters
104
-	 *
105
-	 * @return $this
106
-	 */
107
-	public function __call($method, $parameters)
108
-	{
109
-		$focused = $this->setOnFocused('attributes.'.$method, array_get($parameters, 0));
110
-		if ($focused) {
111
-			return $this;
112
-		}
113
-
114
-		return parent::__call($method, $parameters);
115
-	}
116
-
117
-	/**
118
-	 * Prints out the currently stored checkables
119
-	 */
120
-	public function render()
121
-	{
122
-		$html = null;
123
-
124
-		// Multiple items
125
-		if ($this->items) {
126
-			unset($this->app['former']->labels[array_search($this->name, $this->app['former']->labels)]);
127
-			foreach ($this->items as $key => $item) {
128
-				$value = $this->isCheckbox() && !$this->isGrouped() ? 1 : $key;
129
-				$html .= $this->createCheckable($item, $value);
130
-			}
131
-
132
-			return $html;
133
-		}
134
-
135
-		// Single item
136
-		return $this->createCheckable(array(
137
-			'name'  => $this->name,
138
-			'label' => $this->text,
139
-			'value' => $this->value,
140
-			'attributes' => $this->attributes,
141
-		));
142
-	}
143
-
144
-	////////////////////////////////////////////////////////////////////
145
-	////////////////////////// FIELD METHODS ///////////////////////////
146
-	////////////////////////////////////////////////////////////////////
147
-
148
-	/**
149
-	 * Focus on a particular checkable
150
-	 *
151
-	 * @param integer $on The checkable to focus on
152
-	 *
153
-	 * @return $this
154
-	 */
155
-	public function on($on)
156
-	{
157
-		if (!isset($this->items[$on])) {
158
-			return $this;
159
-		} else {
160
-			$this->focus = $on;
161
-		}
162
-
163
-		return $this;
164
-	}
165
-
166
-	/**
167
-	 * Set the checkables as inline
168
-	 */
169
-	public function inline()
170
-	{
171
-		$this->inline = true;
172
-
173
-		return $this;
174
-	}
175
-
176
-	/**
177
-	 * Set the checkables as stacked
178
-	 */
179
-	public function stacked()
180
-	{
181
-		$this->inline = false;
182
-
183
-		return $this;
184
-	}
185
-
186
-	/**
187
-	 * Set the checkables as grouped
188
-	 */
189
-	public function grouped()
190
-	{
191
-		$this->grouped = true;
192
-
193
-		return $this;
194
-	}
195
-
196
-	/**
197
-	 * Add text to a single checkable
198
-	 *
199
-	 * @param  string $text The checkable label
200
-	 *
201
-	 * @return $this
202
-	 */
203
-	public function text($text)
204
-	{
205
-		// Translate and format
206
-		$text = Helpers::translate($text);
207
-
208
-		// Apply on focused if any
209
-		$focused = $this->setOnFocused('label', $text);
210
-		if ($focused) {
211
-			return $this;
212
-		}
213
-
214
-		$this->text = $text;
215
-
216
-		return $this;
217
-	}
218
-
219
-	/**
220
-	 * Push this particular checkbox
221
-	 *
222
-	 * @param boolean $pushed
223
-	 *
224
-	 * @return $this
225
-	 */
226
-	public function push($pushed = true)
227
-	{
228
-		$this->isPushed = $pushed;
229
-
230
-		return $this;
231
-	}
232
-
233
-	/**
234
-	 * Check a specific item
235
-	 *
236
-	 * @param bool|string $checked The checkable to check, or an array of checked items
237
-	 *
238
-	 * @return $this
239
-	 */
240
-	public function check($checked = true)
241
-	{
242
-		// If we're setting all the checked items at once
243
-		if (is_array($checked)) {
244
-			$this->checked = $checked;
245
-			// Checking an item in particular
246
-		} elseif (is_string($checked) or is_int($checked)) {
247
-			$this->checked[$checked] = true;
248
-			// Only setting a single item
249
-		} else {
250
-			$this->checked[$this->name] = (bool) $checked;
251
-		}
252
-
253
-		return $this;
254
-	}
255
-
256
-	////////////////////////////////////////////////////////////////////
257
-	////////////////////////// INTERNAL METHODS ////////////////////////
258
-	////////////////////////////////////////////////////////////////////
259
-
260
-	/**
261
-	 * Creates a series of checkable items
262
-	 *
263
-	 * @param array $_items Items to create
264
-	 */
265
-	protected function items($_items)
266
-	{
267
-		// If passing an array
268
-		if (sizeof($_items) == 1 and
269
-			isset($_items[0]) and
270
-			is_array($_items[0])
271
-		) {
272
-			$_items = $_items[0];
273
-		}
274
-
275
-		// Fetch models if that's what we were passed
276
-		if (isset($_items[0]) and is_object($_items[0])) {
277
-			$_items = Helpers::queryToArray($_items);
278
-			$_items = array_flip($_items);
279
-		}
280
-
281
-		// Iterate through items, assign a name and a label to each
282
-		$count = 0;
283
-		foreach ($_items as $label => $name) {
284
-
285
-			// Define a fallback name in case none is found
286
-			$fallback = $this->isCheckbox()
287
-				? $this->name.'_'.$count
288
-				: $this->name;
289
-
290
-			// Grouped fields
291
-			if ($this->isGrouped()) {
292
-				$attributes['id'] = str_replace('[]', null, $fallback);
293
-				$fallback         = str_replace('[]', null, $this->name).'[]';
294
-			}
295
-
296
-			// If we haven't any name defined for the checkable, try to compute some
297
-			if (!is_string($label) and !is_array($name)) {
298
-				$label = $name;
299
-				$name  = $fallback;
300
-			}
301
-
302
-			// If we gave custom information on the item, add them
303
-			if (is_array($name)) {
304
-				$attributes = $name;
305
-				$name       = array_get($attributes, 'name', $fallback);
306
-				unset($attributes['name']);
307
-			}
308
-
309
-			// Store all informations we have in an array
310
-			$item = array(
311
-				'name'  => $name,
312
-				'label' => Helpers::translate($label),
313
-				'count' => $count,
314
-			);
315
-			if (isset($attributes)) {
316
-				$item['attributes'] = $attributes;
317
-			}
318
-
319
-			$this->items[] = $item;
320
-			$count++;
321
-		}
322
-	}
323
-
324
-	/**
325
-	 * Renders a checkable
326
-	 *
327
-	 * @param string|array $item          A checkable item
328
-	 * @param integer      $fallbackValue A fallback value if none is set
329
-	 *
330
-	 * @return string
331
-	 */
332
-	protected function createCheckable($item, $fallbackValue = 1)
333
-	{
334
-		// Extract informations
335
-		extract($item);
336
-
337
-		// Set default values
338
-		if (!isset($attributes)) {
339
-			$attributes = array();
340
-		}
341
-		if (isset($attributes['value'])) {
342
-			$value = $attributes['value'];
343
-		}
344
-		if (!isset($value) or $value === $this->app['former']->getOption('unchecked_value')) {
345
-			$value = $fallbackValue;
346
-		}
347
-
348
-		// If inline items, add class
349
-		$isInline = $this->inline ? ' '.$this->app['former.framework']->getInlineLabelClass($this) : null;
350
-
351
-		// In Bootsrap 3 or 4, don't append the the checkable type (radio/checkbox) as a class if
352
-		// rendering inline.
353
-		$class =  ($this->app['former']->framework() == 'TwitterBootstrap3' ||
354
-			$this->app['former']->framework() == 'TwitterBootstrap4') ? trim($isInline) : $this->checkable.$isInline;
355
-
356
-		// Merge custom attributes with global attributes
357
-		$attributes = array_merge($this->attributes, $attributes);
358
-		if (!isset($attributes['id'])) {
359
-			$attributes['id'] = $name.$this->unique($name);
360
-		}
361
-
362
-		// Create field
363
-		$field = Input::create($this->checkable, $name, $value, $attributes);
364
-		if ($this->isChecked($item, $value)) {
365
-			$field->checked('checked');
366
-		}
367
-
368
-		// Add hidden checkbox if requested
369
-		if ($this->isOfType('checkbox', 'checkboxes')) {
370
-			if ($this->isPushed or ($this->app['former']->getOption('push_checkboxes') and $this->isPushed !== false)) {
371
-				$field = $this->app['former']->hidden($name)->forceValue($this->app['former']->getOption('unchecked_value')).$field->render();
372
-
373
-				// app['former.field'] was overwritten by Former::hidden() call in the line above, so here
374
-				// we reset it to $this to enable $this->app['former']->getErrors() to retrieve the correct object
375
-				$this->app->instance('former.field', $this);
376
-			}
377
-		}
378
-
379
-		// If no label to wrap, return plain checkable
380
-		if (!$label) {
381
-			$element = (is_object($field)) ? $field->render() : $field;
382
-		} elseif ($this->app['former']->framework() == 'TwitterBootstrap4') {
383
-			// Revised for Bootstrap 4, move the 'input' outside of the 'label'
384
-			$element = $field . Element::create('label', $label)->for($attributes['id'])->class($class)->render();
385
-
386
-			$wrapper_class = $this->inline ? 'form-check form-check-inline' : 'form-check';
15
+    /**
16
+     * Renders the checkables as inline
17
+     *
18
+     * @var boolean
19
+     */
20
+    protected $inline = false;
21
+
22
+    /**
23
+     * Add a text to a single element
24
+     *
25
+     * @var string
26
+     */
27
+    protected $text = null;
28
+
29
+    /**
30
+     * Renders the checkables as grouped
31
+     *
32
+     * @var boolean
33
+     */
34
+    protected $grouped = false;
35
+
36
+    /**
37
+     * The checkable items currently stored
38
+     *
39
+     * @var array
40
+     */
41
+    protected $items = array();
42
+
43
+    /**
44
+     * The type of checkable item
45
+     *
46
+     * @var string
47
+     */
48
+    protected $checkable = null;
49
+
50
+    /**
51
+     * An array of checked items
52
+     *
53
+     * @var array
54
+     */
55
+    protected $checked = array();
56
+
57
+    /**
58
+     * The checkable currently being focused on
59
+     *
60
+     * @var integer
61
+     */
62
+    protected $focus = null;
63
+
64
+    /**
65
+     * Whether this particular checkable is to be pushed
66
+     *
67
+     * @var boolean
68
+     */
69
+    protected $isPushed = null;
70
+
71
+    ////////////////////////////////////////////////////////////////////
72
+    //////////////////////////// CORE METHODS //////////////////////////
73
+    ////////////////////////////////////////////////////////////////////
74
+
75
+    /**
76
+     * Build a new checkable
77
+     *
78
+     * @param Container $app
79
+     * @param string    $type
80
+     * @param array     $name
81
+     * @param           $label
82
+     * @param           $value
83
+     * @param           $attributes
84
+     */
85
+    public function __construct(Container $app, $type, $name, $label, $value, $attributes)
86
+    {
87
+        // Unify auto and chained methods of grouping checkboxes
88
+        if (ends_with($name, '[]')) {
89
+            $name = substr($name, 0, -2);
90
+            $this->grouped();
91
+        }
92
+        parent::__construct($app, $type, $name, $label, $value, $attributes);
93
+
94
+        if (is_array($this->value)) {
95
+            $this->items($this->value);
96
+        }
97
+    }
98
+
99
+    /**
100
+     * Apply methods to focused checkable
101
+     *
102
+     * @param string $method
103
+     * @param array  $parameters
104
+     *
105
+     * @return $this
106
+     */
107
+    public function __call($method, $parameters)
108
+    {
109
+        $focused = $this->setOnFocused('attributes.'.$method, array_get($parameters, 0));
110
+        if ($focused) {
111
+            return $this;
112
+        }
113
+
114
+        return parent::__call($method, $parameters);
115
+    }
116
+
117
+    /**
118
+     * Prints out the currently stored checkables
119
+     */
120
+    public function render()
121
+    {
122
+        $html = null;
123
+
124
+        // Multiple items
125
+        if ($this->items) {
126
+            unset($this->app['former']->labels[array_search($this->name, $this->app['former']->labels)]);
127
+            foreach ($this->items as $key => $item) {
128
+                $value = $this->isCheckbox() && !$this->isGrouped() ? 1 : $key;
129
+                $html .= $this->createCheckable($item, $value);
130
+            }
131
+
132
+            return $html;
133
+        }
134
+
135
+        // Single item
136
+        return $this->createCheckable(array(
137
+            'name'  => $this->name,
138
+            'label' => $this->text,
139
+            'value' => $this->value,
140
+            'attributes' => $this->attributes,
141
+        ));
142
+    }
143
+
144
+    ////////////////////////////////////////////////////////////////////
145
+    ////////////////////////// FIELD METHODS ///////////////////////////
146
+    ////////////////////////////////////////////////////////////////////
147
+
148
+    /**
149
+     * Focus on a particular checkable
150
+     *
151
+     * @param integer $on The checkable to focus on
152
+     *
153
+     * @return $this
154
+     */
155
+    public function on($on)
156
+    {
157
+        if (!isset($this->items[$on])) {
158
+            return $this;
159
+        } else {
160
+            $this->focus = $on;
161
+        }
162
+
163
+        return $this;
164
+    }
165
+
166
+    /**
167
+     * Set the checkables as inline
168
+     */
169
+    public function inline()
170
+    {
171
+        $this->inline = true;
172
+
173
+        return $this;
174
+    }
175
+
176
+    /**
177
+     * Set the checkables as stacked
178
+     */
179
+    public function stacked()
180
+    {
181
+        $this->inline = false;
182
+
183
+        return $this;
184
+    }
185
+
186
+    /**
187
+     * Set the checkables as grouped
188
+     */
189
+    public function grouped()
190
+    {
191
+        $this->grouped = true;
192
+
193
+        return $this;
194
+    }
195
+
196
+    /**
197
+     * Add text to a single checkable
198
+     *
199
+     * @param  string $text The checkable label
200
+     *
201
+     * @return $this
202
+     */
203
+    public function text($text)
204
+    {
205
+        // Translate and format
206
+        $text = Helpers::translate($text);
207
+
208
+        // Apply on focused if any
209
+        $focused = $this->setOnFocused('label', $text);
210
+        if ($focused) {
211
+            return $this;
212
+        }
213
+
214
+        $this->text = $text;
215
+
216
+        return $this;
217
+    }
218
+
219
+    /**
220
+     * Push this particular checkbox
221
+     *
222
+     * @param boolean $pushed
223
+     *
224
+     * @return $this
225
+     */
226
+    public function push($pushed = true)
227
+    {
228
+        $this->isPushed = $pushed;
229
+
230
+        return $this;
231
+    }
232
+
233
+    /**
234
+     * Check a specific item
235
+     *
236
+     * @param bool|string $checked The checkable to check, or an array of checked items
237
+     *
238
+     * @return $this
239
+     */
240
+    public function check($checked = true)
241
+    {
242
+        // If we're setting all the checked items at once
243
+        if (is_array($checked)) {
244
+            $this->checked = $checked;
245
+            // Checking an item in particular
246
+        } elseif (is_string($checked) or is_int($checked)) {
247
+            $this->checked[$checked] = true;
248
+            // Only setting a single item
249
+        } else {
250
+            $this->checked[$this->name] = (bool) $checked;
251
+        }
252
+
253
+        return $this;
254
+    }
255
+
256
+    ////////////////////////////////////////////////////////////////////
257
+    ////////////////////////// INTERNAL METHODS ////////////////////////
258
+    ////////////////////////////////////////////////////////////////////
259
+
260
+    /**
261
+     * Creates a series of checkable items
262
+     *
263
+     * @param array $_items Items to create
264
+     */
265
+    protected function items($_items)
266
+    {
267
+        // If passing an array
268
+        if (sizeof($_items) == 1 and
269
+            isset($_items[0]) and
270
+            is_array($_items[0])
271
+        ) {
272
+            $_items = $_items[0];
273
+        }
274
+
275
+        // Fetch models if that's what we were passed
276
+        if (isset($_items[0]) and is_object($_items[0])) {
277
+            $_items = Helpers::queryToArray($_items);
278
+            $_items = array_flip($_items);
279
+        }
280
+
281
+        // Iterate through items, assign a name and a label to each
282
+        $count = 0;
283
+        foreach ($_items as $label => $name) {
284
+
285
+            // Define a fallback name in case none is found
286
+            $fallback = $this->isCheckbox()
287
+                ? $this->name.'_'.$count
288
+                : $this->name;
289
+
290
+            // Grouped fields
291
+            if ($this->isGrouped()) {
292
+                $attributes['id'] = str_replace('[]', null, $fallback);
293
+                $fallback         = str_replace('[]', null, $this->name).'[]';
294
+            }
295
+
296
+            // If we haven't any name defined for the checkable, try to compute some
297
+            if (!is_string($label) and !is_array($name)) {
298
+                $label = $name;
299
+                $name  = $fallback;
300
+            }
301
+
302
+            // If we gave custom information on the item, add them
303
+            if (is_array($name)) {
304
+                $attributes = $name;
305
+                $name       = array_get($attributes, 'name', $fallback);
306
+                unset($attributes['name']);
307
+            }
308
+
309
+            // Store all informations we have in an array
310
+            $item = array(
311
+                'name'  => $name,
312
+                'label' => Helpers::translate($label),
313
+                'count' => $count,
314
+            );
315
+            if (isset($attributes)) {
316
+                $item['attributes'] = $attributes;
317
+            }
318
+
319
+            $this->items[] = $item;
320
+            $count++;
321
+        }
322
+    }
323
+
324
+    /**
325
+     * Renders a checkable
326
+     *
327
+     * @param string|array $item          A checkable item
328
+     * @param integer      $fallbackValue A fallback value if none is set
329
+     *
330
+     * @return string
331
+     */
332
+    protected function createCheckable($item, $fallbackValue = 1)
333
+    {
334
+        // Extract informations
335
+        extract($item);
336
+
337
+        // Set default values
338
+        if (!isset($attributes)) {
339
+            $attributes = array();
340
+        }
341
+        if (isset($attributes['value'])) {
342
+            $value = $attributes['value'];
343
+        }
344
+        if (!isset($value) or $value === $this->app['former']->getOption('unchecked_value')) {
345
+            $value = $fallbackValue;
346
+        }
347
+
348
+        // If inline items, add class
349
+        $isInline = $this->inline ? ' '.$this->app['former.framework']->getInlineLabelClass($this) : null;
350
+
351
+        // In Bootsrap 3 or 4, don't append the the checkable type (radio/checkbox) as a class if
352
+        // rendering inline.
353
+        $class =  ($this->app['former']->framework() == 'TwitterBootstrap3' ||
354
+            $this->app['former']->framework() == 'TwitterBootstrap4') ? trim($isInline) : $this->checkable.$isInline;
355
+
356
+        // Merge custom attributes with global attributes
357
+        $attributes = array_merge($this->attributes, $attributes);
358
+        if (!isset($attributes['id'])) {
359
+            $attributes['id'] = $name.$this->unique($name);
360
+        }
361
+
362
+        // Create field
363
+        $field = Input::create($this->checkable, $name, $value, $attributes);
364
+        if ($this->isChecked($item, $value)) {
365
+            $field->checked('checked');
366
+        }
367
+
368
+        // Add hidden checkbox if requested
369
+        if ($this->isOfType('checkbox', 'checkboxes')) {
370
+            if ($this->isPushed or ($this->app['former']->getOption('push_checkboxes') and $this->isPushed !== false)) {
371
+                $field = $this->app['former']->hidden($name)->forceValue($this->app['former']->getOption('unchecked_value')).$field->render();
372
+
373
+                // app['former.field'] was overwritten by Former::hidden() call in the line above, so here
374
+                // we reset it to $this to enable $this->app['former']->getErrors() to retrieve the correct object
375
+                $this->app->instance('former.field', $this);
376
+            }
377
+        }
378
+
379
+        // If no label to wrap, return plain checkable
380
+        if (!$label) {
381
+            $element = (is_object($field)) ? $field->render() : $field;
382
+        } elseif ($this->app['former']->framework() == 'TwitterBootstrap4') {
383
+            // Revised for Bootstrap 4, move the 'input' outside of the 'label'
384
+            $element = $field . Element::create('label', $label)->for($attributes['id'])->class($class)->render();
385
+
386
+            $wrapper_class = $this->inline ? 'form-check form-check-inline' : 'form-check';
387 387
 			
388
-			$element = Element::create('div', $element)->class($wrapper_class)->render();
389
-
390
-		} else {
391
-			// Original way is to add the 'input' inside the 'label'
392
-			$element = Element::create('label', $field.$label)->for($attributes['id'])->class($class)->render();
393
-		}
394
-
395
-		// If BS3, if checkables are stacked, wrap them in a div with the checkable type
396
-		if (!$isInline && $this->app['former']->framework() == 'TwitterBootstrap3') {
397
-			$wrapper = Element::create('div', $element)->class($this->checkable);
398
-			if ($this->getAttribute('disabled')) {
399
-				$wrapper->addClass('disabled');
400
-			}
401
-			$element = $wrapper->render();
402
-		}
403
-
404
-		// Return the field
405
-		return $element;
406
-	}
407
-
408
-	////////////////////////////////////////////////////////////////////
409
-	///////////////////////////// HELPERS //////////////////////////////
410
-	////////////////////////////////////////////////////////////////////
411
-
412
-	/**
413
-	 * Generate an unique ID for a field
414
-	 *
415
-	 * @param string $name The field's name
416
-	 *
417
-	 * @return string A field number to use
418
-	 */
419
-	protected function unique($name)
420
-	{
421
-		$this->app['former']->labels[] = $name;
422
-
423
-		// Count number of fields with the same ID
424
-		$where  = array_filter($this->app['former']->labels, function ($label) use ($name) {
425
-			return $label == $name;
426
-		});
427
-		$unique = sizeof($where);
428
-
429
-		// In case the field doesn't need to be numbered
430
-		if ($unique < 2 or empty($this->items)) {
431
-			return false;
432
-		}
433
-
434
-		return $unique;
435
-	}
436
-
437
-	/**
438
-	 * Set something on the currently focused checkable
439
-	 *
440
-	 * @param string $attribute The key to set
441
-	 * @param string $value     Its value
442
-	 *
443
-	 * @return $this|bool
444
-	 */
445
-	protected function setOnFocused($attribute, $value)
446
-	{
447
-		if (is_null($this->focus)) {
448
-			return false;
449
-		}
450
-
451
-		$this->items[$this->focus] = array_set($this->items[$this->focus], $attribute, $value);
452
-
453
-		return $this;
454
-	}
455
-
456
-	/**
457
-	 * Check if a checkable is checked
458
-	 *
459
-	 * @return boolean Checked or not
460
-	 */
461
-	protected function isChecked($item = null, $value = null)
462
-	{
463
-		if (isset($item['name'])) {
464
-			$name = $item['name'];
465
-		}
466
-		if (empty($name)) {
467
-			$name = $this->name;
468
-		}
469
-
470
-		// If it's a checkbox, see if we marqued that one as checked in the array
471
-		// Or if it's a single radio, simply see if we called check
472
-		if ($this->isCheckbox() or
473
-			!$this->isCheckbox() and !$this->items
474
-		) {
475
-			$checked = array_get($this->checked, $name, false);
476
-
477
-			// If there are multiple, search for the value
478
-			// as the name are the same between radios
479
-		} else {
480
-			$checked = array_get($this->checked, $value, false);
481
-		}
482
-
483
-		// Check the values and POST array
484
-		if ($this->isGrouped()) {
485
-			// The group index. (e.g. 'bar' if the item name is foo[bar], or the item index for foo[])
486
-			$groupIndex = self::getGroupIndexFromItem($item);
487
-
488
-			// Search using the bare name, not the individual item name
489
-			$post   = $this->app['former']->getPost($this->name);
490
-			$static = $this->app['former']->getValue($this->bind ?: $this->name);
491
-
492
-			if (isset($post[$groupIndex])) {
493
-				$post = $post[$groupIndex];
494
-			}
495
-
496
-			/**
497
-			 * Support for Laravel Collection repopulating for grouped checkboxes. Note that the groupIndex must
498
-			 * match the value in order for the checkbox to be considered checked, e.g.:
499
-			 *
500
-			 *  array(
501
-			 *    'name' = 'roles[foo]',
502
-			 *    'value' => 'foo',
503
-			 *  )
504
-			 */
505
-			if ($static instanceof Collection) {
506
-				// If the repopulate value is a collection, search for an item matching the $groupIndex
507
-				foreach ($static as $staticItem) {
508
-					$staticItemValue = method_exists($staticItem, 'getKey') ? $staticItem->getKey() : $staticItem;
509
-					if ($staticItemValue == $groupIndex) {
510
-						$static = $staticItemValue;
511
-						break;
512
-					}
513
-				}
514
-			} else if (isset($static[$groupIndex])) {
515
-				$static = $static[$groupIndex];
516
-			}
517
-		} else {
518
-			$post   = $this->app['former']->getPost($name);
519
-			$static = $this->app['former']->getValue($this->bind ?: $name);
520
-		}
521
-
522
-		if (!is_null($post) and $post !== $this->app['former']->getOption('unchecked_value')) {
523
-			$isChecked = ($post == $value);
524
-		} elseif (!is_null($static)) {
525
-			$isChecked = ($static == $value);
526
-		} else {
527
-			$isChecked = $checked;
528
-		}
529
-
530
-		return $isChecked ? true : false;
531
-	}
532
-
533
-	/**
534
-	 * Check if the current element is a checkbox
535
-	 *
536
-	 * @return boolean Checkbox or radio
537
-	 */
538
-	protected function isCheckbox()
539
-	{
540
-		return $this->checkable == 'checkbox';
541
-	}
542
-
543
-	/**
544
-	 * Check if the checkables are grouped or not
545
-	 *
546
-	 * @return boolean
547
-	 */
548
-	protected function isGrouped()
549
-	{
550
-		return
551
-			$this->grouped == true or
552
-			strpos($this->name, '[]') !== false;
553
-	}
554
-
555
-	/**
556
-	 * @param array $item The item array, containing at least name and count keys.
557
-	 *
558
-	 * @return mixed The group index. (e.g. returns bar if the item name is foo[bar], or the item count for foo[])
559
-	 */
560
-	public static function getGroupIndexFromItem($item)
561
-	{
562
-		$groupIndex = preg_replace('/^.*?\[(.*)\]$/', '$1', $item['name']);
563
-		if (empty($groupIndex) or $groupIndex == $item['name']) {
564
-			return $item['count'];
565
-		}
566
-
567
-		return $groupIndex;
568
-	}
388
+            $element = Element::create('div', $element)->class($wrapper_class)->render();
389
+
390
+        } else {
391
+            // Original way is to add the 'input' inside the 'label'
392
+            $element = Element::create('label', $field.$label)->for($attributes['id'])->class($class)->render();
393
+        }
394
+
395
+        // If BS3, if checkables are stacked, wrap them in a div with the checkable type
396
+        if (!$isInline && $this->app['former']->framework() == 'TwitterBootstrap3') {
397
+            $wrapper = Element::create('div', $element)->class($this->checkable);
398
+            if ($this->getAttribute('disabled')) {
399
+                $wrapper->addClass('disabled');
400
+            }
401
+            $element = $wrapper->render();
402
+        }
403
+
404
+        // Return the field
405
+        return $element;
406
+    }
407
+
408
+    ////////////////////////////////////////////////////////////////////
409
+    ///////////////////////////// HELPERS //////////////////////////////
410
+    ////////////////////////////////////////////////////////////////////
411
+
412
+    /**
413
+     * Generate an unique ID for a field
414
+     *
415
+     * @param string $name The field's name
416
+     *
417
+     * @return string A field number to use
418
+     */
419
+    protected function unique($name)
420
+    {
421
+        $this->app['former']->labels[] = $name;
422
+
423
+        // Count number of fields with the same ID
424
+        $where  = array_filter($this->app['former']->labels, function ($label) use ($name) {
425
+            return $label == $name;
426
+        });
427
+        $unique = sizeof($where);
428
+
429
+        // In case the field doesn't need to be numbered
430
+        if ($unique < 2 or empty($this->items)) {
431
+            return false;
432
+        }
433
+
434
+        return $unique;
435
+    }
436
+
437
+    /**
438
+     * Set something on the currently focused checkable
439
+     *
440
+     * @param string $attribute The key to set
441
+     * @param string $value     Its value
442
+     *
443
+     * @return $this|bool
444
+     */
445
+    protected function setOnFocused($attribute, $value)
446
+    {
447
+        if (is_null($this->focus)) {
448
+            return false;
449
+        }
450
+
451
+        $this->items[$this->focus] = array_set($this->items[$this->focus], $attribute, $value);
452
+
453
+        return $this;
454
+    }
455
+
456
+    /**
457
+     * Check if a checkable is checked
458
+     *
459
+     * @return boolean Checked or not
460
+     */
461
+    protected function isChecked($item = null, $value = null)
462
+    {
463
+        if (isset($item['name'])) {
464
+            $name = $item['name'];
465
+        }
466
+        if (empty($name)) {
467
+            $name = $this->name;
468
+        }
469
+
470
+        // If it's a checkbox, see if we marqued that one as checked in the array
471
+        // Or if it's a single radio, simply see if we called check
472
+        if ($this->isCheckbox() or
473
+            !$this->isCheckbox() and !$this->items
474
+        ) {
475
+            $checked = array_get($this->checked, $name, false);
476
+
477
+            // If there are multiple, search for the value
478
+            // as the name are the same between radios
479
+        } else {
480
+            $checked = array_get($this->checked, $value, false);
481
+        }
482
+
483
+        // Check the values and POST array
484
+        if ($this->isGrouped()) {
485
+            // The group index. (e.g. 'bar' if the item name is foo[bar], or the item index for foo[])
486
+            $groupIndex = self::getGroupIndexFromItem($item);
487
+
488
+            // Search using the bare name, not the individual item name
489
+            $post   = $this->app['former']->getPost($this->name);
490
+            $static = $this->app['former']->getValue($this->bind ?: $this->name);
491
+
492
+            if (isset($post[$groupIndex])) {
493
+                $post = $post[$groupIndex];
494
+            }
495
+
496
+            /**
497
+             * Support for Laravel Collection repopulating for grouped checkboxes. Note that the groupIndex must
498
+             * match the value in order for the checkbox to be considered checked, e.g.:
499
+             *
500
+             *  array(
501
+             *    'name' = 'roles[foo]',
502
+             *    'value' => 'foo',
503
+             *  )
504
+             */
505
+            if ($static instanceof Collection) {
506
+                // If the repopulate value is a collection, search for an item matching the $groupIndex
507
+                foreach ($static as $staticItem) {
508
+                    $staticItemValue = method_exists($staticItem, 'getKey') ? $staticItem->getKey() : $staticItem;
509
+                    if ($staticItemValue == $groupIndex) {
510
+                        $static = $staticItemValue;
511
+                        break;
512
+                    }
513
+                }
514
+            } else if (isset($static[$groupIndex])) {
515
+                $static = $static[$groupIndex];
516
+            }
517
+        } else {
518
+            $post   = $this->app['former']->getPost($name);
519
+            $static = $this->app['former']->getValue($this->bind ?: $name);
520
+        }
521
+
522
+        if (!is_null($post) and $post !== $this->app['former']->getOption('unchecked_value')) {
523
+            $isChecked = ($post == $value);
524
+        } elseif (!is_null($static)) {
525
+            $isChecked = ($static == $value);
526
+        } else {
527
+            $isChecked = $checked;
528
+        }
529
+
530
+        return $isChecked ? true : false;
531
+    }
532
+
533
+    /**
534
+     * Check if the current element is a checkbox
535
+     *
536
+     * @return boolean Checkbox or radio
537
+     */
538
+    protected function isCheckbox()
539
+    {
540
+        return $this->checkable == 'checkbox';
541
+    }
542
+
543
+    /**
544
+     * Check if the checkables are grouped or not
545
+     *
546
+     * @return boolean
547
+     */
548
+    protected function isGrouped()
549
+    {
550
+        return
551
+            $this->grouped == true or
552
+            strpos($this->name, '[]') !== false;
553
+    }
554
+
555
+    /**
556
+     * @param array $item The item array, containing at least name and count keys.
557
+     *
558
+     * @return mixed The group index. (e.g. returns bar if the item name is foo[bar], or the item count for foo[])
559
+     */
560
+    public static function getGroupIndexFromItem($item)
561
+    {
562
+        $groupIndex = preg_replace('/^.*?\[(.*)\]$/', '$1', $item['name']);
563
+        if (empty($groupIndex) or $groupIndex == $item['name']) {
564
+            return $item['count'];
565
+        }
566
+
567
+        return $groupIndex;
568
+    }
569 569
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -350,7 +350,7 @@  discard block
 block discarded – undo
350 350
 
351 351
 		// In Bootsrap 3 or 4, don't append the the checkable type (radio/checkbox) as a class if
352 352
 		// rendering inline.
353
-		$class =  ($this->app['former']->framework() == 'TwitterBootstrap3' ||
353
+		$class = ($this->app['former']->framework() == 'TwitterBootstrap3' ||
354 354
 			$this->app['former']->framework() == 'TwitterBootstrap4') ? trim($isInline) : $this->checkable.$isInline;
355 355
 
356 356
 		// Merge custom attributes with global attributes
@@ -381,7 +381,7 @@  discard block
 block discarded – undo
381 381
 			$element = (is_object($field)) ? $field->render() : $field;
382 382
 		} elseif ($this->app['former']->framework() == 'TwitterBootstrap4') {
383 383
 			// Revised for Bootstrap 4, move the 'input' outside of the 'label'
384
-			$element = $field . Element::create('label', $label)->for($attributes['id'])->class($class)->render();
384
+			$element = $field.Element::create('label', $label)->for($attributes['id'])->class($class)->render();
385 385
 
386 386
 			$wrapper_class = $this->inline ? 'form-check form-check-inline' : 'form-check';
387 387
 			
@@ -421,7 +421,7 @@  discard block
 block discarded – undo
421 421
 		$this->app['former']->labels[] = $name;
422 422
 
423 423
 		// Count number of fields with the same ID
424
-		$where  = array_filter($this->app['former']->labels, function ($label) use ($name) {
424
+		$where  = array_filter($this->app['former']->labels, function($label) use ($name) {
425 425
 			return $label == $name;
426 426
 		});
427 427
 		$unique = sizeof($where);
Please login to merge, or discard this patch.