Completed
Push — master ( 264ea0...a36f01 )
by Tortue
14s queued 11s
created
src/Former/Form/Group.php 1 patch
Indentation   +476 added lines, -476 removed lines patch added patch discarded remove patch
@@ -13,480 +13,480 @@
 block discarded – undo
13 13
  */
14 14
 class Group extends Tag
15 15
 {
16
-	/**
17
-	 * The Container
18
-	 *
19
-	 * @var Container
20
-	 */
21
-	protected $app;
22
-
23
-	/**
24
-	 * The current state of the group
25
-	 *
26
-	 * @var string
27
-	 */
28
-	protected $state = null;
29
-
30
-	/**
31
-	 * Whether the field should be displayed raw or not
32
-	 *
33
-	 * @var boolean
34
-	 */
35
-	protected $raw = false;
36
-
37
-	/**
38
-	 * The group label
39
-	 *
40
-	 * @var Element
41
-	 */
42
-	protected $label;
43
-
44
-	/**
45
-	 * The group help
46
-	 *
47
-	 * @var array
48
-	 */
49
-	protected $help = array();
50
-
51
-	/**
52
-	 * An array of elements to preprend the field
53
-	 *
54
-	 * @var array
55
-	 */
56
-	protected $prepend = array();
57
-
58
-	/**
59
-	 * An array of elements to append the field
60
-	 *
61
-	 * @var array
62
-	 */
63
-	protected $append = array();
64
-
65
-	/**
66
-	 * The field validations to be checked for errors
67
-	 *
68
-	 * @var array
69
-	 */
70
-	protected $validations = array();
71
-
72
-	/**
73
-	 * The group's element
74
-	 *
75
-	 * @var string
76
-	 */
77
-	protected $element = 'div';
78
-
79
-	/**
80
-	 * Whether a custom group is opened or not
81
-	 *
82
-	 * @var boolean
83
-	 */
84
-	public static $opened = false;
85
-
86
-	/**
87
-	 * The custom group that is open
88
-	 *
89
-	 * @var Former\Form\Group
90
-	 */
91
-	public static $openGroup = null;
92
-
93
-	////////////////////////////////////////////////////////////////////
94
-	/////////////////////////// CORE METHODS ///////////////////////////
95
-	////////////////////////////////////////////////////////////////////
96
-
97
-	/**
98
-	 * Creates a group
99
-	 *
100
-	 * @param string $label Its label
101
-	 */
102
-	public function __construct(Container $app, $label, $validations = null)
103
-	{
104
-		// Get special classes
105
-		$this->app = $app;
106
-		$this->addClass($this->app['former.framework']->getGroupClasses());
107
-
108
-		// Invisible if Nude
109
-		if ($this->app['former.framework']->is('Nude')) {
110
-			$this->element = '';
111
-		}
112
-
113
-		// Set group label
114
-		if ($label) {
115
-			$this->setLabel($label);
116
-		}
117
-
118
-		// Set validations used to override groups own conclusions
119
-		$this->validations = (array) $validations;
120
-	}
121
-
122
-	/**
123
-	 * Prints out the opening of the Control Group
124
-	 *
125
-	 * @return string A control group opening tag
126
-	 */
127
-	public function __toString()
128
-	{
129
-		return $this->open().$this->getFormattedLabel();
130
-	}
131
-
132
-	/**
133
-	 * Opens a group
134
-	 *
135
-	 * @return string Opening tag
136
-	 */
137
-	public function open()
138
-	{
139
-		if ($this->getErrors()) {
140
-			$this->state($this->app['former.framework']->errorState());
141
-		}
142
-
143
-		// Retrieve state and append it to classes
144
-		if ($this->state) {
145
-			$this->addClass($this->state);
146
-		}
147
-
148
-		// Required state
149
-		if ($this->app->bound('former.field') and $this->app['former.field']->isRequired()) {
150
-			$this->addClass($this->app['former']->getOption('required_class'));
151
-		}
152
-
153
-		return parent::open();
154
-	}
155
-
156
-	/**
157
-	 * Set the contents of the current group
158
-	 *
159
-	 * @param string $contents The group contents
160
-	 *
161
-	 * @return string A group
162
-	 */
163
-	public function contents($contents)
164
-	{
165
-		return $this->wrap($contents, $this->getFormattedLabel());
166
-	}
167
-
168
-	/**
169
-	 * Wrap a Field with the current group
170
-	 *
171
-	 * @param  \Former\Traits\Field $field A Field instance
172
-	 *
173
-	 * @return string        A group
174
-	 */
175
-	public function wrapField($field)
176
-	{
177
-		$label = $this->getLabel($field);
178
-		$help = $this->getHelp();
179
-		if ($field->isCheckable() && $this->app['former']->framework() == 'TwitterBootstrap4') {
180
-			$wrapperClass = $field->isInline() ? 'form-check form-check-inline' : 'form-check';
181
-			if ($this->app['former']->getErrors($field->getName())) {
182
-				$hiddenInput = Element::create('input', null, ['type' => 'hidden'])->class('form-check-input is-invalid');
183
-				$help = $hiddenInput.$help;
184
-			}
185
-			$help = Element::create('div', $help)->class($wrapperClass);
186
-		}
187
-		$field = $this->prependAppend($field);
188
-		$field .= $help;
189
-
190
-		return $this->wrap($field, $label);
191
-	}
192
-
193
-	////////////////////////////////////////////////////////////////////
194
-	//////////////////////////// FIELD METHODS /////////////////////////
195
-	////////////////////////////////////////////////////////////////////
196
-
197
-	/**
198
-	 * Set the state of the group
199
-	 *
200
-	 * @param  string $state A Bootstrap state class
201
-	 */
202
-	public function state($state)
203
-	{
204
-		// Filter state
205
-		$state = $this->app['former.framework']->filterState($state);
206
-
207
-		$this->state = $state;
208
-	}
209
-
210
-	/**
211
-	 * Set a class on the Group
212
-	 *
213
-	 * @param string $class The class to add
214
-	 */
215
-	public function addGroupClass($class)
216
-	{
217
-		$this->addClass($class);
218
-	}
219
-
220
-	/**
221
-	 * Adds a label to the group
222
-	 *
223
-	 * @param  string $label A label
224
-	 */
225
-	public function setLabel($label)
226
-	{
227
-		if (!$label instanceof Element) {
228
-			$label = Helpers::translate($label);
229
-			$label = Element::create('label', $label)->for($label);
230
-		}
231
-
232
-		$this->label = $label;
233
-	}
234
-
235
-	/**
236
-	 * Get the formatted group label
237
-	 *
238
-	 * @return string|null
239
-	 */
240
-	public function getFormattedLabel()
241
-	{
242
-		if (!$this->label) {
243
-			return false;
244
-		}
245
-
246
-		return $this->label->addClass($this->app['former.framework']->getLabelClasses());
247
-	}
248
-
249
-	/**
250
-	 * Disables the control group for the current field
251
-	 */
252
-	public function raw()
253
-	{
254
-		$this->raw = true;
255
-	}
256
-
257
-	/**
258
-	 * Check if the current group is to be displayed or not
259
-	 *
260
-	 * @return boolean
261
-	 */
262
-	public function isRaw()
263
-	{
264
-		return (bool) $this->raw;
265
-	}
266
-
267
-	////////////////////////////////////////////////////////////////////
268
-	///////////////////////////// HELP BLOCKS //////////////////////////
269
-	////////////////////////////////////////////////////////////////////
270
-
271
-	/**
272
-	 * Alias for inlineHelp
273
-	 *
274
-	 * @param  string $help       The help text
275
-	 * @param  array  $attributes Facultative attributes
276
-	 */
277
-	public function help($help, $attributes = array())
278
-	{
279
-		return $this->inlineHelp($help, $attributes);
280
-	}
281
-
282
-	/**
283
-	 * Add an inline help
284
-	 *
285
-	 * @param  string $help       The help text
286
-	 * @param  array  $attributes Facultative attributes
287
-	 */
288
-	public function inlineHelp($help, $attributes = array())
289
-	{
290
-		// If no help text, do nothing
291
-		if (!$help) {
292
-			return false;
293
-		}
294
-
295
-		$this->help['inline'] = $this->app['former.framework']->createHelp($help, $attributes);
296
-	}
297
-
298
-	/**
299
-	 * Add an block help
300
-	 *
301
-	 * @param  string $help       The help text
302
-	 * @param  array  $attributes Facultative attributes
303
-	 */
304
-	public function blockHelp($help, $attributes = array())
305
-	{
306
-		// Reserved method
307
-		if ($this->app['former.framework']->isnt('TwitterBootstrap') &&
308
-		    $this->app['former.framework']->isnt('TwitterBootstrap3') &&
309
-		    $this->app['former.framework']->isnt('TwitterBootstrap4')
310
-		) {
311
-			throw new BadMethodCallException('This method is only available on the Bootstrap framework');
312
-		}
313
-
314
-		// If no help text, do nothing
315
-		if (!$help) {
316
-			return false;
317
-		}
318
-
319
-		$this->help['block'] = $this->app['former.framework']->createBlockHelp($help, $attributes);
320
-	}
321
-
322
-	////////////////////////////////////////////////////////////////////
323
-	///////////////////////// PREPEND/APPEND METHODS ///////////////////
324
-	////////////////////////////////////////////////////////////////////
325
-
326
-	/**
327
-	 * Prepend elements to the field
328
-	 */
329
-	public function prepend()
330
-	{
331
-		$this->placeAround(func_get_args(), 'prepend');
332
-	}
333
-
334
-	/**
335
-	 * Append elements to the field
336
-	 */
337
-	public function append()
338
-	{
339
-		$this->placeAround(func_get_args(), 'append');
340
-	}
341
-
342
-	/**
343
-	 * Prepends an icon to a field
344
-	 *
345
-	 * @param string $icon       The icon to prepend
346
-	 * @param array  $attributes Its attributes
347
-	 */
348
-	public function prependIcon($icon, $attributes = array(), $iconSettings = array())
349
-	{
350
-		$icon = $this->app['former.framework']->createIcon($icon, $attributes, $iconSettings);
351
-
352
-		$this->prepend($icon);
353
-	}
354
-
355
-	/**
356
-	 * Append an icon to a field
357
-	 *
358
-	 * @param string $icon       The icon to prepend
359
-	 * @param array  $attributes Its attributes
360
-	 */
361
-	public function appendIcon($icon, $attributes = array(), $iconSettings = array())
362
-	{
363
-		$icon = $this->app['former.framework']->createIcon($icon, $attributes, $iconSettings);
364
-
365
-		$this->append($icon);
366
-	}
367
-
368
-	////////////////////////////////////////////////////////////////////
369
-	//////////////////////////////// HELPERS ///////////////////////////
370
-	////////////////////////////////////////////////////////////////////
371
-
372
-	/**
373
-	 * Get the errors for the group
374
-	 *
375
-	 * @return string
376
-	 */
377
-	public function getErrors()
378
-	{
379
-		$errors = '';
380
-
381
-		if (!self::$opened) {
382
-
383
-			// for non-custom groups, normal error handling applies
384
-			$errors = $this->app['former']->getErrors();
385
-		} elseif (!empty($this->validations)) {
386
-
387
-			// error handling only when validations specified for custom groups
388
-			foreach ($this->validations as $validation) {
389
-				$errors .= $this->app['former']->getErrors($validation);
390
-			}
391
-		}
392
-
393
-		return $errors;
394
-	}
395
-
396
-	/**
397
-	 * Wraps content in a group
398
-	 *
399
-	 * @param string $contents The content
400
-	 * @param string $label    The label to add
401
-	 *
402
-	 * @return string A group
403
-	 */
404
-	public function wrap($contents, $label = null)
405
-	{
406
-		$group = $this->open();
407
-		$group .= $label;
408
-		$group .= $this->app['former.framework']->wrapField($contents);
409
-		$group .= $this->close();
410
-
411
-		return $group;
412
-	}
413
-
414
-	/**
415
-	 * Prints out the current label
416
-	 *
417
-	 * @param  string $field The field to create a label for
418
-	 *
419
-	 * @return string        A <label> tag
420
-	 */
421
-	 protected function getLabel($field = null)
422
- 	{
423
- 		// Don't create a label if none exist
424
- 		if (!$field or !$this->label) {
425
- 			return null;
426
- 		}
427
-
428
- 		// Wrap label in framework classes
429
- 		$labelClasses = $this->app['former.framework']->getLabelClasses();
430
- 		if ($field->isCheckable() &&
431
- 			$this->app['former']->framework() == 'TwitterBootstrap4' &&
432
- 			$this->app['former.form']->isOfType('horizontal')
433
- 		) {
434
- 			$labelClasses = array_merge($labelClasses, array('pt-0'));
435
- 		}
436
- 		$this->label->addClass($labelClasses);
437
- 		$this->label = $this->app['former.framework']->createLabelOf($field, $this->label);
438
- 		$this->label = $this->app['former.framework']->wrapLabel($this->label);
439
-
440
- 		return $this->label;
441
- 	}
442
-
443
-	/**
444
-	 * Prints out the current help
445
-	 *
446
-	 * @return string A .help-block or .help-inline
447
-	 */
448
-	protected function getHelp()
449
-	{
450
-		$inline = Arr::get($this->help, 'inline');
451
-		$block  = Arr::get($this->help, 'block');
452
-
453
-		// Replace help text with error if any found
454
-		$errors = $this->app['former']->getErrors();
455
-		if ($errors and $this->app['former']->getOption('error_messages')) {
456
-			$inline = $this->app['former.framework']->createValidationError($errors);
457
-		}
458
-
459
-		return join(null, array($inline, $block));
460
-	}
461
-
462
-	/**
463
-	 * Format the field with prepended/appended elements
464
-	 *
465
-	 * @param  Field $field The field to format
466
-	 *
467
-	 * @return string        Field plus supplementary elements
468
-	 */
469
-	protected function prependAppend($field)
470
-	{
471
-		if (!$this->prepend and !$this->append) {
472
-			return $field->render();
473
-		}
474
-
475
-		return $this->app['former.framework']->prependAppend($field, $this->prepend, $this->append);
476
-	}
477
-
478
-	/**
479
-	 * Place elements around the field
480
-	 *
481
-	 * @param  array  $items An array of items to place
482
-	 * @param  string $place Where they should end up (prepend|append)
483
-	 */
484
-	protected function placeAround($items, $place)
485
-	{
486
-		// Iterate over the items and place them where they should
487
-		foreach ((array) $items as $item) {
488
-			$item             = $this->app['former.framework']->placeAround($item, $place);
489
-			$this->{$place}[] = $item;
490
-		}
491
-	}
16
+    /**
17
+     * The Container
18
+     *
19
+     * @var Container
20
+     */
21
+    protected $app;
22
+
23
+    /**
24
+     * The current state of the group
25
+     *
26
+     * @var string
27
+     */
28
+    protected $state = null;
29
+
30
+    /**
31
+     * Whether the field should be displayed raw or not
32
+     *
33
+     * @var boolean
34
+     */
35
+    protected $raw = false;
36
+
37
+    /**
38
+     * The group label
39
+     *
40
+     * @var Element
41
+     */
42
+    protected $label;
43
+
44
+    /**
45
+     * The group help
46
+     *
47
+     * @var array
48
+     */
49
+    protected $help = array();
50
+
51
+    /**
52
+     * An array of elements to preprend the field
53
+     *
54
+     * @var array
55
+     */
56
+    protected $prepend = array();
57
+
58
+    /**
59
+     * An array of elements to append the field
60
+     *
61
+     * @var array
62
+     */
63
+    protected $append = array();
64
+
65
+    /**
66
+     * The field validations to be checked for errors
67
+     *
68
+     * @var array
69
+     */
70
+    protected $validations = array();
71
+
72
+    /**
73
+     * The group's element
74
+     *
75
+     * @var string
76
+     */
77
+    protected $element = 'div';
78
+
79
+    /**
80
+     * Whether a custom group is opened or not
81
+     *
82
+     * @var boolean
83
+     */
84
+    public static $opened = false;
85
+
86
+    /**
87
+     * The custom group that is open
88
+     *
89
+     * @var Former\Form\Group
90
+     */
91
+    public static $openGroup = null;
92
+
93
+    ////////////////////////////////////////////////////////////////////
94
+    /////////////////////////// CORE METHODS ///////////////////////////
95
+    ////////////////////////////////////////////////////////////////////
96
+
97
+    /**
98
+     * Creates a group
99
+     *
100
+     * @param string $label Its label
101
+     */
102
+    public function __construct(Container $app, $label, $validations = null)
103
+    {
104
+        // Get special classes
105
+        $this->app = $app;
106
+        $this->addClass($this->app['former.framework']->getGroupClasses());
107
+
108
+        // Invisible if Nude
109
+        if ($this->app['former.framework']->is('Nude')) {
110
+            $this->element = '';
111
+        }
112
+
113
+        // Set group label
114
+        if ($label) {
115
+            $this->setLabel($label);
116
+        }
117
+
118
+        // Set validations used to override groups own conclusions
119
+        $this->validations = (array) $validations;
120
+    }
121
+
122
+    /**
123
+     * Prints out the opening of the Control Group
124
+     *
125
+     * @return string A control group opening tag
126
+     */
127
+    public function __toString()
128
+    {
129
+        return $this->open().$this->getFormattedLabel();
130
+    }
131
+
132
+    /**
133
+     * Opens a group
134
+     *
135
+     * @return string Opening tag
136
+     */
137
+    public function open()
138
+    {
139
+        if ($this->getErrors()) {
140
+            $this->state($this->app['former.framework']->errorState());
141
+        }
142
+
143
+        // Retrieve state and append it to classes
144
+        if ($this->state) {
145
+            $this->addClass($this->state);
146
+        }
147
+
148
+        // Required state
149
+        if ($this->app->bound('former.field') and $this->app['former.field']->isRequired()) {
150
+            $this->addClass($this->app['former']->getOption('required_class'));
151
+        }
152
+
153
+        return parent::open();
154
+    }
155
+
156
+    /**
157
+     * Set the contents of the current group
158
+     *
159
+     * @param string $contents The group contents
160
+     *
161
+     * @return string A group
162
+     */
163
+    public function contents($contents)
164
+    {
165
+        return $this->wrap($contents, $this->getFormattedLabel());
166
+    }
167
+
168
+    /**
169
+     * Wrap a Field with the current group
170
+     *
171
+     * @param  \Former\Traits\Field $field A Field instance
172
+     *
173
+     * @return string        A group
174
+     */
175
+    public function wrapField($field)
176
+    {
177
+        $label = $this->getLabel($field);
178
+        $help = $this->getHelp();
179
+        if ($field->isCheckable() && $this->app['former']->framework() == 'TwitterBootstrap4') {
180
+            $wrapperClass = $field->isInline() ? 'form-check form-check-inline' : 'form-check';
181
+            if ($this->app['former']->getErrors($field->getName())) {
182
+                $hiddenInput = Element::create('input', null, ['type' => 'hidden'])->class('form-check-input is-invalid');
183
+                $help = $hiddenInput.$help;
184
+            }
185
+            $help = Element::create('div', $help)->class($wrapperClass);
186
+        }
187
+        $field = $this->prependAppend($field);
188
+        $field .= $help;
189
+
190
+        return $this->wrap($field, $label);
191
+    }
192
+
193
+    ////////////////////////////////////////////////////////////////////
194
+    //////////////////////////// FIELD METHODS /////////////////////////
195
+    ////////////////////////////////////////////////////////////////////
196
+
197
+    /**
198
+     * Set the state of the group
199
+     *
200
+     * @param  string $state A Bootstrap state class
201
+     */
202
+    public function state($state)
203
+    {
204
+        // Filter state
205
+        $state = $this->app['former.framework']->filterState($state);
206
+
207
+        $this->state = $state;
208
+    }
209
+
210
+    /**
211
+     * Set a class on the Group
212
+     *
213
+     * @param string $class The class to add
214
+     */
215
+    public function addGroupClass($class)
216
+    {
217
+        $this->addClass($class);
218
+    }
219
+
220
+    /**
221
+     * Adds a label to the group
222
+     *
223
+     * @param  string $label A label
224
+     */
225
+    public function setLabel($label)
226
+    {
227
+        if (!$label instanceof Element) {
228
+            $label = Helpers::translate($label);
229
+            $label = Element::create('label', $label)->for($label);
230
+        }
231
+
232
+        $this->label = $label;
233
+    }
234
+
235
+    /**
236
+     * Get the formatted group label
237
+     *
238
+     * @return string|null
239
+     */
240
+    public function getFormattedLabel()
241
+    {
242
+        if (!$this->label) {
243
+            return false;
244
+        }
245
+
246
+        return $this->label->addClass($this->app['former.framework']->getLabelClasses());
247
+    }
248
+
249
+    /**
250
+     * Disables the control group for the current field
251
+     */
252
+    public function raw()
253
+    {
254
+        $this->raw = true;
255
+    }
256
+
257
+    /**
258
+     * Check if the current group is to be displayed or not
259
+     *
260
+     * @return boolean
261
+     */
262
+    public function isRaw()
263
+    {
264
+        return (bool) $this->raw;
265
+    }
266
+
267
+    ////////////////////////////////////////////////////////////////////
268
+    ///////////////////////////// HELP BLOCKS //////////////////////////
269
+    ////////////////////////////////////////////////////////////////////
270
+
271
+    /**
272
+     * Alias for inlineHelp
273
+     *
274
+     * @param  string $help       The help text
275
+     * @param  array  $attributes Facultative attributes
276
+     */
277
+    public function help($help, $attributes = array())
278
+    {
279
+        return $this->inlineHelp($help, $attributes);
280
+    }
281
+
282
+    /**
283
+     * Add an inline help
284
+     *
285
+     * @param  string $help       The help text
286
+     * @param  array  $attributes Facultative attributes
287
+     */
288
+    public function inlineHelp($help, $attributes = array())
289
+    {
290
+        // If no help text, do nothing
291
+        if (!$help) {
292
+            return false;
293
+        }
294
+
295
+        $this->help['inline'] = $this->app['former.framework']->createHelp($help, $attributes);
296
+    }
297
+
298
+    /**
299
+     * Add an block help
300
+     *
301
+     * @param  string $help       The help text
302
+     * @param  array  $attributes Facultative attributes
303
+     */
304
+    public function blockHelp($help, $attributes = array())
305
+    {
306
+        // Reserved method
307
+        if ($this->app['former.framework']->isnt('TwitterBootstrap') &&
308
+            $this->app['former.framework']->isnt('TwitterBootstrap3') &&
309
+            $this->app['former.framework']->isnt('TwitterBootstrap4')
310
+        ) {
311
+            throw new BadMethodCallException('This method is only available on the Bootstrap framework');
312
+        }
313
+
314
+        // If no help text, do nothing
315
+        if (!$help) {
316
+            return false;
317
+        }
318
+
319
+        $this->help['block'] = $this->app['former.framework']->createBlockHelp($help, $attributes);
320
+    }
321
+
322
+    ////////////////////////////////////////////////////////////////////
323
+    ///////////////////////// PREPEND/APPEND METHODS ///////////////////
324
+    ////////////////////////////////////////////////////////////////////
325
+
326
+    /**
327
+     * Prepend elements to the field
328
+     */
329
+    public function prepend()
330
+    {
331
+        $this->placeAround(func_get_args(), 'prepend');
332
+    }
333
+
334
+    /**
335
+     * Append elements to the field
336
+     */
337
+    public function append()
338
+    {
339
+        $this->placeAround(func_get_args(), 'append');
340
+    }
341
+
342
+    /**
343
+     * Prepends an icon to a field
344
+     *
345
+     * @param string $icon       The icon to prepend
346
+     * @param array  $attributes Its attributes
347
+     */
348
+    public function prependIcon($icon, $attributes = array(), $iconSettings = array())
349
+    {
350
+        $icon = $this->app['former.framework']->createIcon($icon, $attributes, $iconSettings);
351
+
352
+        $this->prepend($icon);
353
+    }
354
+
355
+    /**
356
+     * Append an icon to a field
357
+     *
358
+     * @param string $icon       The icon to prepend
359
+     * @param array  $attributes Its attributes
360
+     */
361
+    public function appendIcon($icon, $attributes = array(), $iconSettings = array())
362
+    {
363
+        $icon = $this->app['former.framework']->createIcon($icon, $attributes, $iconSettings);
364
+
365
+        $this->append($icon);
366
+    }
367
+
368
+    ////////////////////////////////////////////////////////////////////
369
+    //////////////////////////////// HELPERS ///////////////////////////
370
+    ////////////////////////////////////////////////////////////////////
371
+
372
+    /**
373
+     * Get the errors for the group
374
+     *
375
+     * @return string
376
+     */
377
+    public function getErrors()
378
+    {
379
+        $errors = '';
380
+
381
+        if (!self::$opened) {
382
+
383
+            // for non-custom groups, normal error handling applies
384
+            $errors = $this->app['former']->getErrors();
385
+        } elseif (!empty($this->validations)) {
386
+
387
+            // error handling only when validations specified for custom groups
388
+            foreach ($this->validations as $validation) {
389
+                $errors .= $this->app['former']->getErrors($validation);
390
+            }
391
+        }
392
+
393
+        return $errors;
394
+    }
395
+
396
+    /**
397
+     * Wraps content in a group
398
+     *
399
+     * @param string $contents The content
400
+     * @param string $label    The label to add
401
+     *
402
+     * @return string A group
403
+     */
404
+    public function wrap($contents, $label = null)
405
+    {
406
+        $group = $this->open();
407
+        $group .= $label;
408
+        $group .= $this->app['former.framework']->wrapField($contents);
409
+        $group .= $this->close();
410
+
411
+        return $group;
412
+    }
413
+
414
+    /**
415
+     * Prints out the current label
416
+     *
417
+     * @param  string $field The field to create a label for
418
+     *
419
+     * @return string        A <label> tag
420
+     */
421
+        protected function getLabel($field = null)
422
+        {
423
+            // Don't create a label if none exist
424
+            if (!$field or !$this->label) {
425
+                return null;
426
+            }
427
+
428
+            // Wrap label in framework classes
429
+            $labelClasses = $this->app['former.framework']->getLabelClasses();
430
+            if ($field->isCheckable() &&
431
+             $this->app['former']->framework() == 'TwitterBootstrap4' &&
432
+             $this->app['former.form']->isOfType('horizontal')
433
+            ) {
434
+                $labelClasses = array_merge($labelClasses, array('pt-0'));
435
+            }
436
+            $this->label->addClass($labelClasses);
437
+            $this->label = $this->app['former.framework']->createLabelOf($field, $this->label);
438
+            $this->label = $this->app['former.framework']->wrapLabel($this->label);
439
+
440
+            return $this->label;
441
+        }
442
+
443
+    /**
444
+     * Prints out the current help
445
+     *
446
+     * @return string A .help-block or .help-inline
447
+     */
448
+    protected function getHelp()
449
+    {
450
+        $inline = Arr::get($this->help, 'inline');
451
+        $block  = Arr::get($this->help, 'block');
452
+
453
+        // Replace help text with error if any found
454
+        $errors = $this->app['former']->getErrors();
455
+        if ($errors and $this->app['former']->getOption('error_messages')) {
456
+            $inline = $this->app['former.framework']->createValidationError($errors);
457
+        }
458
+
459
+        return join(null, array($inline, $block));
460
+    }
461
+
462
+    /**
463
+     * Format the field with prepended/appended elements
464
+     *
465
+     * @param  Field $field The field to format
466
+     *
467
+     * @return string        Field plus supplementary elements
468
+     */
469
+    protected function prependAppend($field)
470
+    {
471
+        if (!$this->prepend and !$this->append) {
472
+            return $field->render();
473
+        }
474
+
475
+        return $this->app['former.framework']->prependAppend($field, $this->prepend, $this->append);
476
+    }
477
+
478
+    /**
479
+     * Place elements around the field
480
+     *
481
+     * @param  array  $items An array of items to place
482
+     * @param  string $place Where they should end up (prepend|append)
483
+     */
484
+    protected function placeAround($items, $place)
485
+    {
486
+        // Iterate over the items and place them where they should
487
+        foreach ((array) $items as $item) {
488
+            $item             = $this->app['former.framework']->placeAround($item, $place);
489
+            $this->{$place}[] = $item;
490
+        }
491
+    }
492 492
 }
Please login to merge, or discard this patch.
src/Former/Framework/TwitterBootstrap4.php 1 patch
Indentation   +465 added lines, -465 removed lines patch added patch discarded remove patch
@@ -13,469 +13,469 @@
 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
-		'is-invalid',
69
-	);
70
-
71
-	/**
72
-	 * The default HTML tag used for icons
73
-	 *
74
-	 * @var string
75
-	 */
76
-	protected $iconTag = 'i';
77
-
78
-	/**
79
-	 * The default set for icon fonts
80
-	 * By default Bootstrap 4 offers no fonts, but we'll add Font Awesome
81
-	 *
82
-	 * @var string
83
-	 */
84
-	protected $iconSet = 'fa';
85
-
86
-	/**
87
-	 * The default prefix icon names
88
-	 * Using Font Awesome 5, this can be 'fa' or 'fas' for solid, 'far' for regular
89
-	 *
90
-	 * @var string
91
-	 */
92
-	protected $iconPrefix = 'fa';
93
-
94
-	/**
95
-	 * Create a new TwitterBootstrap instance
96
-	 *
97
-	 * @param \Illuminate\Container\Container $app
98
-	 */
99
-	public function __construct(Container $app)
100
-	{
101
-		$this->app = $app;
102
-		$this->setFrameworkDefaults();
103
-	}
104
-
105
-	////////////////////////////////////////////////////////////////////
106
-	/////////////////////////// FILTER ARRAYS //////////////////////////
107
-	////////////////////////////////////////////////////////////////////
108
-
109
-	/**
110
-	 * Filter buttons classes
111
-	 *
112
-	 * @param  array $classes An array of classes
113
-	 *
114
-	 * @return string[] A filtered array
115
-	 */
116
-	public function filterButtonClasses($classes)
117
-	{
118
-		// Filter classes
119
-		// $classes = array_intersect($classes, $this->buttons);
120
-
121
-		// Prepend button type
122
-		$classes   = $this->prependWith($classes, 'btn-');
123
-		$classes[] = 'btn';
124
-
125
-		return $classes;
126
-	}
127
-
128
-	/**
129
-	 * Filter field classes
130
-	 *
131
-	 * @param  array $classes An array of classes
132
-	 *
133
-	 * @return array A filtered array
134
-	 */
135
-	public function filterFieldClasses($classes)
136
-	{
137
-		// Filter classes
138
-		$classes = array_intersect($classes, $this->fields);
139
-
140
-		// Prepend field type
141
-		$classes = array_map(function ($class) {
142
-			return Str::startsWith($class, 'col') ? $class : 'input-'.$class;
143
-		}, $classes);
144
-
145
-		return $classes;
146
-	}
147
-
148
-	////////////////////////////////////////////////////////////////////
149
-	///////////////////// EXPOSE FRAMEWORK SPECIFICS ///////////////////
150
-	////////////////////////////////////////////////////////////////////
151
-
152
-	/**
153
-	 * Framework error state
154
-	 *
155
-	 * @return string
156
-	 */
157
-	public function errorState()
158
-	{
159
-		return 'is-invalid';
160
-	}
161
-
162
-	/**
163
-	 * Returns corresponding inline class of a field
164
-	 *
165
-	 * @param Field $field
166
-	 *
167
-	 * @return string
168
-	 */
169
-	public function getInlineLabelClass($field)
170
-	{
171
-		$inlineClass = parent::getInlineLabelClass($field);
172
-		if ($field->isOfType('checkbox', 'checkboxes', 'radio', 'radios')) {
173
-			$inlineClass = 'form-check-label';
174
-		}
175
-
176
-		return $inlineClass;
177
-	}
178
-
179
-	/**
180
-	 * Set the fields width from a label width
181
-	 *
182
-	 * @param array $labelWidths
183
-	 */
184
-	protected function setFieldWidths($labelWidths)
185
-	{
186
-		$labelWidthClass = $fieldWidthClass = $fieldOffsetClass = '';
187
-
188
-		$viewports = $this->getFrameworkOption('viewports');
189
-		foreach ($labelWidths as $viewport => $columns) {
190
-			if ($viewport) {
191
-				$labelWidthClass .= " col-$viewports[$viewport]-$columns";
192
-				$fieldWidthClass .= " col-$viewports[$viewport]-".(12 - $columns);
193
-				$fieldOffsetClass .= " col-$viewports[$viewport]-offset-$columns";
194
-			}
195
-		}
196
-
197
-		$this->labelWidth  = ltrim($labelWidthClass);
198
-		$this->fieldWidth  = ltrim($fieldWidthClass);
199
-		$this->fieldOffset = ltrim($fieldOffsetClass);
200
-	}
201
-
202
-	////////////////////////////////////////////////////////////////////
203
-	///////////////////////////// ADD CLASSES //////////////////////////
204
-	////////////////////////////////////////////////////////////////////
205
-
206
-	/**
207
-	 * Add classes to a field
208
-	 *
209
-	 * @param Field $field
210
-	 * @param array $classes The possible classes to add
211
-	 *
212
-	 * @return Field
213
-	 */
214
-	public function getFieldClasses(Field $field, $classes)
215
-	{
216
-		// Add inline class for checkables
217
-		if ($field->isCheckable()) {
218
-			// Adds correct checkbox input class when is a checkbox (or radio)
219
-			$field->addClass('form-check-input');
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
-		if ($this->app['former']->getErrors($field->getName())) {
245
-			$classes[] = $this->errorState();
246
-		}
247
-
248
-		return $this->addClassesToField($field, $classes);
249
-	}
250
-
251
-	/**
252
-	 * Add group classes
253
-	 *
254
-	 * @return string A list of group classes
255
-	 */
256
-	public function getGroupClasses()
257
-	{
258
-		if ($this->app['former.form']->isOfType('horizontal')) {
259
-			return 'form-group row';
260
-		} else {
261
-			return 'form-group';
262
-		}
263
-	}
264
-
265
-	/**
266
-	 * Add label classes
267
-	 *
268
-	 * @return string[] An array of attributes with the label class
269
-	 */
270
-	public function getLabelClasses()
271
-	{
272
-		if ($this->app['former.form']->isOfType('horizontal')) {
273
-			return array('col-form-label', $this->labelWidth);
274
-		} elseif ($this->app['former.form']->isOfType('inline')) {
275
-			return array('sr-only');
276
-		} else {
277
-			return array('col-form-label');
278
-		}
279
-	}
280
-
281
-	/**
282
-	 * Add uneditable field classes
283
-	 *
284
-	 * @return string An array of attributes with the uneditable class
285
-	 */
286
-	public function getUneditableClasses()
287
-	{
288
-		return '';
289
-	}
290
-
291
-	/**
292
-	 * Add plain text field classes
293
-	 *
294
-	 * @return string An array of attributes with the plain text class
295
-	 */
296
-	public function getPlainTextClasses()
297
-	{
298
-		return 'form-control-static';
299
-	}
300
-
301
-	/**
302
-	 * Add form class
303
-	 *
304
-	 * @param  string $type The type of form to add
305
-	 *
306
-	 * @return string|null
307
-	 */
308
-	public function getFormClasses($type)
309
-	{
310
-		return $type ? 'form-'.$type : null;
311
-	}
312
-
313
-	/**
314
-	 * Add actions block class
315
-	 *
316
-	 * @return string|null
317
-	 */
318
-	public function getActionClasses()
319
-	{
320
-		if ($this->app['former.form']->isOfType('horizontal') || $this->app['former.form']->isOfType('inline')) {
321
-			return 'form-group row';
322
-		}
323
-
324
-		return null;
325
-	}
326
-
327
-	////////////////////////////////////////////////////////////////////
328
-	//////////////////////////// RENDER BLOCKS /////////////////////////
329
-	////////////////////////////////////////////////////////////////////
330
-
331
-	/**
332
-	 * Render an help text
333
-	 *
334
-	 * @param string $text
335
-	 * @param array  $attributes
336
-	 *
337
-	 * @return Element
338
-	 */
339
-	public function createHelp($text, $attributes = array())
340
-	{
341
-		return Element::create('small', $text, $attributes)->addClass('text-muted');
342
-	}
343
-
344
-	/**
345
-	 * Render an validation error text
346
-	 *
347
-	 * @param string $text
348
-	 * @param array  $attributes
349
-	 *
350
-	 * @return string
351
-	 */
352
-	public function createValidationError($text, $attributes = array())
353
-	{
354
-		return Element::create('div', $text, $attributes)->addClass('invalid-feedback');
355
-	}
356
-
357
-	/**
358
-	 * Render an help text
359
-	 *
360
-	 * @param string $text
361
-	 * @param array  $attributes
362
-	 *
363
-	 * @return Element
364
-	 */
365
-	public function createBlockHelp($text, $attributes = array())
366
-	{
367
-		return Element::create('small', $text, $attributes)->addClass('form-text text-muted');
368
-	}
369
-
370
-	/**
371
-	 * Render a disabled field
372
-	 *
373
-	 * @param Field $field
374
-	 *
375
-	 * @return Element
376
-	 */
377
-	public function createDisabledField(Field $field)
378
-	{
379
-		return Element::create('span', $field->getValue(), $field->getAttributes());
380
-	}
381
-
382
-	/**
383
-	 * Render a plain text field
384
-	 *
385
-	 * @param Field $field
386
-	 *
387
-	 * @return Element
388
-	 */
389
-	public function createPlainTextField(Field $field)
390
-	{
391
-		$label = $field->getLabel();
392
-		if ($label) {
393
-			$label->for('');
394
-		}
395
-
396
-		return Element::create('div', $field->getValue(), $field->getAttributes());
397
-	}
398
-
399
-	////////////////////////////////////////////////////////////////////
400
-	//////////////////////////// WRAP BLOCKS ///////////////////////////
401
-	////////////////////////////////////////////////////////////////////
402
-
403
-	/**
404
-	 * Wrap an item to be prepended or appended to the current field
405
-	 *
406
-	 * @return Element A wrapped item
407
-	 */
408
-	public function placeAround($item, $place = null)
409
-	{
410
-		// Render object
411
-		if (is_object($item) and method_exists($item, '__toString')) {
412
-			$item = $item->__toString();
413
-		}
414
-
415
-		$items = (array) $item;
416
-		$element = '';
417
-		foreach ($items as $item) {
418
-			$hasButtonTag = strpos(ltrim($item), '<button') === 0;
419
-
420
-			// Get class to use
421
-			$class = $hasButtonTag ? '' : 'input-group-text';
422
-
423
-			$element .= $hasButtonTag ? $item : Element::create('span', $item)->addClass($class);
424
-		}
425
-
426
-		return Element::create('div', $element)->addClass('input-group-'.$place);
427
-	}
428
-
429
-	/**
430
-	 * Wrap a field with prepended and appended items
431
-	 *
432
-	 * @param  Field $field
433
-	 * @param  array $prepend
434
-	 * @param  array $append
435
-	 *
436
-	 * @return string A field concatented with prepended and/or appended items
437
-	 */
438
-	public function prependAppend($field, $prepend, $append)
439
-	{
440
-		$return = '<div class="input-group">';
441
-		$return .= join(null, $prepend);
442
-		$return .= $field->render();
443
-		$return .= join(null, $append);
444
-		$return .= '</div>';
445
-
446
-		return $return;
447
-	}
448
-
449
-	/**
450
-	 * Wrap a field with potential additional tags
451
-	 *
452
-	 * @param  Field $field
453
-	 *
454
-	 * @return Element A wrapped field
455
-	 */
456
-	public function wrapField($field)
457
-	{
458
-		if ($this->app['former.form']->isOfType('horizontal')) {
459
-			return Element::create('div', $field)->addClass($this->fieldWidth);
460
-		}
461
-
462
-		return $field;
463
-	}
464
-
465
-	/**
466
-	 * Wrap actions block with potential additional tags
467
-	 *
468
-	 * @param  Actions $actions
469
-	 *
470
-	 * @return string A wrapped actions block
471
-	 */
472
-	public function wrapActions($actions)
473
-	{
474
-		// For horizontal forms, we wrap the actions in a div
475
-		if ($this->app['former.form']->isOfType('horizontal')) {
476
-			return Element::create('div', $actions)->addClass(array($this->fieldOffset, $this->fieldWidth));
477
-		}
478
-
479
-		return $actions;
480
-	}
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
+        'is-invalid',
69
+    );
70
+
71
+    /**
72
+     * The default HTML tag used for icons
73
+     *
74
+     * @var string
75
+     */
76
+    protected $iconTag = 'i';
77
+
78
+    /**
79
+     * The default set for icon fonts
80
+     * By default Bootstrap 4 offers no fonts, but we'll add Font Awesome
81
+     *
82
+     * @var string
83
+     */
84
+    protected $iconSet = 'fa';
85
+
86
+    /**
87
+     * The default prefix icon names
88
+     * Using Font Awesome 5, this can be 'fa' or 'fas' for solid, 'far' for regular
89
+     *
90
+     * @var string
91
+     */
92
+    protected $iconPrefix = 'fa';
93
+
94
+    /**
95
+     * Create a new TwitterBootstrap instance
96
+     *
97
+     * @param \Illuminate\Container\Container $app
98
+     */
99
+    public function __construct(Container $app)
100
+    {
101
+        $this->app = $app;
102
+        $this->setFrameworkDefaults();
103
+    }
104
+
105
+    ////////////////////////////////////////////////////////////////////
106
+    /////////////////////////// FILTER ARRAYS //////////////////////////
107
+    ////////////////////////////////////////////////////////////////////
108
+
109
+    /**
110
+     * Filter buttons classes
111
+     *
112
+     * @param  array $classes An array of classes
113
+     *
114
+     * @return string[] A filtered array
115
+     */
116
+    public function filterButtonClasses($classes)
117
+    {
118
+        // Filter classes
119
+        // $classes = array_intersect($classes, $this->buttons);
120
+
121
+        // Prepend button type
122
+        $classes   = $this->prependWith($classes, 'btn-');
123
+        $classes[] = 'btn';
124
+
125
+        return $classes;
126
+    }
127
+
128
+    /**
129
+     * Filter field classes
130
+     *
131
+     * @param  array $classes An array of classes
132
+     *
133
+     * @return array A filtered array
134
+     */
135
+    public function filterFieldClasses($classes)
136
+    {
137
+        // Filter classes
138
+        $classes = array_intersect($classes, $this->fields);
139
+
140
+        // Prepend field type
141
+        $classes = array_map(function ($class) {
142
+            return Str::startsWith($class, 'col') ? $class : 'input-'.$class;
143
+        }, $classes);
144
+
145
+        return $classes;
146
+    }
147
+
148
+    ////////////////////////////////////////////////////////////////////
149
+    ///////////////////// EXPOSE FRAMEWORK SPECIFICS ///////////////////
150
+    ////////////////////////////////////////////////////////////////////
151
+
152
+    /**
153
+     * Framework error state
154
+     *
155
+     * @return string
156
+     */
157
+    public function errorState()
158
+    {
159
+        return 'is-invalid';
160
+    }
161
+
162
+    /**
163
+     * Returns corresponding inline class of a field
164
+     *
165
+     * @param Field $field
166
+     *
167
+     * @return string
168
+     */
169
+    public function getInlineLabelClass($field)
170
+    {
171
+        $inlineClass = parent::getInlineLabelClass($field);
172
+        if ($field->isOfType('checkbox', 'checkboxes', 'radio', 'radios')) {
173
+            $inlineClass = 'form-check-label';
174
+        }
175
+
176
+        return $inlineClass;
177
+    }
178
+
179
+    /**
180
+     * Set the fields width from a label width
181
+     *
182
+     * @param array $labelWidths
183
+     */
184
+    protected function setFieldWidths($labelWidths)
185
+    {
186
+        $labelWidthClass = $fieldWidthClass = $fieldOffsetClass = '';
187
+
188
+        $viewports = $this->getFrameworkOption('viewports');
189
+        foreach ($labelWidths as $viewport => $columns) {
190
+            if ($viewport) {
191
+                $labelWidthClass .= " col-$viewports[$viewport]-$columns";
192
+                $fieldWidthClass .= " col-$viewports[$viewport]-".(12 - $columns);
193
+                $fieldOffsetClass .= " col-$viewports[$viewport]-offset-$columns";
194
+            }
195
+        }
196
+
197
+        $this->labelWidth  = ltrim($labelWidthClass);
198
+        $this->fieldWidth  = ltrim($fieldWidthClass);
199
+        $this->fieldOffset = ltrim($fieldOffsetClass);
200
+    }
201
+
202
+    ////////////////////////////////////////////////////////////////////
203
+    ///////////////////////////// ADD CLASSES //////////////////////////
204
+    ////////////////////////////////////////////////////////////////////
205
+
206
+    /**
207
+     * Add classes to a field
208
+     *
209
+     * @param Field $field
210
+     * @param array $classes The possible classes to add
211
+     *
212
+     * @return Field
213
+     */
214
+    public function getFieldClasses(Field $field, $classes)
215
+    {
216
+        // Add inline class for checkables
217
+        if ($field->isCheckable()) {
218
+            // Adds correct checkbox input class when is a checkbox (or radio)
219
+            $field->addClass('form-check-input');
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
+        if ($this->app['former']->getErrors($field->getName())) {
245
+            $classes[] = $this->errorState();
246
+        }
247
+
248
+        return $this->addClassesToField($field, $classes);
249
+    }
250
+
251
+    /**
252
+     * Add group classes
253
+     *
254
+     * @return string A list of group classes
255
+     */
256
+    public function getGroupClasses()
257
+    {
258
+        if ($this->app['former.form']->isOfType('horizontal')) {
259
+            return 'form-group row';
260
+        } else {
261
+            return 'form-group';
262
+        }
263
+    }
264
+
265
+    /**
266
+     * Add label classes
267
+     *
268
+     * @return string[] An array of attributes with the label class
269
+     */
270
+    public function getLabelClasses()
271
+    {
272
+        if ($this->app['former.form']->isOfType('horizontal')) {
273
+            return array('col-form-label', $this->labelWidth);
274
+        } elseif ($this->app['former.form']->isOfType('inline')) {
275
+            return array('sr-only');
276
+        } else {
277
+            return array('col-form-label');
278
+        }
279
+    }
280
+
281
+    /**
282
+     * Add uneditable field classes
283
+     *
284
+     * @return string An array of attributes with the uneditable class
285
+     */
286
+    public function getUneditableClasses()
287
+    {
288
+        return '';
289
+    }
290
+
291
+    /**
292
+     * Add plain text field classes
293
+     *
294
+     * @return string An array of attributes with the plain text class
295
+     */
296
+    public function getPlainTextClasses()
297
+    {
298
+        return 'form-control-static';
299
+    }
300
+
301
+    /**
302
+     * Add form class
303
+     *
304
+     * @param  string $type The type of form to add
305
+     *
306
+     * @return string|null
307
+     */
308
+    public function getFormClasses($type)
309
+    {
310
+        return $type ? 'form-'.$type : null;
311
+    }
312
+
313
+    /**
314
+     * Add actions block class
315
+     *
316
+     * @return string|null
317
+     */
318
+    public function getActionClasses()
319
+    {
320
+        if ($this->app['former.form']->isOfType('horizontal') || $this->app['former.form']->isOfType('inline')) {
321
+            return 'form-group row';
322
+        }
323
+
324
+        return null;
325
+    }
326
+
327
+    ////////////////////////////////////////////////////////////////////
328
+    //////////////////////////// RENDER BLOCKS /////////////////////////
329
+    ////////////////////////////////////////////////////////////////////
330
+
331
+    /**
332
+     * Render an help text
333
+     *
334
+     * @param string $text
335
+     * @param array  $attributes
336
+     *
337
+     * @return Element
338
+     */
339
+    public function createHelp($text, $attributes = array())
340
+    {
341
+        return Element::create('small', $text, $attributes)->addClass('text-muted');
342
+    }
343
+
344
+    /**
345
+     * Render an validation error text
346
+     *
347
+     * @param string $text
348
+     * @param array  $attributes
349
+     *
350
+     * @return string
351
+     */
352
+    public function createValidationError($text, $attributes = array())
353
+    {
354
+        return Element::create('div', $text, $attributes)->addClass('invalid-feedback');
355
+    }
356
+
357
+    /**
358
+     * Render an help text
359
+     *
360
+     * @param string $text
361
+     * @param array  $attributes
362
+     *
363
+     * @return Element
364
+     */
365
+    public function createBlockHelp($text, $attributes = array())
366
+    {
367
+        return Element::create('small', $text, $attributes)->addClass('form-text text-muted');
368
+    }
369
+
370
+    /**
371
+     * Render a disabled field
372
+     *
373
+     * @param Field $field
374
+     *
375
+     * @return Element
376
+     */
377
+    public function createDisabledField(Field $field)
378
+    {
379
+        return Element::create('span', $field->getValue(), $field->getAttributes());
380
+    }
381
+
382
+    /**
383
+     * Render a plain text field
384
+     *
385
+     * @param Field $field
386
+     *
387
+     * @return Element
388
+     */
389
+    public function createPlainTextField(Field $field)
390
+    {
391
+        $label = $field->getLabel();
392
+        if ($label) {
393
+            $label->for('');
394
+        }
395
+
396
+        return Element::create('div', $field->getValue(), $field->getAttributes());
397
+    }
398
+
399
+    ////////////////////////////////////////////////////////////////////
400
+    //////////////////////////// WRAP BLOCKS ///////////////////////////
401
+    ////////////////////////////////////////////////////////////////////
402
+
403
+    /**
404
+     * Wrap an item to be prepended or appended to the current field
405
+     *
406
+     * @return Element A wrapped item
407
+     */
408
+    public function placeAround($item, $place = null)
409
+    {
410
+        // Render object
411
+        if (is_object($item) and method_exists($item, '__toString')) {
412
+            $item = $item->__toString();
413
+        }
414
+
415
+        $items = (array) $item;
416
+        $element = '';
417
+        foreach ($items as $item) {
418
+            $hasButtonTag = strpos(ltrim($item), '<button') === 0;
419
+
420
+            // Get class to use
421
+            $class = $hasButtonTag ? '' : 'input-group-text';
422
+
423
+            $element .= $hasButtonTag ? $item : Element::create('span', $item)->addClass($class);
424
+        }
425
+
426
+        return Element::create('div', $element)->addClass('input-group-'.$place);
427
+    }
428
+
429
+    /**
430
+     * Wrap a field with prepended and appended items
431
+     *
432
+     * @param  Field $field
433
+     * @param  array $prepend
434
+     * @param  array $append
435
+     *
436
+     * @return string A field concatented with prepended and/or appended items
437
+     */
438
+    public function prependAppend($field, $prepend, $append)
439
+    {
440
+        $return = '<div class="input-group">';
441
+        $return .= join(null, $prepend);
442
+        $return .= $field->render();
443
+        $return .= join(null, $append);
444
+        $return .= '</div>';
445
+
446
+        return $return;
447
+    }
448
+
449
+    /**
450
+     * Wrap a field with potential additional tags
451
+     *
452
+     * @param  Field $field
453
+     *
454
+     * @return Element A wrapped field
455
+     */
456
+    public function wrapField($field)
457
+    {
458
+        if ($this->app['former.form']->isOfType('horizontal')) {
459
+            return Element::create('div', $field)->addClass($this->fieldWidth);
460
+        }
461
+
462
+        return $field;
463
+    }
464
+
465
+    /**
466
+     * Wrap actions block with potential additional tags
467
+     *
468
+     * @param  Actions $actions
469
+     *
470
+     * @return string A wrapped actions block
471
+     */
472
+    public function wrapActions($actions)
473
+    {
474
+        // For horizontal forms, we wrap the actions in a div
475
+        if ($this->app['former.form']->isOfType('horizontal')) {
476
+            return Element::create('div', $actions)->addClass(array($this->fieldOffset, $this->fieldWidth));
477
+        }
478
+
479
+        return $actions;
480
+    }
481 481
 }
Please login to merge, or discard this patch.